/// <summary> /// Initializes a new instance of the <see cref="CoCoL.ChannelNameAttribute"/> class. /// </summary> /// <param name="name">The name of the channel.</param> /// <param name="buffersize">The size of the buffer on the created channel</param> /// <param name="targetScope">The scope where the channel is created</param> /// <param name="maxPendingReaders">The maximum number of pending readers. A negative value indicates infinite</param> /// <param name="maxPendingWriters">The maximum number of pending writers. A negative value indicates infinite</param> /// <param name="pendingReadersOverflowStrategy">The strategy for dealing with overflow for read requests</param> /// <param name="pendingWritersOverflowStrategy">The strategy for dealing with overflow for write requests</param> public ChannelNameAttribute(string name, int buffersize = 0, ChannelNameScope targetScope = ChannelNameScope.Local, int maxPendingReaders = -1, int maxPendingWriters = -1, QueueOverflowStrategy pendingReadersOverflowStrategy = QueueOverflowStrategy.Reject, QueueOverflowStrategy pendingWritersOverflowStrategy = QueueOverflowStrategy.Reject) { Name = name; BufferSize = buffersize; TargetScope = targetScope; MaxPendingReaders = maxPendingReaders; MaxPendingWriters = maxPendingWriters; PendingReadersOverflowStrategy = pendingReadersOverflowStrategy; PendingWritersOverflowStrategy = pendingWritersOverflowStrategy; }
private void TestReaderOverflow(QueueOverflowStrategy strategy) { using (new IsolatedChannelScope()) { var readertasks = Enumerable.Range(0, 4).Select(count => AutomationExtensions.RunTask(new { Input = ChannelMarker.ForRead <int>("channel", maxPendingReaders: 3, pendingReadersOverflowStrategy: strategy) }, async x => { //Console.WriteLine("Started {0}", count); while (true) { await x.Input.ReadAsync(); } }) ).ToList(); using (ChannelManager.GetChannel <int>("channel").AsWriteOnly()) Task.Delay(500).WaitForTaskOrThrow(); Task.WhenAny(readertasks.Union(new [] { Task.Delay(1000) })).WaitForTaskOrThrow(); Task.Delay(500).WaitForTaskOrThrow(); int discard; switch (strategy) { case QueueOverflowStrategy.FIFO: discard = 0; break; case QueueOverflowStrategy.LIFO: discard = readertasks.Count - 2; break; case QueueOverflowStrategy.Reject: default: discard = readertasks.Count - 1; break; } Assert.IsTrue(readertasks[discard].IsFaulted); TestAssert.IsInstanceOf <ChannelOverflowException>(readertasks[discard].Exception.Flatten().InnerExceptions.First()); readertasks.RemoveAt(discard); Assert.IsTrue(readertasks.All(x => x.IsCompleted && !x.IsFaulted && !x.IsCanceled)); } }
/// <summary> /// Initializes a new instance of the <see cref="CoCoL.Channel<T>"/> class. /// </summary> /// <param name="attribute">The attribute describing the channel</param> internal Channel(ChannelNameAttribute attribute) { if (attribute == null) { throw new ArgumentNullException("attribute"); } if (attribute.BufferSize < 0) { throw new ArgumentOutOfRangeException("BufferSize", "The size parameter must be greater than or equal to zero"); } this.Name = attribute.Name; m_bufferSize = attribute.BufferSize; m_maxPendingReaders = attribute.MaxPendingReaders; m_maxPendingWriters = attribute.MaxPendingWriters; m_pendingReadersOverflowStrategy = attribute.PendingReadersOverflowStrategy; m_pendingWritersOverflowStrategy = attribute.PendingWritersOverflowStrategy; }
/// <summary> /// Creates a marker property for a write channel /// </summary> /// <returns>The marker instance.</returns> /// <param name="name">The name of the channel.</param> /// <param name="buffersize">The desired buffersize to use if the channel is created.</param> /// <param name="targetScope">The scope to create or locate the name in.</param> /// <typeparam name="T">The type of data passed on the channel.</typeparam> /// <param name="maxPendingReaders">The maximum number of pending readers. A negative value indicates infinite</param> /// <param name="maxPendingWriters">The maximum number of pending writers. A negative value indicates infinite</param> /// <param name="pendingReadersOverflowStrategy">The strategy for dealing with overflow for read requests</param> /// <param name="pendingWritersOverflowStrategy">The strategy for dealing with overflow for write requests</param> /// <param name="broadcast"><c>True</c> will create the channel as a broadcast channel, the default <c>false</c> will create a normal channel</param> /// <param name="initialBroadcastBarrier">The number of readers required on the channel before sending the first broadcast, can only be used with broadcast channels</param> /// <param name="broadcastMinimum">The minimum number of readers required on the channel, before a broadcast can be performed, can only be used with broadcast channels</param> public static IWriteChannel <T> ForWrite <T>(string name, int buffersize = 0, ChannelNameScope targetScope = ChannelNameScope.Local, int maxPendingReaders = -1, int maxPendingWriters = -1, QueueOverflowStrategy pendingReadersOverflowStrategy = QueueOverflowStrategy.Reject, QueueOverflowStrategy pendingWritersOverflowStrategy = QueueOverflowStrategy.Reject, bool broadcast = false, int initialBroadcastBarrier = -1, int broadcastMinimum = -1) { if (broadcast) { return(ForWrite <T>(new BroadcastChannelNameAttribute(name, buffersize, targetScope, maxPendingReaders, maxPendingWriters, pendingReadersOverflowStrategy, pendingWritersOverflowStrategy, initialBroadcastBarrier, broadcastMinimum))); } if (initialBroadcastBarrier >= 0 || broadcastMinimum >= 0) { throw new ArgumentException(string.Format("Cannot set \"{0}\" or \"{1}\" unless the channel is a broadcast channel", "initialBroadcastBarrier", "broadcastMinimum")); } return(ForWrite <T>(new ChannelNameAttribute(name, buffersize, targetScope, maxPendingReaders, maxPendingWriters, pendingReadersOverflowStrategy, pendingWritersOverflowStrategy))); }
/// <summary> /// Gets or creates a channel /// </summary> /// <returns>The channel with the given name.</returns> /// <param name="name">The name of the channel to create.</param> /// <param name="buffersize">The size of the channel buffer.</param> /// <param name="maxPendingReaders">The maximum number of pending readers. A negative value indicates infinite</param> /// <param name="maxPendingWriters">The maximum number of pending writers. A negative value indicates infinite</param> /// <param name="pendingReadersOverflowStrategy">The strategy for dealing with overflow for read requests</param> /// <param name="pendingWritersOverflowStrategy">The strategy for dealing with overflow for write requests</param> /// <param name="broadcast"><c>True</c> will create the channel as a broadcast channel, the default <c>false</c> will create a normal channel</param> /// <param name="initialBroadcastBarrier">The number of readers required on the channel before sending the first broadcast, can only be used with broadcast channels</param> /// <param name="broadcastMinimum">The minimum number of readers required on the channel, before a broadcast can be performed, can only be used with broadcast channels</param> /// <typeparam name="T">The type of data in the channel.</typeparam> public IChannel <T> GetOrCreate <T>(string name, int buffersize = 0, int maxPendingReaders = -1, int maxPendingWriters = -1, QueueOverflowStrategy pendingReadersOverflowStrategy = QueueOverflowStrategy.Reject, QueueOverflowStrategy pendingWritersOverflowStrategy = QueueOverflowStrategy.Reject, bool broadcast = false, int initialBroadcastBarrier = -1, int broadcastMinimum = -1) { if (!broadcast && (initialBroadcastBarrier >= 0 || broadcastMinimum >= 0)) { throw new ArgumentException(string.Format("Cannot set \"{0}\" or \"{1}\" unless the channel is a broadcast channel", "initialBroadcastBarrier", "broadcastMinimum")); } var attr = broadcast ? new BroadcastChannelNameAttribute(name, buffersize, ChannelNameScope.Local, maxPendingReaders, maxPendingWriters, pendingReadersOverflowStrategy, pendingWritersOverflowStrategy, initialBroadcastBarrier, broadcastMinimum) : new ChannelNameAttribute(name, buffersize, ChannelNameScope.Local, maxPendingReaders, maxPendingWriters, pendingReadersOverflowStrategy, pendingWritersOverflowStrategy); return(GetOrCreate <T>(attr)); }
/// <summary> /// Initializes a new instance of the <see cref="CoCoL.BroadcastChannelNameAttribute"/> class. /// </summary> /// <param name="name">The name of the channel.</param> /// <param name="buffersize">The size of the buffer on the created channel</param> /// <param name="targetScope">The scope where the channel is created</param> /// <param name="maxPendingReaders">The maximum number of pending readers. A negative value indicates infinite</param> /// <param name="maxPendingWriters">The maximum number of pending writers. A negative value indicates infinite</param> /// <param name="pendingReadersOverflowStrategy">The strategy for dealing with overflow for read requests</param> /// <param name="pendingWritersOverflowStrategy">The strategy for dealing with overflow for write requests</param> /// <param name="initialBarrierSize">The number of readers required on the channel before sending the first broadcast</param> /// <param name="minimumReaders">The minimum number of readers required on the channel, before a broadcast can be performed</param> public BroadcastChannelNameAttribute(string name, int buffersize = 0, ChannelNameScope targetScope = ChannelNameScope.Local, int maxPendingReaders = -1, int maxPendingWriters = -1, QueueOverflowStrategy pendingReadersOverflowStrategy = QueueOverflowStrategy.Reject, QueueOverflowStrategy pendingWritersOverflowStrategy = QueueOverflowStrategy.Reject, int initialBarrierSize = -1, int minimumReaders = -1) : base(name, buffersize, targetScope, maxPendingReaders, maxPendingWriters, pendingReadersOverflowStrategy, pendingWritersOverflowStrategy) { InitialBarrierSize = initialBarrierSize; MinimumReaders = minimumReaders; }
/// <summary> /// Creates a channel, possibly unnamed. /// If a channel name is provided, the channel is created in the supplied scope. /// If a channel with the given name is already found in the supplied scope, the named channel is returned. /// </summary> /// <returns>The channel.</returns> /// <param name="name">The name of the channel, or null.</param> /// <param name="buffersize">The number of buffers in the channel.</param> /// <param name="scope">The scope to create a named channel in, defaults to null which means the current scope</param> /// <param name="maxPendingReaders">The maximum number of pending readers. A negative value indicates infinite</param> /// <param name="maxPendingWriters">The maximum number of pending writers. A negative value indicates infinite</param> /// <param name="pendingReadersOverflowStrategy">The strategy for dealing with overflow for read requests</param> /// <param name="pendingWritersOverflowStrategy">The strategy for dealing with overflow for write requests</param> /// <param name="broadcast"><c>True</c> will create the channel as a broadcast channel, the default <c>false</c> will create a normal channel</param> /// <param name="initialBroadcastBarrier">The number of readers required on the channel before sending the first broadcast, can only be used with broadcast channels</param> /// <param name="broadcastMinimum">The minimum number of readers required on the channel, before a broadcast can be performed, can only be used with broadcast channels</param> /// <typeparam name="T">The channel type.</typeparam> public static IChannel <T> Create <T>(string name = null, int buffersize = 0, ChannelScope scope = null, int maxPendingReaders = -1, int maxPendingWriters = -1, QueueOverflowStrategy pendingReadersOverflowStrategy = QueueOverflowStrategy.Reject, QueueOverflowStrategy pendingWritersOverflowStrategy = QueueOverflowStrategy.Reject, bool broadcast = false, int initialBroadcastBarrier = -1, int broadcastMinimum = -1) { return(ChannelManager.CreateChannel <T>(name, buffersize, scope, maxPendingReaders, maxPendingWriters, pendingReadersOverflowStrategy, pendingWritersOverflowStrategy, broadcast, initialBroadcastBarrier, broadcastMinimum)); }
/// <summary> /// Initializes a new instance of the <see cref="T:CoCoL.ChannelMarkerWrapper<T>"/> class, /// </summary> /// <param name="name">The name of the channel.</param> /// <param name="buffersize">The size of the buffer on the created channel</param> /// <param name="targetScope">The scope where the channel is created</param> /// <param name="maxPendingReaders">The maximum number of pending readers. A negative value indicates infinite</param> /// <param name="maxPendingWriters">The maximum number of pending writers. A negative value indicates infinite</param> /// <param name="pendingReadersOverflowStrategy">The strategy for dealing with overflow for read requests</param> /// <param name="pendingWritersOverflowStrategy">The strategy for dealing with overflow for write requests</param> public ChannelMarkerWrapper(string name, int buffersize = 0, ChannelNameScope targetScope = ChannelNameScope.Local, int maxPendingReaders = -1, int maxPendingWriters = -1, QueueOverflowStrategy pendingReadersOverflowStrategy = QueueOverflowStrategy.Reject, QueueOverflowStrategy pendingWritersOverflowStrategy = QueueOverflowStrategy.Reject) : this(new ChannelNameAttribute(name, buffersize, targetScope, maxPendingReaders, maxPendingWriters, pendingReadersOverflowStrategy, pendingWritersOverflowStrategy)) { }