Exemple #1
0
 /// <summary>
 /// Reads from any of the specified channels
 /// </summary>
 /// <param name="channels">The list of channels to call.</param>
 /// <param name="priority">The priority used to select channels, if multiple channels have a value that can be read.</param>
 /// <typeparam name="T">The channel data type.</typeparam>
 public static Task <MultisetResult <T> > ReadFromAnyAsync <T>(MultiChannelPriority priority, params IReadChannel <T>[] channels)
 {
     return(ReadFromAnyAsync(null, channels.AsEnumerable(), Timeout.Infinite, priority));
 }
Exemple #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CoCoL.MultiChannelSetWrite&lt;T&gt;"/> class.
 /// </summary>
 /// <param name="priority">The priority to use when selecting a channel.</param>
 /// <param name="channels">The channels to consider.</param>
 public MultiChannelSetWrite(MultiChannelPriority priority, params IWriteChannel <T>[] channels)
 {
     m_channels       = channels;
     m_sortedChannels = priority == MultiChannelPriority.Fair ? new SortedChannelList <IWriteChannel <T> >(channels) : null;
     m_priority       = priority;
 }
Exemple #3
0
 /// <summary>
 /// Creates a multichannelset from a list of channels
 /// </summary>
 /// <returns>The multichannel set.</returns>
 /// <param name="channels">The channels to make the set from.</param>
 /// <param name="priority">The channel priority.</param>
 /// <typeparam name="T">The type of the channel.</typeparam>
 public static MultiChannelSetWrite <T> CreateSet <T>(this IEnumerable <IWriteChannel <T> > channels, MultiChannelPriority priority = MultiChannelPriority.Any)
 {
     return(new MultiChannelSetWrite <T>(channels, priority));
 }
Exemple #4
0
 /// <summary>
 /// Reads from any of the specified channels
 /// </summary>
 /// <param name="requests">The list of requests</param>
 /// <param name="priority">The priority used to select channels, if multiple channels have a value that can be read.</param>
 /// <typeparam name="T">The channel data type.</typeparam>
 public static Task <MultisetRequest <T> > ReadOrWriteAnyAsync <T>(MultiChannelPriority priority, params MultisetRequest <T>[] requests)
 {
     return(ReadOrWriteAnyAsync(null, requests.AsEnumerable(), Timeout.Infinite, priority));
 }
Exemple #5
0
 /// <summary>
 /// Reads from any of the specified channels
 /// </summary>
 /// <param name="callback">The method to call when the read completes, or null.</param>
 /// <param name="requests">The list of requests</param>
 /// <param name="timeout">The maximum time to wait for a value to read.</param>
 /// <param name="priority">The priority used to select a channel, if multiple channels have a value that can be read.</param>
 /// <typeparam name="T">The channel data type.</typeparam>
 private static Task <MultisetRequest <T> > ReadOrWriteAnyAsync <T>(this IEnumerable <MultisetRequest <T> > requests, Action <object> callback, TimeSpan timeout, MultiChannelPriority priority)
 {
     return(ReadOrWriteAnyAsync(callback, requests, timeout, priority));
 }
Exemple #6
0
 /// <summary>
 /// Writes to any of the specified channels
 /// </summary>
 /// <param name="value">The value to write to the channel.</param>
 /// <param name="channels">The list of channels to attempt to write.</param>
 /// <param name="priority">The priority used to select a channel, if multiple channels have a value that can be written.</param>
 /// <typeparam name="T">The channel data type.</typeparam>
 public static Task <IWriteChannel <T> > WriteToAnyAsync <T>(T value, MultiChannelPriority priority, params IWriteChannel <T>[] channels)
 {
     return(WriteToAnyAsync(null, value, channels, Timeout.Infinite, priority));
 }
Exemple #7
0
 /// <summary>
 /// Writes to any of the specified channels
 /// </summary>
 /// <param name="value">The value to write to the channel.</param>
 /// <param name="channels">The list of channels to attempt to write.</param>
 /// <param name="timeout">The maximum time to wait for a channel to become ready for writing.</param>
 /// <param name="priority">The priority used to select a channel, if multiple channels have a value that can be written.</param>
 /// <typeparam name="T">The channel data type.</typeparam>
 public static Task <IWriteChannel <T> > WriteToAnyAsync <T>(this IEnumerable <IWriteChannel <T> > channels, T value, TimeSpan timeout, MultiChannelPriority priority)
 {
     return(WriteToAnyAsync(null, value, channels, timeout, priority));
 }
