Ejemplo n.º 1
0
        /// <summary>
        /// Adds a context to the supervisor as an agent, which can be stopped by the supervisor.
        /// </summary>
        /// <param name="supervisor">The supervisor</param>
        /// <typeparam name="T">The context type</typeparam>
        /// <returns>A context handle</returns>
        public static IAsyncPipeContextAgent <T> AddAsyncContext <T>(this ISupervisor supervisor)
            where T : class, PipeContext
        {
            if (supervisor == null)
            {
                throw new ArgumentNullException(nameof(supervisor));
            }

            IAsyncPipeContextAgent <T> contextAgent = new AsyncPipeContextAgent <T>();

            supervisor.Add(contextAgent);

            return(contextAgent);
        }
Ejemplo n.º 2
0
        async Task <TContext> CreateJoinContext(IAsyncPipeContextAgent <TContext> asyncContext, CancellationToken cancellationToken)
        {
            IAsyncPipeContextAgent <TLeft>  leftAgent  = new AsyncPipeContextAgent <TLeft>();
            IAsyncPipeContextAgent <TRight> rightAgent = new AsyncPipeContextAgent <TRight>();

            var leftPipe = new AsyncPipeContextPipe <TLeft>(leftAgent, _leftPipe);
            var leftTask = _leftSource.Send(leftPipe, cancellationToken);

            var rightPipe = new AsyncPipeContextPipe <TRight>(rightAgent, _rightPipe);
            var rightTask = _rightSource.Send(rightPipe, cancellationToken);

            async Task Join()
            {
                try
                {
                    var leftAny = await Task.WhenAny(leftAgent.Context, leftTask).ConfigureAwait(false);

                    if (leftAny == leftTask)
                    {
                        await leftTask.ConfigureAwait(false);
                    }

                    var rightAny = await Task.WhenAny(rightAgent.Context, rightTask).ConfigureAwait(false);

                    if (rightAny == rightTask)
                    {
                        await rightTask.ConfigureAwait(false);
                    }

                    var leftContext = await leftAgent.Context.ConfigureAwait(false);

                    var rightContext = await rightAgent.Context.ConfigureAwait(false);

                    var clientContext = CreateClientContext(leftContext, rightContext);

                    clientContext.GetOrAddPayload(() => rightContext);
                    clientContext.GetOrAddPayload(() => leftContext);

                    await asyncContext.Created(clientContext).ConfigureAwait(false);

                    await asyncContext.Completed.ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    await asyncContext.CreateCanceled().ConfigureAwait(false);
                }
                catch (Exception exception)
                {
                    await asyncContext.CreateFaulted(exception).ConfigureAwait(false);
                }
                finally
                {
                    await Task.WhenAll(leftAgent.Stop("Complete", cancellationToken), rightAgent.Stop("Complete", cancellationToken)).ConfigureAwait(false);
                }

                try
                {
                    await Task.WhenAll(leftTask, rightTask).ConfigureAwait(false);
                }
                catch (Exception exception)
                {
                    LogContext.Warning?.Log(exception, "Join faulted");
                }
            }

            await Task.WhenAny(asyncContext.Context, Join()).ConfigureAwait(false);

            return(await asyncContext.Context.ConfigureAwait(false));
        }