Skip to content

Commit fffa6fb

Browse files
committed
experiment
1 parent f070b9a commit fffa6fb

2 files changed

Lines changed: 128 additions & 91 deletions

File tree

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

Lines changed: 90 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
using System.Buffers;
22
using System.Collections.Immutable;
33
using System.Diagnostics;
4-
using System.Diagnostics.CodeAnalysis;
54
using System.Runtime.CompilerServices;
65
using System.Runtime.InteropServices;
76
using System.Text.Json;
87
using HotChocolate.Buffers;
98
using HotChocolate.Execution;
109
using HotChocolate.Fusion.Execution.Clients;
1110
using HotChocolate.Fusion.Execution.Nodes;
12-
using HotChocolate.Fusion.Language;
1311
using HotChocolate.Fusion.Text.Json;
1412
using HotChocolate.Language;
1513
using HotChocolate.Types;
16-
using HotChocolate.Text.Json;
1714

1815
namespace HotChocolate.Fusion.Execution.Results;
1916

@@ -114,38 +111,46 @@ public bool AddPartialResults(
114111
errorTriesSpan[i] = GetErrorTrie(sourcePath, errors?.Trie);
115112
}
116113

114+
// Admin-only: bookkeeping mutations under narrow lock, not SaveSafeResult.
117115
lock (_lock)
118116
{
119-
try
117+
if (rootErrors is not null)
120118
{
121-
if (rootErrors is not null)
122-
{
123-
_errors ??= [];
124-
_errors.AddRange(rootErrors);
125-
}
119+
_errors ??= [];
120+
_errors.AddRange(rootErrors);
121+
}
122+
123+
for (var i = 0; i < results.Length; i++)
124+
{
125+
_memory.Add(results[i]);
126+
}
127+
}
126128

