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

Allow setting TaskScheduler.Current #29593

Open
ReubenBond opened this issue May 17, 2019 · 1 comment
Open

Allow setting TaskScheduler.Current #29593

ReubenBond opened this issue May 17, 2019 · 1 comment
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Threading.Tasks
Milestone

Comments

@ReubenBond
Copy link
Member

ReubenBond commented May 17, 2019

Orleans is one of the (seemingly few) frameworks which makes heavy use of custom TaskSchedulers. We use them to implement single-threaded execution for grains (~distributed objects). Each grain has its own ActivationTaskScheduler, so there may be 10^5 or 10^6 TaskScheduler instances in a process at any one time (on the high end).

ActivationTaskScheduler is a wrapper around WorkItemGroup, a collection of work items to execute serially. When a work item (eg, a Task) is scheduled, the WorkItemGroup itself is scheduled onto a dedicated thread pool for execution. This is very similar to IThreadPoolWorkItem, so there's room for us to support IThreadPoolWorkItem and also use the default thread pool in future. EDIT 2021: Those WorkItemGroup instances are now scheduled on the ThreadPool via IThreadPoolWorkItem.

Each grain sends/receives calls via RPC interfaces. We schedule those messages onto the grain's WorkItemGroup, but we have to wrap these work items in a Task so we can maintain single-threadedness in the case that the user's code doesn't complete synchronously or kicks off some background work (fire-and-forget style). For example, a JoinGame(id) call might contact some other grains and write to storage. This wrapping is not ideal.

If we could set & reset TaskScheduler.Current from within our WorkItemGroup then we could avoid this wrapping while still being able to have single-threadedness.

Is exposing a TaskScheduler.Current setter a possibility? Failing that, what other options should we consider?

I recognize potential pitfalls associated with broadly exposing a setter for TaskScheduler.Current. If that is a major concern then perhaps we could expose some scary-looking API like TaskScheduler.UnsafeSetCurrent(TaskScheduler) or some alternative means to control the ambient scheduler which doesn't require allocating a task.

@ReubenBond ReubenBond changed the title Add setter for TaskScheduler.Current Allow setting TaskScheduler.Current May 20, 2019
@msftgits msftgits transferred this issue from dotnet/corefx Feb 1, 2020
@msftgits msftgits added this to the 5.0 milestone Feb 1, 2020
@maryamariyan maryamariyan added the untriaged New issue has not been triaged by the area owner label Feb 23, 2020
@stephentoub stephentoub removed the untriaged New issue has not been triaged by the area owner label Feb 25, 2020
@stephentoub stephentoub modified the milestones: 5.0, Future Feb 25, 2020
@stephentoub
Copy link
Member

stephentoub commented Jan 21, 2023

In theory I'm not against the idea of a TaskScheduler.SetCurrent. In practice I'm not sure how it would work, at least not without an overhaul of this area of tasks. Today TaskScheduler.get_Current is effectively just:

Task t = Task.CurrentTask; // gets whatever innermost Task is currently executing on this thread
return t?.Scheduler ?? TaskScheduler.Default;

so there isn't really a notion of a stored current scheduler like you'd need to implement SetCurrent. Someone would need to prototype this in corelib to get a sense for the implications... I don't know if it'd end up being trivial or a rewrite or somewhere in between.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Threading.Tasks
Projects
None yet
Development

No branches or pull requests

4 participants