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));
        }
Exemple #2
0
        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}");
                    }
                }
        }
Exemple #3
0
        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}");
                    }
                }
        }