-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API Proposal: Inform client code when a BoundedChannel drops an item #36522
Comments
I really want this! |
The beauty of the channels is the simplicity of the contract. It allows them to be very efficient. For more complex and rich semantics there is another library; Dataflow. |
Yeah,I also think that,but... There's no such API for implement the logic. Also,the overhead of this feature is really low.We can know whether on dropped action has been assigned by very simple null check,and if it is not assigned,it never causes any virtual call.
Dataflow has lower performance than Channels. More specifically, Dataflow and Channels are made by the same author, and Channels seems to be Dataflow's upward compatibility, combining Dataflow's reflections and ValueTask as a replacement for Task. |
Although I generaly agree, I still believe this change is reasonable. Currently you are forced to ignore dropped items, so there is no consistent way to implement "cleanup logic" (for example, cleanup code is easy to implement for "dropWrite" but nearly impossible for "dropOldest"). What I am proposing basically changes the semantics from "drop and ignore" to "drop and optionally handle", while leaving the responsibility to the consumer of how exactly this is gonna be implemented. In other words the contract stays basically intact, it just enhances on the current semantics. Regarding efficiency, the overhead seems minimal on first inspection, but it leaves room to the consumer of the API to abuse the cb mechanism with some expensive operation. I don't know if this is considered a big problem. |
Tagging subscribers to this area: @tarekgh |
CC @stephentoub |
If you control creation of the channel you could make it non-dropping and then TryWrite on the sending side and dispose the object in the right context. |
It works only when DropWrite. |
I would love to use channels with DropOldest behavior, but currently I do not have way to cleanup/dispose object that was dropped. I have got 2 alternatives which would be great to consider:
Thank you for consideration. |
Functionally, this is a reasonable request, though I think it should be exposed differently. Rather than it being a separate CreateBounded method, the delegate should be added to BoundedChannelOptions: that's the reason BoundedChannelOptions exists, to be able to add new options in the future without a proliferation of CreateBounded overloads. Further, the default mode for CreateBounded is to not drop anything, so the only way the delegate would ever be invoked is if you were supplying a BoundedChannelOptions anyway that specified a different blocking mode. public sealed class BoundedChannelOptions : ChannelOptions
{
public Action<T> ItemDropped { get; set; }
...
} There's also a question of whether this should be an asynchronous callback, e.g. EDIT: Almost immediately after posting I realized my suggestion doesn't work, as BoundedChannelOptions is separate from the generic type parameter passed to
|
Hi Stephen, I am glad that you found time to look at it. |
namespace System.Threading.Channels
{
public static class Channel
{
// Existing:
// public static Channel<T> CreateBounded<T>(int capacity);
// public static Channel<T> CreateBounded<T>(BoundedChannelOptions options);
public static Channel<T> CreateBounded<T>(BoundedChannelOptions options, Action<T> itemDropped);
}
} |
Great to see proposal being approved. I will start working on this. |
Background and Motivation
The current Channels API clearly states in all drop modes that the message is "ignored and dropped". But consider that the message/item we try to send has some sort of cleanup code (maybe an IDisposable or a pooled object) that always need to be called eventually. Since the API forces the consumer to "ignore" the dropped messages, instances of those classes are currently unusable without external modifications.
Proposed API
Add a callback mechanism for dropped messages. As an example, since this only makes sense for Bounded channels, it could be provided as an optional argument during the construction of the channel. Something like the following:
namespace System.Threading.Channels { public static class Channel { public static Channel<T> CreateBounded<T>(int capacity); public static Channel<T> CreateBounded<T>(BoundedChannelOptions options); + public static Channel<T> CreateBounded<T>(BoundedChannelOptions options, Action<T> itemDropped); } }
The text was updated successfully, but these errors were encountered: