Skip to content

Commit 63f9584

Browse files
committed
Optimize locking of FetchResultStore
1 parent bbe486a commit 63f9584

8 files changed

Lines changed: 1395 additions & 991 deletions

File tree

docs/internal/hive-router-comparison.md

Lines changed: 242 additions & 0 deletions
Large diffs are not rendered by default.

src/HotChocolate/Fusion/src/Fusion.Execution/Execution/OperationPlanContext.Pooling.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ internal void Clean()
6969
Array.Clear(_transportContentTypes, 0, _nodeSlotCapacity);
7070
}
7171

72-
_resultStore.Clean(256, 256);
72+
_resultStore.Clean();
7373
_executionState.Clean();
7474

7575
RequestContext = default!;

src/HotChocolate/Fusion/src/Fusion.Execution/Execution/OperationPlanContext.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,18 @@ namespace HotChocolate.Fusion.Execution;
2323
public sealed partial class OperationPlanContext : IFeatureProvider, IAsyncDisposable
2424
{
2525
private static readonly JsonOperationPlanFormatter s_planFormatter = new();
26+
private readonly IFusionExecutionDiagnosticEvents _diagnosticEvents;
27+
private readonly FetchResultStore _resultStore;
28+
private readonly ExecutionState _executionState;
29+
private readonly INodeIdParser _nodeIdParser;
30+
private readonly IErrorHandler _errorHandler;
2631
private NodeCompletionSet?[] _nodesToComplete = [];
2732
private int _dependentBitsetWordCount;
2833
private string?[] _schemaNames = [];
2934
private ImmutableArray<VariableValues>[] _variableValueSets = [];
3035
private Uri?[] _transportUris = [];
3136
private string?[] _transportContentTypes = [];
3237
private List<IOperationPlanNode>?[] _skippedDefinitions = [];
33-
private readonly IFusionExecutionDiagnosticEvents _diagnosticEvents;
34-
private readonly FetchResultStore _resultStore;
35-
private readonly ExecutionState _executionState;
36-
private readonly INodeIdParser _nodeIdParser;
37-
private readonly IErrorHandler _errorHandler;
3838
private bool _collectTelemetry;
3939
private ISourceSchemaClientScope _clientScope = default!;
4040
private string? _traceId;

src/HotChocolate/Fusion/src/Fusion.Execution/Execution/Results/FetchResultStore.Pooling.cs

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Buffers;
21
using HotChocolate.Execution;
32
using HotChocolate.Fusion.Execution.Nodes;
43
using HotChocolate.Fusion.Text.Json;
@@ -8,6 +7,8 @@ namespace HotChocolate.Fusion.Execution.Results;
87

98
internal sealed partial class FetchResultStore
109
{
10+
private const int MaxDictionaryRetainCapacity = 256;
11+
1112
/// <summary>
1213
/// Initializes the <see cref="FetchResultStore"/> for a new request.
1314
/// </summary>
@@ -64,56 +65,30 @@ public void Reset()
6465
/// Cleans the store for return to the pool.
6566
/// Releases per-request state while retaining reusable buffers.
6667
/// </summary>
67-
internal void Clean(int maxCollectTargetRetainLength, int maxDictionaryRetainCapacity)
68+
internal void Clean()
6869
{
69-
// drain and dispose per-request memory
7070
while (_memory.TryPop(out var memory))
7171
{
7272
memory.Dispose();
7373
}
7474

75-
// return path segments to global pool and reset local pool
7675
_pathPool.Dispose();
7776
_pathPool = null!;
7877

79-
// clear errors
8078
_errors?.Clear();
8179
_pocketedErrors?.Clear();
8280

83-
// reset variable writer (returns excess chunks, keeps the first)
84-
_variableWriter.Clean();
85-
86-
// clear collect target arrays to unroot CompositeResultDocument references;
87-
// if they grew too large during a burst, swap them for smaller ones.
88-
TrimOrClearBuffer(ref _collectTargetA, maxCollectTargetRetainLength);
89-
TrimOrClearBuffer(ref _collectTargetB, maxCollectTargetRetainLength);
90-
TrimOrClearBuffer(ref _collectTargetCombined, maxCollectTargetRetainLength);
81+
_builderPool.Clean();
9182

92-
// clear dictionaries/hashsets; drop oversized ones.
93-
TrimOrClear(ref _seenPaths, maxDictionaryRetainCapacity, ReferenceEqualityComparer.Instance);
94-
_variableDedupTable.Clear();
83+
TrimOrClear(ref _seenPaths, MaxDictionaryRetainCapacity, ReferenceEqualityComparer.Instance);
9584

96-
// null out per-request references
9785
_result = default!;
9886
_valueCompletion = default!;
9987
_schema = default!;
10088
_errorHandler = default!;
10189
_operation = default!;
10290
}
10391

104-
private static void TrimOrClearBuffer(ref CompositeResultElement[] buffer, int maxRetainLength)
105-
{
106-
if (buffer.Length > maxRetainLength)
107-
{
108-
ArrayPool<CompositeResultElement>.Shared.Return(buffer, clearArray: true);
109-
buffer = ArrayPool<CompositeResultElement>.Shared.Rent(64);
110-
}
111-
else
112-
{
113-
buffer.AsSpan().Clear();
114-
}
115-
}
116-
11792
private static void TrimOrClear<TKey>(
11893
ref HashSet<TKey> set,
11994
int maxRetainCapacity,

0 commit comments

Comments
 (0)