Example #1
0
 /// <param name="first"> First conveyor </param>
 /// <param name="second"> Second conveyor </param>
 /// <exception cref="ArgumentNullException"> Thrown if <paramref name="first" /> or <paramref name="second" /> is NULL </exception>
 public PriorityConveyorChain(IPriorityConveyor <TData, TIntermediate> first, IConveyor <TIntermediate, TResult> second)
 {
     _first       = first ?? throw new ArgumentNullException(nameof(first));
     _second      = new PriorityConveyorEmulator <TIntermediate, TResult>(second);
     _maxPriority = Math.Max(_first.MaxPriority, _second.MaxPriority);
     _maxAttempts = Math.Max(_first.MaxAttempts, _second.MaxAttempts);
 }
Example #2
0
 /// <param name="first"> First conveyor </param>
 /// <param name="second"> Second conveyor </param>
 /// <param name="third"> Third conveyor </param>
 /// <exception cref="ArgumentNullException"> Thrown if <paramref name="first" />, <paramref name="second" /> or <paramref name="third" /> is NULL </exception>
 public PriorityConveyorChain(IConveyor <TData, TFirstIntermediate> first, IConveyor <TFirstIntermediate, TSecondIntermediate> second,
                              IPriorityConveyor <TSecondIntermediate, TResult> third)
 {
     _first       = new PriorityConveyorEmulator <TData, TFirstIntermediate>(first);
     _second      = new PriorityConveyorEmulator <TFirstIntermediate, TSecondIntermediate>(second);
     _third       = third ?? throw new ArgumentNullException(nameof(third));
     _maxAttempts = Math.Max(_first.MaxAttempts, Math.Max(_second.MaxAttempts, _third.MaxAttempts));
     _maxPriority = Math.Max(_first.MaxPriority, Math.Max(_second.MaxPriority, _third.MaxPriority));
 }
Example #3
0
 /// <inheritdoc cref="ProcessDataAsync{TData,TResult}(IPriorityConveyor{TData,TResult},IEnumerable{TData},int,CancellationToken,int,bool)" />
 public static IAsyncEnumerable <TResult> ProcessDataAsync <TData, TResult>(this IEnumerable <TData> data, IPriorityConveyor <TData, TResult> conveyor,
                                                                            int priority = 0, CancellationToken cancellation = default, int attemptsCount = 1, bool enqueueAll = false)
     where TData : notnull
 => (conveyor ?? throw new ArgumentNullException(nameof(conveyor))).ProcessDataAsync(data, priority, cancellation, attemptsCount, enqueueAll);
Example #4
0
        /// <summary> Batch process data with giver <paramref name="priority" /> </summary>
        /// <param name="conveyor"> Conveyor instance </param>
        /// <param name="data"> Data to process </param>
        /// <param name="cancellation"> Processing cancellation token </param>
        /// <param name="attemptsCount"> Retry on fail attempts count </param>
        /// <param name="priority"> Operation priority </param>
        /// <param name="enqueueAll"> Option to enqueue all data first </param>
        /// <typeparam name="TData"> Input data type </typeparam>
        /// <typeparam name="TResult"> Processing result type </typeparam>
        /// <returns> Processing result task enumeration </returns>
        /// <exception cref="ArgumentNullException"> Thrown if <paramref name="conveyor" /> or <paramref name="data" /> is NULL </exception>
        public static async IAsyncEnumerable <TResult> ProcessDataAsync <TData, TResult>(this IPriorityConveyor <TData, TResult> conveyor,
                                                                                         IEnumerable <TData> data, int priority = 0, [EnumeratorCancellation] CancellationToken cancellation = default, int attemptsCount = 1,
                                                                                         bool enqueueAll = false)
            where TData : notnull
        {
            _ = conveyor ?? throw new ArgumentNullException(nameof(conveyor));
            var results = (data ?? throw new ArgumentNullException(nameof(data))).Select(item
                                                                                         => conveyor.ProcessDataAsync(item, priority, cancellation, attemptsCount));

            if (enqueueAll)
            {
                results = results.ToList();
            }
            foreach (var result in results)
            {
                yield return(await result.ConfigureAwait(false));
            }
        }
Example #5
0
        /// <inheritdoc cref="ProcessDataAsync{TData,TResult}(IPriorityConveyor{TData,TResult},IEnumerable{TData},int,CancellationToken,int,bool)" />
        public static async IAsyncEnumerable <TResult> ProcessDataAsync <TData, TResult>(this IPriorityConveyor <TData, TResult> conveyor,
                                                                                         IAsyncEnumerable <TData> data, int priority = 0, [EnumeratorCancellation] CancellationToken cancellation = default, int attemptsCount = 1)
            where TData : notnull
        {
            _ = conveyor ?? throw new ArgumentNullException(nameof(conveyor));
            var channel = Channel.CreateUnbounded <Task <TResult> >(new UnboundedChannelOptions {
                SingleReader = true, SingleWriter = true
            });
            var reader = channel.Reader;
            var writer = channel.Writer;

            _ = Task.Run(async() =>
            {
                try
                {
                    await foreach (var item in data.WithCancellation(cancellation).ConfigureAwait(false))
                    {
                        await writer.WriteAsync(conveyor.ProcessDataAsync(item, priority, cancellation, attemptsCount), cancellation)
                        .ConfigureAwait(false);
                    }
                }
                catch (OperationCanceledException ex)
                {
                    await writer.WriteAsync(Task.FromCanceled <TResult>(ex.CancellationToken), CancellationToken.None).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    await writer.WriteAsync(Task.FromException <TResult>(ex), cancellation).ConfigureAwait(false);
                }
                finally
                {
                    writer.Complete();
                }
            },
                         cancellation);
            while (await reader.WaitToReadAsync(cancellation).ConfigureAwait(false))
            {
                yield return(await(await reader.ReadAsync(cancellation).ConfigureAwait(false)).ConfigureAwait(false));
            }
        }