Skip to content

Commit

Permalink
Put two Task.Yield calls into place to make sure the receive loop in …
Browse files Browse the repository at this point in the history
…WebSocketGremlinqClient won't get stuck.
  • Loading branch information
danielcweber committed Jan 9, 2025
1 parent 6c57f81 commit 1992ff2
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion src/Providers.Core/Factory/WebSocketGremlinqClientFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,21 @@ public async IAsyncEnumerator<ResponseMessage<T>> GetAsyncEnumerator(Cancellatio
if (await new ValueTask<ResponseAndQueueUnion<T>?>(this, 0).ConfigureAwait(false) is { } union)
{
if (union.TryGetResponse(out var response))
{
// Since the below yield return is what effectively yields control back to user code,
// the receive loop may stall if user code blocks. Although technically not Gremlinq's
// fault, we take this measure.
await Task.Yield();

yield return response;
}
else if (union.TryGetQueue(out var semaphore, out var queue))
{
while (true)
{
await semaphore.WaitAsync(ct).ConfigureAwait(false);
await semaphore
.WaitAsync(ct)
.ConfigureAwait(false);

if (queue.TryDequeue(out var queuedResponse))
{
Expand All @@ -155,6 +164,9 @@ await _client
}
else
{
// See above.
await Task.Yield();

yield return queuedResponse;

if (queuedResponse.Status.Code != PartialContent)
Expand Down

0 comments on commit 1992ff2

Please sign in to comment.