public override async Task StreamingCall(IAsyncStreamReader<SimpleRequest> requestStream, IServerStreamWriter<SimpleResponse> responseStream, ServerCallContext context)
 {
     await requestStream.ForEachAsync(async request =>
     {
         var response = new SimpleResponse { Payload = CreateZerosPayload(request.ResponseSize) };
         await responseStream.WriteAsync(response);
     });
 }
Beispiel #2
1
 public async Task DivMany(ServerCallContext context, IAsyncStreamReader<DivArgs> requestStream, IServerStreamWriter<DivReply> responseStream)
 {
     await requestStream.ForEach(async divArgs =>
     {
         await responseStream.WriteAsync(DivInternal(divArgs));
     });
 }
 public async Task OperationStream(IAsyncStreamReader<ServiceRequest> requestStream, IServerStreamWriter<ServiceResponse> responseStream, ServerCallContext context)
 {
     while (await requestStream.MoveNext(CancellationToken.None))
     {
         await responseStream.WriteAsync(new ServiceResponse { Id = requestStream.Current.Id });
     }
 }
        /// <summary>
        /// Gets a stream of points, and responds with statistics about the "trip": number of points,
        /// number of known features visited, total distance traveled, and total time spent.
        /// </summary>
        public override async Task<RouteSummary> RecordRoute(IAsyncStreamReader<Point> requestStream, ServerCallContext context)
        {
            int pointCount = 0;
            int featureCount = 0;
            int distance = 0;
            Point previous = null;
            var stopwatch = new Stopwatch();
            stopwatch.Start();

            while (await requestStream.MoveNext())
            {
                var point = requestStream.Current;
                pointCount++;
                if (CheckFeature(point).Exists())
                {
                    featureCount++;
                }
                if (previous != null)
                {
                    distance += (int) previous.GetDistance(point);
                }
                previous = point;
            }

            stopwatch.Stop();
            
            return new RouteSummary
            {
                PointCount = pointCount,
                FeatureCount = featureCount,
                Distance = distance,
                ElapsedTime = (int)(stopwatch.ElapsedMilliseconds / 1000)
            };
        }
Beispiel #5
0
 public override async Task ServerReflectionInfo(IAsyncStreamReader<ServerReflectionRequest> requestStream, IServerStreamWriter<ServerReflectionResponse> responseStream, ServerCallContext context)
 {
     while (await requestStream.MoveNext())
     {
         var response = ProcessRequest(requestStream.Current);
         await responseStream.WriteAsync(response);
     }
 }
 public async Task<StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<StreamingInputCallRequest> requestStream, ServerCallContext context)
 {
     int sum = 0;
     await requestStream.ForEachAsync(async request =>
     {
         sum += request.Payload.Body.Length;
     });
     return StreamingInputCallResponse.CreateBuilder().SetAggregatedPayloadSize(sum).Build();
 }
Beispiel #7
0
 public async Task<Num> Sum(ServerCallContext context, IAsyncStreamReader<Num> requestStream)
 {
     long sum = 0;
     await requestStream.ForEach(async num =>
     {
         sum += num.Num_;
     });
     return Num.CreateBuilder().SetNum_(sum).Build();
 }
Beispiel #8
0
 public async Task<StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<StreamingInputCallRequest> requestStream, ServerCallContext context)
 {
     int sum = 0;
     await requestStream.ForEachAsync(async request =>
     {
         sum += request.Payload.Body.Length;
     });
     return new StreamingInputCallResponse { AggregatedPayloadSize = sum };
 }
 public override async Task<Num> Sum(IAsyncStreamReader<Num> requestStream, ServerCallContext context)
 {
     long sum = 0;
     await requestStream.ForEachAsync(async num =>
     {
         sum += num.Num_;
     });
     return new Num { Num_ = sum };
 }
 public async Task<PersonListResponse> CreatePeople(IAsyncStreamReader<Person> requestStream, ServerCallContext context)
 {
     LogRpc(context);
     while (await requestStream.MoveNext(CancellationToken.None))
     {
         var person = requestStream.Current;
         _personRepository.TryCreate(person);
     }
     return new PersonListResponse { People = { _personRepository.GetAllPeople() } };
 }