127-
var resultData = _result.Data;
129+
try
130+
{
131+
var resultData = _result.Data;
128132

129-
for (var i = 0; i < results.Length; i++)
133+
for (var i = 0; i < results.Length; i++)
134+
{
135+
var result = results[i];
136+
137+
if (!SaveSafeResult(
138+
resultData,
139+
result.Path,
140+
result.AdditionalPaths.AsSpan(),
141+
dataElementsSpan[i],
142+
errorTriesSpan[i],
143+
resultSelectionSet))
130144
{
131-
var result = results[i];
132-
_memory.Add(result);
133-
134-
if (!SaveSafeResult(
135-
resultData,
136-
result.Path,
137-
result.AdditionalPaths.AsSpan(),
138-
dataElementsSpan[i],
139-
errorTriesSpan[i],
140-
resultSelectionSet))
141-
{
142-
return false;
143-
}
145+
return false;
144146
}
145-
146-
return true;
147147
}
148-
finally
148+
149+
return true;
150+
}
151+
finally
152+
{
153+
lock (_lock)
149154
{
150155
ReturnPathSegments(results);
151156
}
@@ -177,30 +182,37 @@ private bool AddPartialResultsNoErrors(
177182

178183
lock (_lock)
179184
{
180-
try
185+
for (var i = 0; i < results.Length; i++)
181186
{
182-
var resultData = _result.Data;
187+
_memory.Add(results[i]);
188+
}
189+
}
190+
191+
try
192+
{
193+
var resultData = _result.Data;
183194

184-
for (var i = 0; i < results.Length; i++)
195+
for (var i = 0; i < results.Length; i++)
196+
{
197+
var result = results[i];
198+
199+
if (!SaveSafeResult(
200+
resultData,
201+
result.Path,
202+
result.AdditionalPaths.AsSpan(),
203+
dataElementsSpan[i],
204+
errorTrie: null,
205+
resultSelectionSet))
185206
{
186-
var result = results[i];
187-
_memory.Add(result);
188-
189-
if (!SaveSafeResult(
190-
resultData,
191-
result.Path,
192-
result.AdditionalPaths.AsSpan(),
193-
dataElementsSpan[i],
194-
errorTrie: null,
195-
resultSelectionSet))
196-
{
197-
return false;
198-
}
207+
return false;
199208
}
200-
201-
return true;
202209
}
203-
finally
210+
211+
return true;
212+
}
213+
finally
214+
{
215+
lock (_lock)
204216
{
205217
ReturnPathSegments(results);
206218
}
@@ -226,23 +238,26 @@ private bool AddSinglePartialResult(
226238
{
227239
_memory.Add(result);
228240

229-
try
241+
if (errors?.RootErrors is { Length: > 0 } rootErrors)
230242
{
231-
if (errors?.RootErrors is { Length: > 0 } rootErrors)
232-
{
233-
_errors ??= [];
234-
_errors.AddRange(rootErrors);
235-
}
236-
237-
return SaveSafeResult(
238-
_result.Data,
239-
result.Path,
240-
result.AdditionalPaths.AsSpan(),
241-
dataElement,
242-
errorTrie,
243-
resultSelectionSet);
243+
_errors ??= [];
244+
_errors.AddRange(rootErrors);
244245
}
245-
finally
246+
}
247+
248+
try
249+
{
250+
return SaveSafeResult(
251+
_result.Data,
252+
result.Path,
253+
result.AdditionalPaths.AsSpan(),
254+
dataElement,
255+
errorTrie,
256+
resultSelectionSet);
257+
}
258+
finally
259+
{
260+
lock (_lock)
246261
{
247262
ReturnPathSegments(result);
248263
}
@@ -259,18 +274,21 @@ private bool AddSinglePartialResultNoErrors(
259274
lock (_lock)
260275
{
261276
_memory.Add(result);
277+
}
262278

263-
try
264-
{
265-
return SaveSafeResult(
266-
_result.Data,
267-
result.Path,
268-
result.AdditionalPaths.AsSpan(),
269-
dataElement,
270-
errorTrie: null,
271-
resultSelectionSet);
272-
}
273-
finally
279+
try
280+
{
281+
return SaveSafeResult(
282+
_result.Data,
283+
result.Path,
284+
result.AdditionalPaths.AsSpan(),
285+
dataElement,
286+
errorTrie: null,
287+
resultSelectionSet);
288+
}
289+
finally
290+
{
291+
lock (_lock)
274292
{
275293
ReturnPathSegments(result);
276294
}

src/HotChocolate/Fusion/src/Fusion.Execution/Text/Json/CompositeResultDocument.cs

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ public sealed partial class CompositeResultDocument : IDisposable
1414
private readonly Operation _operation;
1515
private readonly ulong _includeFlags;
1616
private readonly PathSegmentLocalPool? _pathPool;
17+
#if NET9_0_OR_GREATER
18+
private readonly Lock _metaDbLock = new();
19+
private readonly Lock _sourcesLock = new();
20+
#else
21+
private readonly object _metaDbLock = new();
22+
private readonly object _sourcesLock = new();
23+
#endif
1724
internal MetaDb _metaDb;
1825
private bool _disposed;
1926

@@ -341,32 +348,38 @@ private ReadOnlySpan<byte> ReadRawValue(DbRow row)
341348

342349
internal CompositeResultElement CreateObject(Cursor parent, SelectionSet selectionSet)
343350
{
344-
var startObjectCursor = WriteStartObject(parent, selectionSet.Id);
345-
346-
var selectionCount = 0;
347-
foreach (var selection in selectionSet.Selections)
351+
lock (_metaDbLock)
348352
{
349-
WriteEmptyProperty(startObjectCursor, selection);
350-
selectionCount++;
351-
}
353+
var startObjectCursor = WriteStartObject(parent, selectionSet.Id);
354+
355+
var selectionCount = 0;
356+
foreach (var selection in selectionSet.Selections)
357+
{
358+
WriteEmptyProperty(startObjectCursor, selection);
359+
selectionCount++;
360+
}
352361

353-
WriteEndObject(startObjectCursor, selectionCount);
362+
WriteEndObject(startObjectCursor, selectionCount);
354363

355-
return new CompositeResultElement(this, startObjectCursor);
364+
return new CompositeResultElement(this, startObjectCursor);
365+
}
356366
}
357367

358368
internal CompositeResultElement CreateArray(Cursor parent, int length)
359369
{
360-
var cursor = WriteStartArray(parent, length);
361-
362-
for (var i = 0; i < length; i++)
370+
lock (_metaDbLock)
363371
{
364-
WriteEmptyValue(cursor);
365-
}
372+
var cursor = WriteStartArray(parent, length);
366373

367-
WriteEndArray();
374+
for (var i = 0; i < length; i++)
375+
{
376+
WriteEmptyValue(cursor);
377+
}
368378

369-
return new CompositeResultElement(this, cursor);
379+
WriteEndArray();
380+
381+
return new CompositeResultElement(this, cursor);
382+
}
370383
}
371384

372385
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -387,9 +400,15 @@ internal void AssignSourceValue(CompositeResultElement target, SourceResultEleme
387400

388401
if (parent.Id == -1)
389402
{
390-
Debug.Assert(!_sources.Contains(parent), "The source document is marked as unbound but is already registered.");
391-
parent.Id = _sources.Count;
392-
_sources.Add(parent);
403+
lock (_sourcesLock)
404+
{
405+
if (parent.Id == -1)
406+
{
407+
Debug.Assert(!_sources.Contains(parent), "The source document is marked as unbound but is already registered.");
408+
parent.Id = _sources.Count;
409+
_sources.Add(parent);
410+
}
411+
}
393412
}
394413

395414
Debug.Assert(_sources.Contains(parent), "Expected the source document of the source element to be registered.");

0 commit comments

Comments
 (0)