Exemple #8
0
 /// <summary>
 /// Writes to any of the specified channels
 /// </summary>
 /// <param name="requests">The list of channels to attempt to write.</param>
 /// <param name="priority">The priority used to select a channel, if multiple channels have a value that can be written.</param>
 public static Task <IUntypedChannel> WriteToAnyAsync(this IEnumerable <IMultisetRequestUntyped> requests, MultiChannelPriority priority)
 {
     return(WriteToAnyAsync(requests, Timeout.Infinite, priority));
 }
Exemple #9
0
 /// <summary>
 /// Writes to any of the specified channels
 /// </summary>
 /// <param name="requests">The list of channels to attempt to write.</param>
 /// <param name="timeout">The maximum time to wait for a channel to become ready for writing.</param>
 /// <param name="priority">The priority used to select a channel, if multiple channels have a value that can be written.</param>
 public static async Task <IUntypedChannel> WriteToAnyAsync(this IEnumerable <IMultisetRequestUntyped> requests, TimeSpan timeout, MultiChannelPriority priority)
 {
     return((await ReadOrWriteAnyAsync(null, requests, timeout, priority)).Channel);
 }
Exemple #10
0
 /// <summary>
 /// Reads from any of the specified channels
 /// </summary>
 /// <param name="callback">The method to call when the read completes, or null.</param>
 /// <param name="requests">The list of requests.</param>
 /// <param name="timeout">The maximum time to wait for a value to read.</param>
 /// <param name="priority">The priority used to select a channel, if multiple channels have a value that can be read.</param>
 public static async Task <IMultisetRequestUntyped> ReadFromAnyAsync(Action <object> callback, IEnumerable <IMultisetRequestUntyped> requests, TimeSpan timeout, MultiChannelPriority priority)
 {
     return(await ReadOrWriteAnyAsync(callback, requests, timeout, priority));
 }
Exemple #11
0
 /// <summary>
 /// Writes to any of the specified channels
 /// </summary>
 /// <param name="requests">The list of channels to attempt to write.</param>
 /// <param name="priority">The priority used to select a channel, if multiple channels have a value that can be written.</param>
 public static Task <IUntypedChannel> WriteToAnyAsync(MultiChannelPriority priority, params IMultisetRequestUntyped[] requests)
 {
     return(WriteToAnyAsync(requests.AsEnumerable(), Timeout.Infinite, priority));
 }
Exemple #12
0
 /// <summary>
 /// Reads from any of the specified channels
 /// </summary>
 /// <param name="requests">The list of requests.</param>
 /// <param name="timeout">The maximum time to wait for a value to read.</param>
 /// <param name="priority">The priority used to select a channel, if multiple channels have a value that can be read.</param>
 public static Task <IMultisetRequestUntyped> ReadFromAnyAsync(this IEnumerable <IMultisetRequestUntyped> requests, TimeSpan timeout, MultiChannelPriority priority)
 {
     return(ReadFromAnyAsync(null, requests, timeout, priority));
 }
Exemple #13
0
 /// <summary>
 /// Reads from any of the specified channels
 /// </summary>
 /// <param name="callback">The method to call after the read completes.</param>
 /// <param name="channels">The list of channels to attempt to read from.</param>
 /// <param name="timeout">The maximum time to wait for a value to read.</param>
 /// <param name="priority">The priority used to select a channel, if multiple channels have a value that can be read.</param>
 public static Task <IMultisetRequestUntyped> ReadFromAnyAsync(Action <object> callback, IEnumerable <IUntypedChannel> channels, TimeSpan timeout, MultiChannelPriority priority)
 {
     return(ReadFromAnyAsync(callback, channels.Select(x => x.RequestRead()), timeout, priority));
 }
Exemple #14
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CoCoL.MultiChannelSetWrite&lt;T&gt;"/> class.
 /// </summary>
 /// <param name="priority">The priority to use when selecting a channel.</param>
 /// <param name="channels">The channels to consider.</param>
 public MultiChannelSetWrite(IEnumerable <IWriteChannel <T> > channels, MultiChannelPriority priority = MultiChannelPriority.Any)
     : this(priority, channels.ToArray())
 {
 }
