openai/openai-dotnet

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
OpenAI_2.0.0-beta.1

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/Utility/AsyncServerSentEventEnumerable.cs

82lines · modecode

1using 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{
16 private readonly Stream _contentStream;
17
18 public AsyncServerSentEventEnumerable(Stream contentStream)
19 {
20 Argument.AssertNotNull(contentStream, nameof(contentStream));
21
22 _contentStream = contentStream;
23
24 LastEventId = string.Empty;
25 ReconnectionInterval = Timeout.InfiniteTimeSpan;
26 }
27
28 public string LastEventId { get; private set; }
29
30 public TimeSpan ReconnectionInterval { get; private set; }
31
32 public IAsyncEnumerator<ServerSentEvent> GetAsyncEnumerator(CancellationToken cancellationToken = default)
33 {
34 return new AsyncServerSentEventEnumerator(_contentStream, this, cancellationToken);
35 }
36
37 private sealed class AsyncServerSentEventEnumerator : IAsyncEnumerator<ServerSentEvent>
38 {
39 private readonly ServerSentEventReader _reader;
40 private readonly AsyncServerSentEventEnumerable _enumerable;
41 private readonly CancellationToken _cancellationToken;
42
43 public ServerSentEvent Current { get; private set; }
44
45 public AsyncServerSentEventEnumerator(Stream contentStream,
46 AsyncServerSentEventEnumerable enumerable,
47 CancellationToken cancellationToken = default)
48 {
49 _reader = new(contentStream);
50 _enumerable = enumerable;
51 _cancellationToken = cancellationToken;
52 }
53
54 public async ValueTask<bool> MoveNextAsync()
55 {
56 ServerSentEvent? nextEvent = await _reader.TryGetNextEventAsync(_cancellationToken).ConfigureAwait(false);
57 _enumerable.LastEventId = _reader.LastEventId;
58 _enumerable.ReconnectionInterval = _reader.ReconnectionInterval;
59
60 if (nextEvent.HasValue)
61 {
62 Current = nextEvent.Value;
63 return true;
64 }
65
66 Current = default;
67 return false;
68 }
69
70 public 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
76 return ValueTask.CompletedTask;
77#else
78 return new ValueTask();
79#endif
80 }
81 }
82}
83