Skip to content

Record the operator a thread is scheduling - #831

Merged
frankmcsherry merged 3 commits into
TimelyDataflow:masterfrom
antiguru:current-operator
Oct 30, 2026
Merged

frankmcsherry merged 3 commits into
TimelyDataflow:masterfrom
antiguru:current-operator

Conversation

@antiguru

Copy link
Copy Markdown
Member

Adds timely::scheduling::current, a thread-local holding the global identifier of the operator whose schedule call is running, the same identifier ScheduleEvent reports. PerOperatorState::schedule and the worker's dataflow Wrapper::step set it for the duration of the call, and guards restore the enclosing operator, so the innermost operator is current.

The motivating use is attributing sampled heap allocations to dataflow operators from a global allocator. Logging can't serve this: events are buffered and arrive after the allocation, and the allocator has no handle to the worker. The thread-local is const-initialized and has no destructor, so reading it from an allocator neither allocates nor reenters.

current::enter is public so a host can charge work done on an operator's behalf outside its schedule call, for example trace maintenance or compaction, to that operator.

The cost is one thread-local swap and restore per schedule. In a Materialize prototype with about 50k schedules per second the hook did not show up in a CPU profile. With it, 92% of the sampled live heap was attributed to an operator.

🤖 Generated with Claude Code

Adds `scheduling::current`, a thread-local holding the global identifier of
the operator whose `schedule` call is running. Code without a handle to the
operator, such as a global allocator attributing allocations, reads it with
`current::operator()`. Hosts claim an operator for work done on its behalf
outside `schedule` with `current::enter`.

The thread-local is const-initialized and has no destructor, so reading it
from an allocator neither allocates nor reenters.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…lue's meaning

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@antiguru
antiguru marked this pull request as ready for review October 29, 2026 19:56
Comment thread timely/src/scheduling/current.rs Outdated
Comment on lines +13 to +16
//! The current operator is whoever is running, not whoever owns the data. An allocation made by
//! one operator and handed to another, such as a buffer pushed through `Pipeline`, is attributed
//! to the operator that made it. Work outside any operator, such as communication in
//! `Worker::step` and dataflow construction, has no current operator.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor, but: this may be relevant for the allocator example, but it is not specific to this code or feature.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, removed in 50a7f84. The docs keep only that work outside any operator has no current operator; the ownership caveat moved to the allocator consumer.

Posted by Claude Code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@frankmcsherry
frankmcsherry merged commit 492787b into TimelyDataflow:master Oct 30, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants