Skip to content
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] Channel.CreateUnboundedPrioritized #62761

Closed
shaggygi opened this issue Dec 14, 2021 · 13 comments · Fixed by #100550
Closed

[API Proposal] Channel.CreateUnboundedPrioritized #62761

shaggygi opened this issue Dec 14, 2021 · 13 comments · Fixed by #100550
Assignees
Labels
api-approved API was approved in API review, it can be implemented area-System.Threading.Channels in-pr There is an active PR which will close this issue when it is merged
Milestone

Comments

@shaggygi
Copy link
Contributor

shaggygi commented Dec 14, 2021

EDITED by @stephentoub on 2/17/2024:

namespace System.Threading.Channels;

public class Channel
{
+   public static Channel<T> CreateUnboundedPrioritized<T>();
+   public static Channel<T> CreateUnboundedPrioritized<T>(UnboundedPrioritizedChannelOptions<T> options);
}
+public sealed partial class UnboundedPrioritizedChannelOptions<T> : ChannelOptions
+{
+   public System.Collections.Generic.IComparer<T>? Comparer { get; set; }
+}

Just wondering if anyone knows if a priority channel is available or a potential idea of adding to System.Threading.Channels. Something similar to Bounded/Unbounded channels with Reader/Writer along with priority capabilities. Meaning, you could write a large set of items to a channel in any order, but the reader would be sorted/read by a prioritized item.

I guess when it boils down to it I could use the PriorityQueue, but I do like the features provided by Channels.

Referencing
https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.priorityqueue-2?view=net-6.0
https://devblogs.microsoft.com/dotnet/an-introduction-to-system-threading-channels/

cc: @stephentoub

@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Threading.Channels untriaged New issue has not been triaged by the area owner labels Dec 14, 2021
@ghost
Copy link

ghost commented Dec 14, 2021

Tagging subscribers to this area: @dotnet/area-system-threading-channels
See info in area-owners.md if you want to be subscribed.

Issue Details

Just wondering if anyone knows if a priority channel is available or a potential idea of adding to System.Threading.Channels. Something similar to Bounded/Unbounded channels with Reader/Writer along with priority capabilities. Meaning, you could write a large set of items to a reader in any order, but the reader would be sorted/read by a prioritized item.

I guess when it boils down to it I could use the PriorityQueue, but I do like the features provided by Channels.

Referencing
https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.priorityqueue-2?view=net-6.0
https://devblogs.microsoft.com/dotnet/an-introduction-to-system-threading-channels/

cc: @stephentoub

Author: shaggygi
Assignees: -
Labels:

area-System.Threading.Channels, untriaged

Milestone: -

@gfoidl
Copy link
Member

gfoidl commented Dec 14, 2021

A potential simple workaround:
If you only need two priorities like "normal", and "high", then you could create and use two channels. One for "normal" priority, the other one for "high" priority. The reader checks the "high" channel first, if there's nothing to read from, then consult the "normal" channel.

Note: the base channel types are abstract so you could build your own based on PriorityQueue or whatever priorization solution you'd like to use.

@shaggygi
Copy link
Contributor Author

shaggygi commented Dec 14, 2021

Thanks @gfoidl

I was thinking similar to your scheme but have around 6 priority levels. I noticed the abstracts and thinking that might be the route I'll have to take.

@buyaa-n buyaa-n added api-suggestion Early API idea and discussion, it is NOT ready for implementation and removed untriaged New issue has not been triaged by the area owner labels Dec 22, 2021
@buyaa-n
Copy link
Contributor

buyaa-n commented Dec 22, 2021

Doesn't look like we have something like PriortyChannel, but it sounds useful, we could consider adding one using PriorityQueue as you mentioned, @shaggygi feel free to add/update the issue with an API proposal if you have one in mind.

@buyaa-n buyaa-n added this to the Future milestone Dec 22, 2021
@shaggygi
Copy link
Contributor Author

@buyaa-n Thanks for the response. I actually don't have anything specific in mind and probably a semi-combination of both their features would help. I'll add later if I something specific comes up. Thanks again.

@Lucian1000
Copy link

Hi, are there any updates on this?

@johnib
Copy link

johnib commented Feb 3, 2024

