public IPipeline Create(IServiceProvider hostServiceProvider, int pipelineId) { var pipelineServices = new ChildServiceCollection <IPipeline>(this.hostServices, hostServiceProvider); this.pipelineAction(pipelineServices); return(ActivatorUtilities.CreateInstance <Pipeline>(hostServiceProvider, pipelineServices, pipelineId)); }
private async Task OnNewConnection(IConnection connection) { using (logger.BeginPropertyScope("Connection", connection.UniqueIdentifier)) using (logger.BeginPropertyScope("PipelineId", this.pipelineId)) { logger.LogInformation("New connection: {Connection} on pipeline {PipelineId}"); try { var sessionServices = new ChildServiceCollection <ISession>(this.services, this.serviceProvider); sessionServices.AddSingleton <IStateManager, StateManager>(); var sessionServiceProvider = sessionServices.BuildServiceProvider(); var channel = sessionServiceProvider.GetService <IChannel>(); var textChannel = sessionServiceProvider.GetService <ITextChannel>(); if (channel == null) { this.logger.LogError("No channel configured for pipeline {PipelineId}."); return; } channel.Bind(connection); Func <Task> pipeline = async() => { if (textChannel != null) { await textChannel.ReceiveLineAsync(); } }; foreach (var middleware in this.middlewares.Reverse()) { pipeline = middleware.BuildHandler(sessionServiceProvider, pipeline); } await pipeline(); } catch (ClientDisconnectedException) { this.logger.LogWarning("Client disconnected unexpectedly: {Connection}"); } finally { connection.Close(); await connection.Closed; logger.LogInformation("Connection closed: {Connection}"); } } }
private async Task OnNewConnection(IConnection connection) { using (logger.BeginPropertyScope("Connection", connection.UniqueIdentifier)) using (logger.BeginPropertyScope("PipelineId", this.pipelineId)) { logger.LogInformation("New connection: {Connection} on pipeline {PipelineId}"); try { var sessionServices = new ChildServiceCollection <ISession>(this.services, this.serviceProvider); sessionServices.AddSingleton <IStateManager, StateManager>(); var sessionServiceProvider = sessionServices.BuildServiceProvider(); var channels = sessionServiceProvider.GetServices <IChannel>(); Action <byte> stack = x => { }; Action <SignalType> signalStack = x => { }; Func <ArraySegment <byte>, Task> send = connection.Send.SendAsync; foreach (var channel in channels.Reverse()) { var stackTemp = stack; var signalTemp = signalStack; stack = datum => channel.Handle(datum, stackTemp, signalTemp); signalStack = signal => channel.Signal(signal, signalTemp); } foreach (var channel in channels) { send = channel.Bind(send); } connection.Receive.LinkTo(new ActionBlock <(ArraySegment <byte> Data, bool IsComplete)>(frame => { this.logger.LogDebug("Received {ByteCount} bytes.", frame.Data.Count); foreach (var datum in frame.Data) { stack(datum); } if (frame.IsComplete) { signalStack(SignalType.EndOfFrame); } })); Func <Task> pipeline = () => Task.CompletedTask; foreach (var middleware in this.middlewares.Reverse()) { pipeline = middleware.BuildHandler(sessionServiceProvider, pipeline); } logger.LogDebug("Pipeline {PipelineId} built; starting."); await pipeline(); signalStack(SignalType.ConnectionClosed); } catch (ClientDisconnectedException) { this.logger.LogWarning("Client disconnected unexpectedly: {Connection}"); } finally { connection.Close(); await connection.Closed; logger.LogInformation("Connection closed: {Connection}"); } } }