Skip to content

Introduce distributed planning lifecycle event handlers for replacing TaskEstimator - #564

Merged
gabotechs merged 2 commits into
mainfrom
gabrielmusat/events
Jul 28, 2026
Merged

Introduce distributed planning lifecycle event handlers for replacing TaskEstimator#564
gabotechs merged 2 commits into
mainfrom
gabrielmusat/events

Conversation

@gabotechs

@gabotechs gabotechs commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Stack

  1. Introduce distributed planning lifecycle event handlers for replacing TaskEstimator #564 <- you are here
  2. Define routing in terms of events #567
  3. Define worker plan rewrites in terms of events #568
  4. Make desired task-count handlers async #569
  5. Add dynamic stage built events #570

Introduces an event-driven API for reacting to distributed planning lifecycle events, and replaces the previous TaskEstimator methods with it.

Motivation

TaskEstimator was a convenient initial extension point, but its methods run at different points in planning, observe different context, and have different result semantics. Task-count estimation is evaluated while traversing the plan; leaf specialization only runs after a stage's final task count is known; routing runs later on the coordinator. Keeping these operations in one trait couples otherwise independent APIs.

This event-specific pattern is easier to extend without breaking API consumers: a capability can evolve within the event that owns it instead of requiring every TaskEstimator implementation to adopt a broader trait. It is also easier to document and expose to users. Dedicated event types give us focused API pages and code documentation, and provide a quick index of the project’s extension points by the planner lifecycle events where users can hook their code.

What changed

Previously, one trait covered task-count estimation, leaf specialization, and task routing:

trait TaskEstimator {
    fn task_estimation(&self, plan: &Arc<dyn ExecutionPlan>, cfg: &ConfigOptions)
        -> Option<TaskEstimation>;
    fn scale_up_leaf_node(&self, plan: &Arc<dyn ExecutionPlan>, task_count: usize,
        cfg: &ConfigOptions) -> Result<Option<Arc<dyn ExecutionPlan>>>;
    fn route_tasks(&self, ctx: &TaskRoutingContext<'_>)
        -> Result<Option<Vec<Url>>>;
}

The old API registered one implementation containing every hook:

SessionStateBuilder::new()
    .with_distributed_task_estimator(MyTaskEstimator);

Those phases now have dedicated event handlers, which can be ordinary functions and are registered independently:

fn desired_task_count(
    _event: DesiredTaskCountEvent,
) -> Option<DesiredTaskCountEventResponse> {
    None
}

fn scale_up_leaf_node(
    _event: ScaleUpLeafNodeEvent,
) -> Option<Result<ScaleUpLeafNodeEventResponse>> {
    None
}

fn route_tasks(
    _event: RouteTasksEvent,
) -> Option<Result<RouteTasksEventResponse>> {
    None
}

SessionStateBuilder::new()
    .with_distributed_desired_task_count_handler(desired_task_count)
    .with_distributed_scale_up_leaf_node_handler(scale_up_leaf_node)
    .with_distributed_route_tasks_handler(route_tasks);

@gabotechs
gabotechs force-pushed the gabrielmusat/events branch 2 times, most recently from 63e1cab to e240854 Compare July 23, 2026 18:17
@gabotechs
gabotechs force-pushed the gabrielmusat/events branch 2 times, most recently from fdbc9ba to f4361cc Compare July 27, 2026 07:37
@gabotechs
gabotechs force-pushed the gabrielmusat/events branch from f760854 to a4a9541 Compare July 27, 2026 08:26
@gabotechs
gabotechs marked this pull request as ready for review July 27, 2026 08:45
@gabotechs gabotechs changed the title Refactor task estimation events Introduce distributed planning lifecycle event handlers for replacing TaskEstimator Jul 27, 2026
@jayshrivastava

Copy link
Copy Markdown
Collaborator

This PR pretty much LGTM. I got a good sense of it while working on #571. I'm good to merge that into this one and then merge this into main.

@gabotechs
gabotechs force-pushed the gabrielmusat/events branch from a4a9541 to 1871bb9 Compare July 28, 2026 09:18
@gabotechs
gabotechs merged commit e3ac0fb into main Jul 28, 2026
31 checks passed
@gabotechs
gabotechs deleted the gabrielmusat/events branch July 28, 2026 15:12
gabotechs added a commit that referenced this pull request Jul 31, 2026
## Stack

1. #564
2. #567
<- you are here
3. #568
4. #569
5. #570

---

Moves routing policy into ordered `RouteTasksHandler`s. Built-ins now
cover child co-location, coordinator co-location, and randomized
fallback, while custom handlers can override them.

```rust
config.with_distributed_route_tasks_handler(|event| {
    Some(Ok(RouteTasksEventResponse::new(
        vec![worker_url.clone(); event.task_count],
    )))
});
```

---------

Co-authored-by: Jayant Shrivastava <jshrivastava03@gmail.com>
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