To add on the above, I would really like to have PriorityQueue-like Channel implementation.
Specifically, the above mentioned solutions won't work for me, because my scenario would prioritize the items based on some property, such as cache TTL, which will be highly randomized.

For example, this class PriorityQueue<TElement,TPriority> would have made perfect job if only it had the goods of Channel:

  1. Support multiple writers and readers
  2. Provide async API for Enqueue/Dequeue/Peek
  3. Provide sync API (TryEnqueue/TryDequeue/TryPeek)

@stephentoub

@stephentoub
Copy link
Member

This is approximately what I think this would look like:
main...stephentoub:runtime:channelpriority
with the API shape:

namespace System.Threading.Channels;

public class Channel
{
+   public static Channel<T> CreateUnboundedPrioritized<T>();
+   public static Channel<T> CreateUnboundedPrioritized<T>(UnboundedPrioritizedChannelOptions<T> options);
}
+public sealed partial class UnboundedPrioritizedChannelOptions<T> : ChannelOptions
+{
+   public System.Collections.Generic.IComparer<T>? Comparer { get; set; }
+}

Any feedback?

@stephentoub stephentoub modified the milestones: Future, 9.0.0 Feb 15, 2024
@stephentoub stephentoub self-assigned this Feb 15, 2024
@johnib
Copy link

johnib commented Feb 16, 2024

This is approximately what I think this would look like: main...stephentoub:runtime:channelpriority with the API shape:

namespace System.Threading.Channels;

public class Channel
{
+   public static Channel<T> CreateUnboundedPrioritized<T>();
+   public static Channel<T> CreateUnboundedPrioritized<T>(UnboundedPrioritizedChannelOptions<T> options);
}
+public sealed partial class UnboundedPrioritizedChannelOptions<T> : ChannelOptions
+{
+   public System.Collections.Generic.IComparer<T>? Comparer { get; set; }
+}

Any feedback?

@stephentoub really happy to see this

Given the implementation is done, I'd be happy to start using it (now..).
At the moment, my app is running on dotnet 6, I guess in couple of weeks we'll be on dotnet 8 -- is it possible to reference this class?

Many thanks !

@stephentoub
Copy link
Member

It is not in .NET 8. If it gets added, it would be at the earliest in .NET 9. But you can copy/paste the code from my branch into your project and tweak it to make it compile.

@stephentoub stephentoub added api-ready-for-review API is ready for review, it is NOT ready for implementation and removed api-suggestion Early API idea and discussion, it is NOT ready for implementation labels Feb 17, 2024
@stephentoub stephentoub changed the title Possible PriorityChannel [API Proposal] Channel.CreateUnboundedPrioritized Feb 17, 2024
@johnib
Copy link

johnib commented Feb 21, 2024

But you can copy/paste the code from my branch into your project and tweak it to make it compile.

@stephentoub, are you sure I can? It relies on internal classes/APIs which I no longer have access to, such as Deque, AsyncOperation's ctors, ChannelUtilities etc.

Actually I have a real of this implementation, if some hacks need to be made in order to make it work, please tell me.

Thanks Stephen

@stephentoub
Copy link
Member

It relies on internal classes/APIs

Those are all part of its implementation. You would copy those, too.

@bartonjs
Copy link
Member

bartonjs commented Apr 2, 2024

Video

Looks good as proposed.

namespace System.Threading.Channels;

public class Channel
{
+   public static Channel<T> CreateUnboundedPrioritized<T>();
+   public static Channel<T> CreateUnboundedPrioritized<T>(UnboundedPrioritizedChannelOptions<T> options);
}
+public sealed partial class UnboundedPrioritizedChannelOptions<T> : ChannelOptions
+{
+   public System.Collections.Generic.IComparer<T>? Comparer { get; set; }
+}

@bartonjs bartonjs added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review API is ready for review, it is NOT ready for implementation labels Apr 2, 2024
@dotnet-policy-service dotnet-policy-service bot added in-pr There is an active PR which will close this issue when it is merged labels Apr 2, 2024
@github-actions github-actions bot locked and limited conversation to collaborators May 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-approved API was approved in API review, it can be implemented area-System.Threading.Channels in-pr There is an active PR which will close this issue when it is merged
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants