openai/openai-dotnet

Public

mirrored from https://github.com/openai/openai-dotnetAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
OpenAI_2.0.0-beta.4

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/Utility/AsyncServerSentEventEnumerable.cs

82lines · modeblame

9f9f2936Jose Arriaga Maldonado2 years ago1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Threading;
5using System.Threading.Tasks;
6
7#nullable enable
8
9namespace OpenAI;
10
11/// <summary>
12/// Represents a collection of SSE events that can be enumerated as a C# async stream.
13/// </summary>
14internal class AsyncServerSentEventEnumerable : IAsyncEnumerable<ServerSentEvent>
15{
16private readonly Stream _contentStream;
17
18public AsyncServerSentEventEnumerable(Stream contentStream)
19{
20Argument.AssertNotNull(contentStream, nameof(contentStream));
21
22_contentStream = contentStream;
23
24LastEventId = string.Empty;
25ReconnectionInterval = Timeout.InfiniteTimeSpan;
26}
27
28public string LastEventId { get; private set; }
29
30public TimeSpan ReconnectionInterval { get; private set; }
31
32public IAsyncEnumerator<ServerSentEvent> GetAsyncEnumerator(CancellationToken cancellationToken = default)
33{
34return new AsyncServerSentEventEnumerator(_contentStream, this, cancellationToken);
35}
36
37private sealed class AsyncServerSentEventEnumerator : IAsyncEnumerator<ServerSentEvent>
38{
39private readonly ServerSentEventReader _reader;
40private readonly AsyncServerSentEventEnumerable _enumerable;
41private readonly CancellationToken _cancellationToken;
42
43public ServerSentEvent Current { get; private set; }
44
45public AsyncServerSentEventEnumerator(Stream contentStream,
46AsyncServerSentEventEnumerable enumerable,
47CancellationToken cancellationToken = default)
48{
49_reader = new(contentStream);
50_enumerable = enumerable;
51_cancellationToken = cancellationToken;
52}
53
54public async ValueTask<bool> MoveNextAsync()
55{
56ServerSentEvent? nextEvent = await _reader.TryGetNextEventAsync(_cancellationToken).ConfigureAwait(false);
57_enumerable.LastEventId = _reader.LastEventId;
58_enumerable.ReconnectionInterval = _reader.ReconnectionInterval;
59
60if (nextEvent.HasValue)
61{
62Current = nextEvent.Value;
63return true;
64}
65
66Current = default;
67return false;
68}
69
70public ValueTask DisposeAsync()
71{
72// The creator of the enumerable has responsibility for disposing
73// the content stream passed to the enumerable constructor.
74
75#if NET6_0_OR_GREATER
76return ValueTask.CompletedTask;
77#else
78return new ValueTask();
79#endif
80}
81}
82}