Beispiel #11
0
 public async Task FullDuplexCall(IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
 {
     await requestStream.ForEachAsync(async request =>
     {
         foreach (var responseParam in request.ResponseParameters)
         {
             var response = new StreamingOutputCallResponse { Payload = CreateZerosPayload(responseParam.Size) };
             await responseStream.WriteAsync(response);
         }
     });
 }
Beispiel #12
0
 public async Task FullDuplexCall(ServerCallContext context, IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream)
 {
     await requestStream.ForEach(async request =>
     {
         foreach (var responseParam in request.ResponseParametersList)
         {
             var response = StreamingOutputCallResponse.CreateBuilder()
                 .SetPayload(CreateZerosPayload(responseParam.Size)).Build();
             await responseStream.WriteAsync(response);
         }
     });
 }
 public async Task<ChatMessageCollection> GetChatHistory(IAsyncStreamReader<ChatMessageRequest> requestStream, ServerCallContext context)
 {
     Log(context);
     var responses = new List<ChatMessage>();
     // Async enumerator
     while (await requestStream.MoveNext(CancellationToken.None))
     {
         ChatMessageRequest chatMessageRequest = requestStream.Current;
         ICollection<ChatMessage> chatMessages = await _chatMessageRepository.GetAccountChatHistoryAsync(chatMessageRequest.AccountId);
         responses.AddRange(chatMessages);
     }
     return new ChatMessageCollection { ChatMessages = { responses } };
 }
        public async Task Chat(IAsyncStreamReader<ChatMessage> requestStream, IServerStreamWriter<ChatMessage> responseStream, ServerCallContext context)
        {
            Log(context);

            Program.Log("Server starting to chat");
            while (await requestStream.MoveNext())
            {
                ChatMessage clientChatMessage = requestStream.Current;
                Program.Log($"Client says {clientChatMessage}");

                ChatMessage serverChatMessage = Utility.GetRandomChatMessage(0);
                await responseStream.WriteAsync(serverChatMessage);
            }

            // Returning from the method will automatically complete the response async enumerator on the client.
        }
        public override async Task RunClient(IAsyncStreamReader<ClientArgs> requestStream, IServerStreamWriter<ClientStatus> responseStream, ServerCallContext context)
        {
            GrpcPreconditions.CheckState(await requestStream.MoveNext());
            var clientConfig = requestStream.Current.Setup;
            var runner = ClientRunners.CreateStarted(clientConfig);

            await responseStream.WriteAsync(new ClientStatus
            {
                Stats = runner.GetStats(false)
            });

            while (await requestStream.MoveNext())
            {
                var reset = requestStream.Current.Mark.Reset;
                await responseStream.WriteAsync(new ClientStatus
                {
                    Stats = runner.GetStats(reset)
                });
            }
            await runner.StopAsync();
        }
        public override async Task RunServer(IAsyncStreamReader<ServerArgs> requestStream, IServerStreamWriter<ServerStatus> responseStream, ServerCallContext context)
        {
            GrpcPreconditions.CheckState(await requestStream.MoveNext());
            var serverConfig = requestStream.Current.Setup;
            var runner = ServerRunners.CreateStarted(serverConfig);

            await responseStream.WriteAsync(new ServerStatus
            {
                Stats = runner.GetStats(false),
                Port = runner.BoundPort,
                Cores = Environment.ProcessorCount,
            });
                
            while (await requestStream.MoveNext())
            {
                var reset = requestStream.Current.Mark.Reset;
                await responseStream.WriteAsync(new ServerStatus
                {
                    Stats = runner.GetStats(reset)
                });
            }
            await runner.StopAsync();
        }
Beispiel #17
0
 public static ResponseProgress <TResult, TProgress> Create <TResult, TProgress>(
     IAsyncStreamReader <IProgressMessage <TResult, TProgress> > streamReader,
     IProgress <TProgress>?progress = null)
 {
     return(new ResponseProgress <TResult, TProgress>(streamReader, progress));
 }
Beispiel #18
0
            public override async Task <AverageResponse> AverageStreaming(IAsyncStreamReader <SingleNumber> requestStream, ServerCallContext callContext)
            {
                double runningSum     = 0;
                int    runningSamples = 0;

                while (await requestStream.MoveNext(default))
        public override Task <TResponse> ClientStreamingServerHandler <TRequest, TResponse>(IAsyncStreamReader <TRequest> requestStream, ServerCallContext context, ClientStreamingServerMethod <TRequest, TResponse> continuation)
        {
            var methodName = context.Method.Split('/').Last();
            var callMethod = _methods.FirstOrDefault(p => p.Name == methodName);

            var serviceScopeFactory = _serviceProvider.GetService <IServiceScopeFactory>();

            using (var scope = serviceScopeFactory.CreateScope())
            {
                var serviceInstance = scope.ServiceProvider.GetService(serviceType);
                var serviceResult   = callMethod.Invoke(serviceInstance, new object[] { requestStream, context });

                return(serviceResult as Task <TResponse>);
            }
        }
 public async Task HalfDuplexCall(IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream, ServerCallContext context)
 {
     throw new NotImplementedException();
 }
 public GcpClientResponseStream(IAsyncStreamReader <TResponse> originalStreamReader, Action <TResponse> postProcess)
 {
     this._originalStreamReader = originalStreamReader;
     this._postProcess          = postProcess;
 }
Beispiel #22
0
 public override Task PushFile(IAsyncStreamReader <PushFileRequest> requestStream, IServerStreamWriter <PushFileResponse> responseStream, ServerCallContext context) => _contentServer.HandlePushFileAsync(requestStream, responseStream, context);
Beispiel #23
0
        public override async Task <VoidReply> LibAnnouncementBroadcastStream(IAsyncStreamReader <LibAnnouncement> requestStream, ServerCallContext context)
        {
            await requestStream.ForEachAsync(async r => await ProcessLibAnnouncement(r, context));

            return(new VoidReply());
        }
 public override async Task DivMany(IAsyncStreamReader<DivArgs> requestStream, IServerStreamWriter<DivReply> responseStream, ServerCallContext context)
 {
     await requestStream.ForEachAsync(async divArgs => await responseStream.WriteAsync(DivInternal(divArgs)));
 }
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="requestStream">请求流</param>
        /// <param name="responseStream">响应流</param>
        /// <param name="context">站点上下文</param>
        /// <returns></returns>
        public override async Task UploadFile(IAsyncStreamReader <FileReply> requestStream, IServerStreamWriter <FileResponse> responseStream, ServerCallContext context)
        {
            List <string>    lstFilesName = new List <string>();    //文件名
            List <FileReply> lstContents  = new List <FileReply>(); //数据集合

            FileStream fs        = null;
            DateTime   startTime = DateTime.Now;//开始时间
            string     mark      = string.Empty;
            string     savePath  = string.Empty;

            try
            {
                //reply.Block数字的含义是服务器和客户端约定的
                while (await requestStream.MoveNext())//读取数据
                {
                    var reply = requestStream.Current;
                    mark = reply.Mark;
                    if (reply.Block == -2)//传输完成
                    {
                        Console.WriteLine($"{mark},完成上传文件。共计【{lstFilesName.Count}】个,耗时:{DateTime.Now - startTime}");
                        break;
                    }
                    else if (reply.Block == -1)//取消了传输
                    {
                        Console.WriteLine($"文件【{reply.FileName}】取消传输!");
                        lstContents.Clear();
                        fs?.Close();
                        if (!string.IsNullOrEmpty(savePath) && File.Exists(savePath))//如果传输不成功,删除该文件
                        {
                            File.Delete(savePath);
                        }
                        savePath = string.Empty;
                        break;
                    }
                    else if (reply.Block == 0) //文件传输完成
                    {
                        if (lstContents.Any()) //如果还有数据,就写入文件
                        {
                            lstContents.OrderBy(c => c.Block).ToList().ForEach(c => c.Content.WriteTo(fs));
                            lstContents.Clear();
                        }
                        lstFilesName.Add(savePath); //传输成功的文件
                        fs?.Close();                //释放文件流
                        savePath = string.Empty;

                        //告知客户端,已经完成传输
                        await responseStream.WriteAsync(new FileResponse
                        {
                            FileName = reply.FileName,
                            Mark     = mark
                        });
                    }
                    else
                    {
                        //有新文件
                        if (string.IsNullOrEmpty(savePath))
                        {
                            savePath = $"{AppContext.BaseDirectory}\\{Config.Options.JobDirectory}\\{reply.FileName}".Replace('\\', Path.DirectorySeparatorChar);
                            fs       = new FileStream(savePath, FileMode.Create, FileAccess.ReadWrite);
                            Console.WriteLine($"{mark},上传文件:{savePath},{DateTime.UtcNow.ToString("HH:mm:ss:ffff")}");
                        }
                        lstContents.Add(reply);
                        if (lstContents.Count() >= 20)//每个包1M,20M为一个集合,一起写入数据。
                        {
                            lstContents.OrderBy(c => c.Block).ToList().ForEach(c => c.Content.WriteTo(fs));
                            lstContents.Clear();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"{mark},发生异常({ex.GetType()}):{ex.Message}");
            }
            finally
            {
                fs?.Dispose();
            }
        }
Beispiel #26
0
        private async Task <(long Chunks, long Bytes)> StreamContentWithCompressionAsync(Stream targetStream, IAsyncStreamReader <CopyFileResponse> replyStream, CancellationToken ct)
        {
            Contract.Requires(targetStream != null);
            Contract.Requires(replyStream != null);

            long chunks = 0L;
            long bytes  = 0L;

            using (BufferedReadStream grpcStream = new BufferedReadStream(async() =>
            {
                if (await replyStream.MoveNext(ct))
                {
                    chunks++;
                    bytes += replyStream.Current.Content.Length;
                    return(replyStream.Current.Content.ToByteArray());
                }
                else
                {
                    return(null);
                }
            }))
            {
                using (Stream decompressedStream = new GZipStream(grpcStream, CompressionMode.Decompress, true))
                {
                    await decompressedStream.CopyToAsync(targetStream, _bufferSize, ct);
                }
            }

            return(chunks, bytes);
        }
Beispiel #27
0
        private async Task <(long Chunks, long Bytes)> StreamContentAsync(Stream targetStream, IAsyncStreamReader <CopyFileResponse> replyStream, CancellationToken ct)
        {
            Contract.Requires(targetStream != null);
            Contract.Requires(replyStream != null);

            long chunks = 0L;
            long bytes  = 0L;

            while (await replyStream.MoveNext(ct))
            {
                chunks++;
                CopyFileResponse reply = replyStream.Current;
                bytes += reply.Content.Length;
                reply.Content.WriteTo(targetStream);
            }
            return(chunks, bytes);
        }
Beispiel #28
0
 public virtual global::System.Threading.Tasks.Task <global::Proto.Remoting.Unit> Receive(
     IAsyncStreamReader <global::Proto.Remoting.MessageBatch> requestStream, ServerCallContext context)
 {
     throw new RpcException(new Status(StatusCode.Unimplemented, ""));
 }
Beispiel #29
0
 /// <summary>
 /// Constructor for <see cref="IAsyncStreamReader{T}"/> wrapper
 /// </summary>
 /// <param name="reader">Stream reader that should be wrapped by this class</param>
 /// <param name="onMessage">Action that should be executed on each message received from the stream</param>
 public WrapperStreamReader(IAsyncStreamReader <T> reader, Action onMessage)
 {
     _reader    = reader;
     _onMessage = onMessage;
 }
Beispiel #30
0
        public override Task <TResponse> ClientStreamingServerHandler <TRequest, TResponse>(IAsyncStreamReader <TRequest> requestStream, ServerCallContext context,
                                                                                            ClientStreamingServerMethod <TRequest, TResponse> continuation)
        {
            try
            {
                var peer = _peerPool.FindPeerByPublicKey(context.GetPublicKey());

                if (peer == null)
                {
                    Logger.LogWarning($"Could not find peer {context.GetPublicKey()}");
                    return(Task.FromResult <TResponse>(null));
                }

                if (!peer.InboundSessionId.BytesEqual(context.GetSessionId()))
                {
                    Logger.LogWarning($"Wrong session id, ({peer.InboundSessionId.ToHex()} vs {context.GetSessionId().ToHex()}) {context.GetPublicKey()}");
                    return(Task.FromResult <TResponse>(null));
                }

                context.RequestHeaders.Add(new Metadata.Entry(GrpcConstants.PeerInfoMetadataKey, $"{peer}"));
            }
            catch (Exception e)
            {
                Logger.LogError("Auth interceptor error: ", e);
                return(null);
            }

            return(continuation(requestStream, context));
        }
Beispiel #31
0
 /// <summary>
 ///  A sequence of requests followed by a sequence of responses.
 ///  The server buffers all the client requests and then serves them in order. A
 ///  stream of responses are returned to the client when the server starts with
 ///  first request.
 /// </summary>
 public virtual global::System.Threading.Tasks.Task HalfDuplexCall(IAsyncStreamReader <global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter <global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
 {
     throw new RpcException(new Status(StatusCode.Unimplemented, ""));
 }
Beispiel #32
0
    /// <inheritdoc/>
    public override async Task Connect(
        IAsyncStreamReader <EmbeddingClientToRuntimeMessage> runtimeStream,
        IServerStreamWriter <EmbeddingRuntimeToClientMessage> clientStream,
        ServerCallContext context)
    {
        // TODO: It seems like things are not properly unregistered on exceptions?
        // TODO: I tested this out and while making the DI container work, it kept failing and telling me that the projection was already registered on the second attempt.

        Log.ConnectingEmbeddings(_logger);
        using var cts = CancellationTokenSource.CreateLinkedTokenSource(_hostApplicationLifetime.ApplicationStopping, context.CancellationToken);
        var connection = await _reverseCallServices.Connect(runtimeStream, clientStream, context, _protocol, context.CancellationToken).ConfigureAwait(false);

        if (!connection.Success)
        {
            return;
        }
        using var dispatcher = connection.Result.dispatcher;
        var arguments = connection.Result.arguments;

        var tryCreateExecutionContext = _executionContextCreator.TryCreateUsing(arguments.ExecutionContext);

        if (!tryCreateExecutionContext.Success)
        {
            await dispatcher.Reject(
                _protocol.CreateFailedConnectResponse($"Failed to register embedding because the execution context is invalid: ${tryCreateExecutionContext.Exception.Message}"),
                cts.Token).ConfigureAwait(false);

            return;
        }

        var executionContext = tryCreateExecutionContext.Result; // TODO: Use this

        if (_embeddingProcessors.HasEmbeddingProcessors(arguments.Definition.Embedding))
        {
            await dispatcher.Reject(
                _protocol.CreateFailedConnectResponse($"Failed to register Embedding: {arguments.Definition.Embedding.Value}. Embedding already registered with the same id"),
                cts.Token).ConfigureAwait(false);

            return;
        }

        if (await RejectIfInvalidDefinition(arguments.Definition, dispatcher, cts.Token).ConfigureAwait(false))
        {
            return;
        }
        var persistDefinition = await _embeddingDefinitionPersister.TryPersist(arguments.Definition, cts.Token).ConfigureAwait(false);

        if (!persistDefinition.Success)
        {
            await dispatcher.Reject(
                _protocol.CreateFailedConnectResponse($"Failed to register Embedding: {arguments.Definition.Embedding.Value}. Failed to persist embedding definition. {persistDefinition.Exception.Message}"),
                cts.Token).ConfigureAwait(false);

            return;
        }

        var dispatcherTask = dispatcher.Accept(new EmbeddingRegistrationResponse(), cts.Token);
        var processorTask  = _embeddingProcessors.TryStartEmbeddingProcessorForAllTenants(
            arguments.Definition.Embedding,
            tenant => _getEmbeddingProcessorFactoryFor(tenant)
            .Create(
                arguments.Definition.Embedding,
                new Embedding(
                    arguments.Definition.Embedding,
                    dispatcher,
                    _embeddingRequestFactory,
                    _loggerFactory.CreateLogger <Embedding>()),
                arguments.Definition.InititalState,
                executionContext),
            cts.Token);


        var tasks = new TaskGroup(dispatcherTask, processorTask);
        await tasks.WaitForAllCancellingOnFirst(cts).ConfigureAwait(false);
    }
 /// <summary>
 /// Receives a stream of message/location pairs, and responds with a stream of all previous
 /// messages at each of those locations.
 /// </summary>
 public override async Task RouteChat(IAsyncStreamReader<RouteNote> requestStream, IServerStreamWriter<RouteNote> responseStream, ServerCallContext context)
 {
     while (await requestStream.MoveNext())
     {
         var note = requestStream.Current;
         List<RouteNote> prevNotes = AddNoteForLocation(note.Location, note);
         foreach (var prevNote in prevNotes)
         {
             await responseStream.WriteAsync(prevNote);
         }
     }
 }
 public LoggableStreamReader(IMagicOnionLogger logger, ServiceContext context, IAsyncStreamReader <T> reader)
 {
     this.logger  = logger;
     this.context = context;
     this.reader  = reader;
 }
Beispiel #35
0
        public async Task HandlePushFileAsync(IAsyncStreamReader <PushFileRequest> requestStream, IServerStreamWriter <PushFileResponse> responseStream, ServerCallContext callContext)
        {
            // Detaching from the calling thread to (potentially) avoid IO Completion port thread exhaustion
            await Task.Yield();

            var startTime = DateTime.UtcNow;

            var pushRequest = PushRequest.FromMetadata(callContext.RequestHeaders);

            var hash         = pushRequest.Hash;
            var cacheContext = new Context(pushRequest.TraceId, Logger);
            var token        = callContext.CancellationToken;

            var store = _contentStoreByCacheName.Values.OfType <IPushFileHandler>().FirstOrDefault();

            if (!CanHandlePushRequest(cacheContext, hash, store))
            {
                await callContext.WriteResponseHeadersAsync(PushResponse.DoNotCopy.Metadata);

                return;
            }

            try
            {
                // Running the logic inside try/finally block to remove the hash being processed regardless of the result of this method.
                await callContext.WriteResponseHeadersAsync(PushResponse.Copy.Metadata);

                PutResult?result = null;
                using (var disposableFile = new DisposableFile(cacheContext, _fileSystem, _temporaryDirectory !.CreateRandomFileName()))
                {
                    // NOTE(jubayard): DeleteOnClose not used here because the file needs to be placed into the CAS.
                    // Opening a file for read/write and then doing pretty much anything to it leads to weird behavior
                    // that needs to be tested on a case by case basis. Since we don't know what the underlying store
                    // plans to do with the file, it is more robust to just use the DisposableFile construct.
                    using (var tempFile = await _fileSystem.OpenSafeAsync(disposableFile.Path, FileAccess.Write, FileMode.CreateNew, FileShare.None))
                    {
                        while (await requestStream.MoveNext())
                        {
                            if (token.IsCancellationRequested)
                            {
                                return;
                            }

                            var request = requestStream.Current;
                            var bytes   = request.Content.ToByteArray();
                            await tempFile.WriteAsync(bytes, 0, bytes.Length, token);
                        }
                    }

                    result = await store.HandlePushFileAsync(cacheContext, hash, disposableFile.Path, token);
                }

                var response = result
                    ? new PushFileResponse {
                    Header = ResponseHeader.Success(startTime)
                }
                    : new PushFileResponse {
                    Header = ResponseHeader.Failure(startTime, result.ErrorMessage)
                };

                await responseStream.WriteAsync(response);
            }
            finally
            {
                _ongoingPushes.Remove(hash);
            }
        }
Beispiel #36
0
        public override async Task GetTownWeatherStream(
            IAsyncStreamReader <TownWeatherRequest> requestStream,
            IServerStreamWriter <TownWeatherForecast> responseStream,
            ServerCallContext context)
        {
            var rng = new Random();
            var now = DateTime.UtcNow;

            // we'll use a channel here to handle in-process 'messages' concurrently being written to and read from the channel.
            var channel = Channel.CreateUnbounded <TownWeatherForecast>();

            // background task which uses async streams to write each forecast from the channel to the response steam.
            _ = Task.Run(async() =>
            {
                await foreach (var forecast in channel.Reader.ReadAllAsync())
                {
                    await responseStream.WriteAsync(forecast);
                }
            });

            // a list of tasks handling requests concurrently
            var getTownWeatherRequestTasks = new List <Task>();

            try
            {
                // async streams used to process each request from the stream as they are receieved
                await foreach (var request in requestStream.ReadAllAsync())
                {
                    _logger.LogInformation($"Getting weather for {request.TownName}");
                    getTownWeatherRequestTasks.Add(GetTownWeatherAsync(request.TownName)); // start and add the request handling task
                }

                _logger.LogInformation("Client finished streaming");
            }
            catch (Exception e)
            {
                _logger.LogError(e, "An exception occurred");
            }

            // wait for all responses to be written to the channel
            // from the concurrent tasks handling each request
            await Task.WhenAll(getTownWeatherRequestTasks);

            channel.Writer.TryComplete();

            //  wait for all responses to be read from the channel and streamed as responses
            await channel.Reader.Completion;

            _logger.LogInformation("Completed response streaming");

            // a local function which defines a task to handle a town forecast request
            // it produces 10 forecasts for each town, simulating a 0.5s time to gather each forecast
            // multiple instances of this will run concurrently for each recieved request
            async Task GetTownWeatherAsync(string town)
            {
                for (var i = 0; i < 10; i++)
                {
                    var forecast = new WeatherData
                    {
                        DateTimeStamp = Timestamp.FromDateTime(now.AddDays(i)),
                        TemperatureC  = rng.Next(-20, 55),
                        Summary       = Summaries[rng.Next(Summaries.Length)]
                    };

                    await Task.Delay(500); // Gotta look busy

                    // write the forecast to the channel which will be picked up concurrently by the channel reading background task
                    await channel.Writer.WriteAsync(new TownWeatherForecast
                    {
                        TownName    = town,
                        WeatherData = forecast
                    });
                }
            }
        }
Beispiel #37
0
 public override async Task <TResponse> ClientStreamingServerHandler <TRequest, TResponse>(IAsyncStreamReader <TRequest> requestStream,
                                                                                           ServerCallContext context, ClientStreamingServerMethod <TRequest, TResponse> continuation)
 {
     return(await Monitor <TRequest, TResponse>(requestStream, context, continuation));
 }
Beispiel #38
0
 public override Task StreamAggregatedResources(IAsyncStreamReader <DiscoveryRequest> requestStream,
                                                IServerStreamWriter <DiscoveryResponse> responseStream,
                                                ServerCallContext context)
 {
     return(_services.HandleStream(requestStream, responseStream, context, TypeStrings.Any));
 }
Beispiel #39
0
 public override async Task DuplexStreamingServerHandler <TRequest, TResponse>(IAsyncStreamReader <TRequest> requestStream, IServerStreamWriter <TResponse> responseStream, ServerCallContext context, DuplexStreamingServerMethod <TRequest, TResponse> continuation)
 {
     await Monitor <TRequest, TResponse>(requestStream, context, continuation, responseStream);
 }
Beispiel #40
0
        public override async Task <AppendResp> Append(
            IAsyncStreamReader <AppendReq> requestStream,
            ServerCallContext context)
        {
            if (!await requestStream.MoveNext().ConfigureAwait(false))
            {
                throw new InvalidOperationException();
            }

            if (requestStream.Current.ContentCase != AppendReq.ContentOneofCase.Options)
            {
                throw new InvalidOperationException();
            }

            var options         = requestStream.Current.Options;
            var streamName      = options.StreamName;
            var expectedVersion = options.ExpectedStreamRevisionCase switch {
                AppendReq.Types.Options.ExpectedStreamRevisionOneofCase.Revision => new StreamRevision(
                    options.Revision).ToInt64(),
                AppendReq.Types.Options.ExpectedStreamRevisionOneofCase.Any => AnyStreamRevision.Any.ToInt64(),
                AppendReq.Types.Options.ExpectedStreamRevisionOneofCase.StreamExists => AnyStreamRevision.StreamExists.ToInt64(),
                AppendReq.Types.Options.ExpectedStreamRevisionOneofCase.NoStream => AnyStreamRevision.NoStream.ToInt64(),
                _ => throw new InvalidOperationException()
            };

            var user           = context.GetHttpContext().User;
            var requiresLeader = GetRequiresLeader(context.RequestHeaders);

            var correlationId = Guid.NewGuid();             // TODO: JPB use request id?

            var events = new List <Event>();

            var size = 0;

            while (await requestStream.MoveNext().ConfigureAwait(false))
            {
                if (requestStream.Current.ContentCase != AppendReq.ContentOneofCase.ProposedMessage)
                {
                    throw new InvalidOperationException();
                }

                var proposedMessage = requestStream.Current.ProposedMessage;
                var data            = proposedMessage.Data.ToByteArray();
                size += data.Length;

                if (size > _maxAppendSize)
                {
                    throw RpcExceptions.MaxAppendSizeExceeded(_maxAppendSize);
                }

                if (!proposedMessage.Metadata.TryGetValue(Constants.Metadata.Type, out var eventType))
                {
                    throw RpcExceptions.RequiredMetadataPropertyMissing(Constants.Metadata.Type);
                }

                if (!proposedMessage.Metadata.TryGetValue(Constants.Metadata.ContentType, out var contentType))
                {
                    throw RpcExceptions.RequiredMetadataPropertyMissing(Constants.Metadata.ContentType);
                }

                events.Add(new Event(
                               Uuid.FromDto(proposedMessage.Id).ToGuid(),
                               eventType,
                               contentType == Constants.Metadata.ContentTypes.ApplicationJson,
                               data,
                               proposedMessage.CustomMetadata.ToByteArray()));
            }

            var appendResponseSource = new TaskCompletionSource <AppendResp>();

            var envelope = new CallbackEnvelope(HandleWriteEventsCompleted);

            _queue.Publish(new ClientMessage.WriteEvents(
                               correlationId,
                               correlationId,
                               envelope,
                               true,
                               streamName,
                               expectedVersion,
                               events.ToArray(),
                               user));

            return(await appendResponseSource.Task.ConfigureAwait(false));

            void HandleWriteEventsCompleted(Message message)
            {
                if (message is ClientMessage.NotHandled notHandled && RpcExceptions.TryHandleNotHandled(notHandled, out var ex))
                {
                    appendResponseSource.TrySetException(ex);
                    return;
                }

                if (!(message is ClientMessage.WriteEventsCompleted completed))
                {
                    appendResponseSource.TrySetException(
                        RpcExceptions.UnknownMessage <ClientMessage.WriteEventsCompleted>(message));
                    return;
                }

                switch (completed.Result)
                {
                case OperationResult.Success:
                    var response = new AppendResp();

                    if (completed.LastEventNumber == -1)
                    {
                        response.NoStream = new Empty();
                    }
                    else
                    {
                        response.CurrentRevision = StreamRevision.FromInt64(completed.LastEventNumber);
                    }

                    if (completed.CommitPosition == -1)
                    {
                        response.NoPosition = new Empty();
                    }
                    else
                    {
                        var position = Position.FromInt64(completed.CommitPosition, completed.PreparePosition);
                        response.Position = new AppendResp.Types.Position {
                            CommitPosition  = position.CommitPosition,
                            PreparePosition = position.PreparePosition
                        };
                    }

                    appendResponseSource.TrySetResult(response);
                    return;

                case OperationResult.PrepareTimeout:
                case OperationResult.CommitTimeout:
                case OperationResult.ForwardTimeout:
                    appendResponseSource.TrySetException(RpcExceptions.Timeout());
                    return;

                case OperationResult.WrongExpectedVersion:
                    appendResponseSource.TrySetException(RpcExceptions.WrongExpectedVersion(
                                                             streamName,
                                                             expectedVersion,
                                                             completed.CurrentVersion));
                    return;

                case OperationResult.StreamDeleted:
                    appendResponseSource.TrySetException(RpcExceptions.StreamDeleted(streamName));
                    return;

                case OperationResult.InvalidTransaction:
                    appendResponseSource.TrySetException(RpcExceptions.InvalidTransaction());
                    return;

                case OperationResult.AccessDenied:
                    appendResponseSource.TrySetException(RpcExceptions.AccessDenied());
                    return;

                default:
                    appendResponseSource.TrySetException(RpcExceptions.UnknownError(completed.Result));
                    return;
                }
            }
        }
    }
Beispiel #41
0
 /// <summary>
 /// Handler used for unimplemented method.
 /// </summary>
 private Task UnimplementedMethod(IAsyncStreamReader <byte[]> requestStream, IServerStreamWriter <byte[]> responseStream, ServerCallContext ctx)
 {
     ctx.Status = new Status(StatusCode.Unimplemented, "");
     return(TaskUtils.CompletedTask);
 }
Beispiel #42
0
 public virtual Task <global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader <global::Grpc.Testing.StreamingInputCallRequest> requestStream, ServerCallContext context)
 {
     throw new RpcException(new Status(StatusCode.Unimplemented, ""));
 }
Beispiel #43
0
 public static IObservable <T> AsObservable <T>(this IAsyncStreamReader <T> reader) =>
 new GrpcStreamObservable <T>(reader);
Beispiel #44
0
 private static async Task<string> ConcatAndEchoHandler(IAsyncStreamReader<string> requestStream, ServerCallContext context)
 {
     string result = "";
     await requestStream.ForEach(async (request) =>
     {
         if (request == "THROW")
         {
             throw new Exception("This was thrown on purpose by a test");
         }
         result += request;
     });
     // simulate processing takes some time.
     await Task.Delay(250);
     return result;
 }
Beispiel #45
0
 /// <summary>
 /// Create a new instance.
 /// </summary>
 /// <param name="streamReader">The stream reader.</param>
 /// <param name="converter">Conversion method.</param>
 internal AsyncConvertAsyncStreamReader(IAsyncStreamReader <TResponse> streamReader, Func <TResponse, Task <TResult> > converter)
 {
     m_StreamReader = streamReader;
     m_Converter    = converter;
 }
Beispiel #46
0
 public MarshallingAsyncStreamReader(IAsyncStreamReader <byte[]> inner, IFormatterResolver resolver)
 {
     this.inner    = inner;
     this.resolver = resolver;
 }
            static Task ChatBufferHint(IAsyncStreamReader <ChatMessage> requestStream, IServerStreamWriter <ChatMessage> responseStream, ServerCallContext context)
            {
                context.WriteOptions = new WriteOptions(WriteFlags.BufferHint);

                return(ChatterService.ChatCore(requestStream, responseStream));
            }
 public override Task HalfDuplexCall(IAsyncStreamReader <StreamingOutputCallRequest> requestStream, IServerStreamWriter <StreamingOutputCallResponse> responseStream, ServerCallContext context)
 {
     throw new NotImplementedException();
 }
Beispiel #49
0
 public override Task StreamRoutes(IAsyncStreamReader <DiscoveryRequest> requestStream, IServerStreamWriter <DiscoveryResponse> responseStream, ServerCallContext context)
 {
     return(_service.HandleStream(requestStream, responseStream, context, TypeStrings.RouteType));
 }
Beispiel #50
0
 /// <summary>
 /// Generic streaming call handler.
 /// </summary>
 public async Task StreamingCall(IAsyncStreamReader<byte[]> requestStream, IServerStreamWriter<byte[]> responseStream, ServerCallContext context)
 {
     await requestStream.ForEachAsync(async request =>
     {
         await responseStream.WriteAsync(response);
     });
 }
Beispiel #51
0
        public void AsyncDuplexStreamingCall_returns_builder(IClientStreamWriter <HelloRequest> requests, IAsyncStreamReader <HelloReply> responses)
        {
            var call = TestCallBuilder.AsyncDuplexStreamingCall(requests, responses);

            Assert.That(call, Is.InstanceOf <AsyncDuplexStreamingTestCallBuilder <HelloRequest, HelloReply> >());
        }