| File: Rpc\INativeBackchannelRpc.cs | Web Access |
| Project: src\src\Aspire.Hosting.Native.Server\Aspire.Hosting.Native.Server.csproj (Aspire.Hosting.Native.Server) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.CompilerServices; using System.Text.Json; using System.Text.Json.Serialization.Metadata; using Aspire.Hosting.Native.Cli; namespace Aspire.Hosting.Native.Rpc; /// <summary>Runs one backchannel connection over a caller-owned duplex stream.</summary> internal interface INativeBackchannelRpc { /// <summary>Dispatches concurrent requests and drains connection-owned work before returning.</summary> Task ServeAsync(Stream stream, Func<NativeCliRequest, CancellationToken, Task<NativeBackchannelReply>> dispatch, CancellationToken cancellationToken); } /// <summary>Returns copied data or a connection-owned stream, with optional post-flush lifecycle work.</summary> internal sealed record NativeBackchannelReply(JsonElement Result, IAsyncEnumerable<JsonElement>? Stream = null, Action? AfterResponse = null) { internal static NativeBackchannelReply Value<T>(T value, JsonTypeInfo<T> typeInfo) => new(JsonSerializer.SerializeToElement(value, typeInfo)); internal static NativeBackchannelReply Streaming<T>(IAsyncEnumerable<T> source, JsonTypeInfo<T> typeInfo) => new(default, EncodeAsync(source, typeInfo)); private static async IAsyncEnumerable<JsonElement> EncodeAsync<T>(IAsyncEnumerable<T> source, JsonTypeInfo<T> typeInfo, [EnumeratorCancellation] CancellationToken cancellationToken = default) { await foreach (var value in source.WithCancellation(cancellationToken).ConfigureAwait(false)) { yield return JsonSerializer.SerializeToElement(value, typeInfo); } } }