You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

TestGrpcWorkerConnection.cs 4.8 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // TestGrpcWorkerConnection.cs
  3. using System.Threading.Channels;
  4. using Grpc.Core;
  5. using Microsoft.AutoGen.Protobuf;
  6. namespace Microsoft.AutoGen.Core.Grpc.Tests;
  7. internal sealed class TestGrpcWorkerConnection : IAsyncDisposable
  8. {
  9. private static long s_nextConnectionId;
  10. private Task _readTask = Task.CompletedTask;
  11. private Task _writeTask = Task.CompletedTask;
  12. private readonly string _connectionId = Interlocked.Increment(ref s_nextConnectionId).ToString();
  13. private readonly object _lock = new();
  14. private readonly HashSet<string> _supportedTypes = [];
  15. private readonly CancellationTokenSource _shutdownCancellationToken = new();
  16. public Task Completion { get; private set; } = Task.CompletedTask;
  17. public IAsyncStreamReader<Message> RequestStream { get; }
  18. public IServerStreamWriter<Message> ResponseStream { get; }
  19. public ServerCallContext ServerCallContext { get; }
  20. private readonly Channel<Message> _outboundMessages;
  21. public TestGrpcWorkerConnection(IAsyncStreamReader<Message> requestStream, IServerStreamWriter<Message> responseStream, ServerCallContext context)
  22. {
  23. RequestStream = requestStream;
  24. ResponseStream = responseStream;
  25. ServerCallContext = context;
  26. _outboundMessages = Channel.CreateUnbounded<Message>(new UnboundedChannelOptions { AllowSynchronousContinuations = true, SingleReader = true, SingleWriter = false });
  27. }
  28. public Task Connect()
  29. {
  30. var didSuppress = false;
  31. if (!ExecutionContext.IsFlowSuppressed())
  32. {
  33. didSuppress = true;
  34. ExecutionContext.SuppressFlow();
  35. }
  36. try
  37. {
  38. _readTask = Task.Run(RunReadPump);
  39. _writeTask = Task.Run(RunWritePump);
  40. }
  41. finally
  42. {
  43. if (didSuppress)
  44. {
  45. ExecutionContext.RestoreFlow();
  46. }
  47. }
  48. return Completion = Task.WhenAll(_readTask, _writeTask);
  49. }
  50. public void AddSupportedType(string type)
  51. {
  52. lock (_lock)
  53. {
  54. _supportedTypes.Add(type);
  55. }
  56. }
  57. public HashSet<string> GetSupportedTypes()
  58. {
  59. lock (_lock)
  60. {
  61. return new HashSet<string>(_supportedTypes);
  62. }
  63. }
  64. public async Task SendMessage(Message message)
  65. {
  66. await _outboundMessages.Writer.WriteAsync(message).ConfigureAwait(false);
  67. }
  68. public async Task RunReadPump()
  69. {
  70. await Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding);
  71. try
  72. {
  73. await foreach (var message in RequestStream.ReadAllAsync(_shutdownCancellationToken.Token))
  74. {
  75. //_gateway.OnReceivedMessageAsync(this, message, _shutdownCancellationToken.Token).Ignore();
  76. switch (message.MessageCase)
  77. {
  78. case Message.MessageOneofCase.Request:
  79. await SendMessage(new Message { Request = message.Request }).ConfigureAwait(false);
  80. break;
  81. case Message.MessageOneofCase.Response:
  82. await SendMessage(new Message { Response = message.Response }).ConfigureAwait(false);
  83. break;
  84. case Message.MessageOneofCase.CloudEvent:
  85. await SendMessage(new Message { CloudEvent = message.CloudEvent }).ConfigureAwait(false);
  86. break;
  87. default:
  88. // if it wasn't recognized return bad request
  89. throw new RpcException(new Status(StatusCode.InvalidArgument, $"Unknown message type for message '{message}'"));
  90. }
  91. }
  92. }
  93. catch (OperationCanceledException)
  94. {
  95. }
  96. finally
  97. {
  98. _shutdownCancellationToken.Cancel();
  99. //_gateway.OnRemoveWorkerProcess(this);
  100. }
  101. }
  102. public async Task RunWritePump()
  103. {
  104. await Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding);
  105. try
  106. {
  107. await foreach (var message in _outboundMessages.Reader.ReadAllAsync(_shutdownCancellationToken.Token))
  108. {
  109. await ResponseStream.WriteAsync(message);
  110. }
  111. }
  112. catch (OperationCanceledException)
  113. {
  114. }
  115. finally
  116. {
  117. _shutdownCancellationToken.Cancel();
  118. }
  119. }
  120. public async ValueTask DisposeAsync()
  121. {
  122. _shutdownCancellationToken.Cancel();
  123. await Completion.ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing);
  124. }
  125. public override string ToString() => $"Connection-{_connectionId}";
  126. }