-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
rt: add optional per-task user data exposed to hooks #7688
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
Open
LloydW93
wants to merge
8
commits into
tokio-rs:master
Choose a base branch
from
LloydW93:lloyd/hookening-rehookened
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+403
−33
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
In tokio-rs#7197 and tokio-rs#7306, improved capabilities of task hooks were discussed and an initial implementation provided. However, that involved quite wide-reaching changes, modifying every spawn site and introducing a global map to provide the full inheritance capabilities originally proposed. This is the first part of a more basic version where we only use the existing hooks and provide the capabilities for consumers to be able to implement more complex relationships if needed, just adding an optional user data ref to the task header. The additional data is 2*usize, and is not enough to result in the struct requiring more than one cache line. A user is now able to use their own global map to build inheritance capabilities if needed, and this would be made simpler by also exposing the current task user data to the on_task_spawn hook, which a followup will look to do.
…ast helpers It's nicer syntactically to be able to directly pass whatever type and have tokio deal with how the user data is stored, but it makes on_task_spawn have a horrible wrapper function, so just take that out to keep things simpler and nicer for now.
Darksonn
reviewed
Oct 20, 2025
ADD-SP
reviewed
Oct 20, 2025
Member
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to make an agreement on public interface before talking about the implementation details.
I prefer to discuss the public interface and high-level data structure design in the RFC first.
Contributor
|
Yes, it's useful with an overview of the public API being added. |
scotchmist
reviewed
Oct 22, 2025
martin-g
reviewed
Oct 23, 2025
Addressing PR comments: - UserData is now `Send + Sync` when using `rt-multi-thread` - The runtime::Builder docs now signpost to the `task::Builder` API for setting user data on a per-task basis rather than through the global task spawn hook - Updated `task::Builder::data` to not consume self to align with `task::Builder::name` behaviour
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
A-tokio
Area: The main tokio crate
M-runtime
Module: tokio/runtime
R-loom-current-thread
Run loom current-thread tests on this PR
R-loom-multi-thread
Run loom multi-thread tests on this PR
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In #7197 and #7306, improved capabilities of task hooks were discussed and an initial implementation provided. However, that involved quite wide-reaching changes, modifying every spawn site and introducing a global map to provide the full inheritance capabilities originally proposed.
This is the first part of a more basic version where we only use the existing hooks and provide the capabilities for consumers to be able to implement more complex relationships if needed, just adding an optional user data ref to the task header.
The additional data is 2*usize, and is not enough to result in the struct requiring more than one cache line.
A user is now able to use their own global map to build inheritance capabilities if needed, and this would be made simpler by also exposing the current task user data to the on_task_spawn hook, which a followup will look to do.
Motivation
See #7306. The intent is to allow persistence of context for across evaluations of task hooks, which is potentially also accessible by the task itself.
For example you may want to just know how many poll()s a task took, metrics of each poll duration (or between each poll duration), or to set some flag to track what a task was about to do (e.g. read some bytes from a socket) to identify what a task has become blocked on.
Solution
By adding a fat pointer for task metadata, consumers are able to attack a reference to data of an arbitrary type for a task, which we then expose in hooks. This metadata can be configured at task spawn time, also allowing consumers to maintain some shared reference between the hooks and the task's future itself to maintain knowledge of what is going on.