Exemple #15
0
 /// <summary>
 /// Reads from any of the specified channels
 /// </summary>
 /// <param name="channels">The list of channels to attempt to read from.</param>
 /// <param name="timeout">The maximum time to wait for a value to read.</param>
 /// <param name="priority">The priority used to select a channel, if multiple channels have a value that can be read.</param>
 /// <typeparam name="T">The channel data type.</typeparam>
 public static Task <MultisetResult <T> > ReadFromAnyAsync <T>(this IEnumerable <IReadChannel <T> > channels, TimeSpan timeout, MultiChannelPriority priority)
 {
     return(ReadFromAnyAsync(null, channels, timeout, priority));
 }
Exemple #16
0
 /// <summary>
 /// Reads or writes any of the specified requests
 /// </summary>
 /// <param name="requests">The list of channels to call.</param>
 /// <param name="timeout">The maximum time to wait for a value to read.</param>
 /// <param name="priority">The priority used to select channels, if multiple channels have a value that can be read.</param>
 public static Task <IMultisetRequestUntyped> ReadOrWriteAnyAsync(TimeSpan timeout, MultiChannelPriority priority, params IMultisetRequestUntyped[] requests)
 {
     return(ReadOrWriteAnyAsync(null, requests.AsEnumerable(), timeout, priority));
 }
Exemple #17
0
        /// <summary>
        /// Reads from any of the specified channels
        /// </summary>
        /// <param name="callback">The method to call when the read completes, or null.</param>
        /// <param name="channels">The list of channels to attempt to read from.</param>
        /// <param name="timeout">The maximum time to wait for a value to read.</param>
        /// <param name="priority">The priority used to select a channel, if multiple channels have a value that can be read.</param>
        /// <typeparam name="T">The channel data type.</typeparam>
        public static async Task <MultisetResult <T> > ReadFromAnyAsync <T>(Action <object> callback, IEnumerable <IReadChannel <T> > channels, TimeSpan timeout, MultiChannelPriority priority)
        {
            var res = await ReadOrWriteAnyAsync <T>(callback, channels.Select(x => x.RequestRead()), timeout, priority).ConfigureAwait(false);

            return(new MultisetResult <T>(res.Value, res.ReadChannel));
        }
Exemple #18
0
 /// <summary>
 /// Reads or writes any of the specified requests
 /// </summary>
 /// <param name="requests">The list of channels to call.</param>
 /// <param name="priority">The priority used to select channels, if multiple channels have a value that can be read.</param>
 public static Task <IMultisetRequestUntyped> ReadOrWriteAnyAsync <T>(this IEnumerable <IMultisetRequestUntyped> requests, MultiChannelPriority priority)
 {
     return(ReadOrWriteAnyAsync(null, requests, Timeout.Infinite, priority));
 }
Exemple #19
0
 /// <summary>
 /// Writes to any of the specified channels
 /// </summary>
 /// <param name="value">The value to write to the channel.</param>
 /// <param name="channels">The list of channels to attempt to write.</param>
 /// <param name="priority">The priority used to select a channel, if multiple channels have a value that can be written.</param>
 /// <typeparam name="T">The channel data type.</typeparam>
 public static Task <IWriteChannel <T> > WriteToAnyAsync <T>(T value, IEnumerable <IWriteChannel <T> > channels, MultiChannelPriority priority)
 {
     return(WriteToAnyAsync(null, value, channels, Timeout.Infinite, priority));
 }
Exemple #20
0
        /// <summary>
        /// Reads or writes any of the specified requests
        /// </summary>
        /// <param name="callback">The method to call when the read completes, or null.</param>
        /// <param name="requests">The list of requests.</param>
        /// <param name="timeout">The maximum time to wait for a value to read.</param>
        /// <param name="priority">The priority used to select a channel, if multiple channels have a value that can be read.</param>
        public static Task <IMultisetRequestUntyped> ReadOrWriteAnyAsync(Action <object> callback, IEnumerable <IMultisetRequestUntyped> requests, TimeSpan timeout, MultiChannelPriority priority)
        {
            var tcs = new TaskCompletionSource <IMultisetRequestUntyped>();

            // We only accept the first offer
            var offer = new SingleOffer <IMultisetRequestUntyped>(tcs, timeout == Timeout.Infinite ? Timeout.InfiniteDateTime : DateTime.Now + timeout);

            offer.SetCommitCallback(callback);

            switch (priority)
            {
            case MultiChannelPriority.Fair:
                throw new Exception(string.Format("Construct a {0} or {1} object to use fair multichannel operations", typeof(MultiChannelSetRead <>).Name, typeof(MultiChannelSetWrite <>).Name));

            case MultiChannelPriority.Random:
                requests = MultiChannelAccess.Shuffle(requests);
                break;

            default:
                // Use the order the input has
                break;
            }

            // Keep a map of awaitable items
            var tasks = new Dictionary <Task, IMultisetRequestUntyped>();

            // Then we register the intent to read from a channel in order
            foreach (var c in requests)
            {
                // Timeout is handled by offer instance
                if (c.IsRead)
                {
                    tasks[c.Channel.ReadAsync(Timeout.Infinite, offer)] = c;
                }
                else
                {
                    tasks[c.Channel.WriteAsync(c.Value, Timeout.Infinite, offer)] = c;
                }

                // Fast exit to avoid littering the channels if we are done
                if (offer.IsTaken)
                {
                    break;
                }
            }

            offer.ProbePhaseComplete();

            if (tasks.Count == 0)
            {
                tcs.TrySetException(new InvalidOperationException("List of channels was empty"));
                return(tcs.Task);
            }

            tasks.Keys.WhenAnyNonCancelled().ContinueWith(item => Task.Run(() =>
            {
                if (item.IsCanceled)
                {
                    tcs.TrySetCanceled();
                    return;
                }
                else if (item.IsFaulted)
                {
                    tcs.TrySetException(item.Exception);
                    return;
                }

                if (offer.AtomicIsFirst())
                {
                    var n = item.Result;

                    // Figure out which item was found
                    if (n.IsCanceled)
                    {
                        tcs.SetCanceled();
                    }
                    else if (n.IsFaulted)
                    {
                        // Unwrap aggregate exceptions
                        if (n.Exception is AggregateException && (n.Exception as AggregateException).Flatten().InnerExceptions.Count == 1)
                        {
                            tcs.SetException(n.Exception.InnerException);
                        }
                        else
                        {
                            tcs.SetException(n.Exception);
                        }
                    }
                    else
                    {
                        var orig = tasks[n];
                        if (orig.IsRead)
                        {
                            orig.Value = ((Task <object>)n).Result;
                            tcs.SetResult(orig);
                        }
                        else
                        {
                            orig.Value = null;
                            tcs.SetResult(orig);
                        }
                    }
                }
            }));

            return(tcs.Task);
        }
Exemple #21
0
 /// <summary>
 /// Writes to any of the specified channels
 /// </summary>
 /// <param name="callback">The method to call when the write completes, or null.</param>
 /// <param name="value">The value to write to the channel.</param>
 /// <param name="channels">The list of channels to attempt to write.</param>
 /// <param name="timeout">The maximum time to wait for a channel to become ready for writing.</param>
 /// <param name="priority">The priority used to select a channel, if multiple channels have a value that can be written.</param>
 /// <typeparam name="T">The channel data type.</typeparam>
 public static async Task <IWriteChannel <T> > WriteToAnyAsync <T>(Action <object> callback, T value, IEnumerable <IWriteChannel <T> > channels, TimeSpan timeout, MultiChannelPriority priority)
 {
     return((await ReadOrWriteAnyAsync <T>(callback, channels.Select(x => x.RequestWrite(value)), timeout, priority).ConfigureAwait(false)).WriteChannel);
 }
Exemple #22
0
 /// <summary>
 /// Reads from any of the specified channels
 /// </summary>
 /// <param name="channels">The list of channels to call.</param>
 /// <param name="priority">The priority used to select channels, if multiple channels have a value that can be read.</param>
 public static Task <IMultisetRequestUntyped> ReadFromAnyAsync(MultiChannelPriority priority, params IUntypedChannel[] channels)
 {
     return(ReadFromAnyAsync(null, channels.AsEnumerable(), Timeout.Infinite, priority));
 }
Exemple #23
0
 /// <summary>
 /// Reads from any of the specified channels
 /// </summary>
 /// <param name="requests">The list of requests</param>
 /// <param name="timeout">The maximum time to wait for a value to read.</param>
 /// <param name="priority">The priority used to select a channel, if multiple channels have a value that can be read.</param>
 /// <typeparam name="T">The channel data type.</typeparam>
 public static Task <MultisetRequest <T> > ReadOrWriteAnyAsync <T>(this IEnumerable <MultisetRequest <T> > requests, TimeSpan timeout, MultiChannelPriority priority)
 {
     return(ReadOrWriteAnyAsync(null, requests, timeout, priority));
 }
Exemple #24
0
 /// <summary>
 /// Reads from any of the specified channels
 /// </summary>
 /// <param name="channels">The list of channels to call.</param>
 /// <param name="priority">The priority used to select channels, if multiple channels have a value that can be read.</param>
 public static Task <IMultisetRequestUntyped> ReadFromAnyAsync(this IEnumerable <IUntypedChannel> channels, MultiChannelPriority priority)
 {
     return(ReadFromAnyAsync(null, channels, Timeout.Infinite, priority));
 }
Exemple #25
0
        /// <summary>
        /// Reads from any of the specified channels
        /// </summary>
        /// <param name="callback">The method to call when the read completes, or null.</param>
        /// <param name="requests">The list of requests</param>
        /// <param name="timeout">The maximum time to wait for a value to read.</param>
        /// <param name="priority">The priority used to select a channel, if multiple channels have a value that can be read.</param>
        /// <param name="cancelToken">The cancellation token</param>
        /// <typeparam name="T">The channel data type.</typeparam>
        private static Task <MultisetRequest <T> > ReadOrWriteAnyAsync <T>(Action <object> callback, IEnumerable <MultisetRequest <T> > requests, TimeSpan timeout, MultiChannelPriority priority, CancellationToken cancelToken = default(CancellationToken))
        {
            // This method could also use the untyped version,
            // but using the type version is faster as there are no reflection
            // or boxing/typecasting required

            var tcs = new TaskCompletionSource <MultisetRequest <T> >();

            // We only accept the first offer
            var offer = new SingleOffer <MultisetRequest <T> >(tcs, timeout == Timeout.Infinite ? Timeout.InfiniteDateTime : DateTime.Now + timeout, cancelToken);

            offer.SetCommitCallback(callback);

            switch (priority)
            {
            case MultiChannelPriority.Fair:
                throw new InvalidOperationException(string.Format("Construct a {0} or {1} object to use fair multichannel operations", typeof(MultiChannelSetRead <>).Name, typeof(MultiChannelSetWrite <>).Name));

            case MultiChannelPriority.Random:
                requests = Shuffle(requests);
                break;

            default:
                // Use the order the input has
                break;
            }

            // Keep a map of awaitable items
            // and register the intent to read from a channel in order
            var tasks = new Dictionary <Task, MultisetRequest <T> >();

            foreach (var c in requests)
            {
                // Timeout is handled by offer instance
                if (c.IsRead)
                {
                    tasks[c.ReadChannel.ReadAsync(offer)] = c;
                }
                else
                {
                    tasks[c.WriteChannel.WriteAsync(c.Value, offer)] = c;
                }

                // Fast exit to avoid littering the channels if we are done
                if (offer.IsTaken)
                {
                    break;
                }
            }

            offer.ProbePhaseComplete();

            if (tasks.Count == 0)
            {
                tcs.TrySetException(new InvalidOperationException("List of channels was empty"));
                return(tcs.Task);
            }

            tasks.Keys.WhenAnyNonCancelled().ContinueWith(item => Task.Run(() =>
            {
                if (item.IsCanceled)
                {
                    tcs.TrySetCanceled();
                    return;
                }
                else if (item.IsFaulted)
                {
                    tcs.TrySetException(item.Exception);
                    return;
                }

                var n = item.Result;

                if (offer.AtomicIsFirst())
                {
                    // Figure out which item was found
                    if (n.IsCanceled)
                    {
                        tcs.SetCanceled();
                    }
                    else if (n.IsFaulted)
                    {
                        // Unwrap aggregate exceptions
                        if (n.Exception is AggregateException && (n.Exception as AggregateException).Flatten().InnerExceptions.Count == 1)
                        {
                            tcs.SetException(n.Exception.InnerException);
                        }
                        else
                        {
                            tcs.SetException(n.Exception);
                        }
                    }
                    else
                    {
                        var orig = tasks[n];
                        if (orig.IsRead)
                        {
                            tcs.SetResult(new MultisetRequest <T>(((Task <T>)n).Result, orig.ReadChannel, null, true));
                        }
                        else
                        {
                            tcs.SetResult(new MultisetRequest <T>(default(T), null, orig.WriteChannel, false));
                        }
                    }
                }
            }));

            return(tcs.Task);
        }
Exemple #26
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CoCoL.MultiChannelSetRead&lt;T&gt;"/> class.
 /// </summary>
 /// <param name="priority">The priority to use when selecting a channel.</param>
 /// <param name="channels">The channels to consider.</param>
 public MultiChannelSetRead(IEnumerable <IReadChannel <T> > channels, MultiChannelPriority priority)
     : this(priority, channels.ToArray())
 {
 }