Skip to content

feat!: replace &TaskContext with DomainTaskContext<D> for type-safe child spawning#68

Merged
deepjoy merged 2 commits into
mainfrom
remove-unsafe-api
Mar 21, 2026
Merged

feat!: replace &TaskContext with DomainTaskContext<D> for type-safe child spawning#68
deepjoy merged 2 commits into
mainfrom
remove-unsafe-api

Conversation

@deepjoy
Copy link
Copy Markdown
Owner

@deepjoy deepjoy commented Mar 21, 2026

Summary

  • Introduce DomainTaskContext<'a, D>, a zero-cost wrapper (&TaskContext + PhantomData<D>) that carries domain identity as a type parameter, enabling compile-time–safe child spawning
  • Add ChildSpawnBuilder with .key() / .priority() / .ttl() / .group() overrides and IntoFuture support
  • Add DomainSubmitBuilder::child_of(&ctx) for ergonomic cross-domain child creation
  • Change TypedExecutor<T> trait: ctx parameter is now DomainTaskContext<'a, T::Domain> instead of &'a TaskContext
  • Remove TaskExecutor, TaskContext, Domain::raw_executor(), and DomainHandle::submit_raw() from the public API
  • Fix DomainSubmitBuilder::on_dependency_failure which was previously a no-op
  • Migrate all executor impls, spawn_child call sites, and submit_raw call sites across tests, benches, and examples

Breaking changes

Before After
ctx: &'a TaskContext ctx: DomainTaskContext<'a, T::Domain>
ctx.spawn_child(TaskSubmission::new("name").payload_json(&t)?) ctx.spawn_child_with(t).key("name").await?
ctx.domain::<D>().submit_with(t).parent(ctx.record().id) ctx.domain::<D>().submit_with(t).child_of(&ctx)
domain.raw_executor("name", exec) removed — use Domain::task::<T>(exec)
handle.submit_raw(TaskSubmission::new(...)) removed — use handle.submit_with(typed_task)
pub use registry::{TaskContext, TaskExecutor} removed from public API

deepjoy added 2 commits March 20, 2026 17:53
…hild spawning

Introduce a domain-parameterized execution context wrapper that enables
compile-time–safe child spawning and eliminates the untyped executor API
from the public surface.

- Add DomainTaskContext<'a, D> (zero-cost wrapper: &TaskContext + PhantomData)
- Add ChildSpawnBuilder with .key()/.priority()/.ttl()/.group() overrides
- Add DomainSubmitBuilder::child_of() for cross-domain children
- Change TypedExecutor<T> signature: ctx parameter is now DomainTaskContext
- Make TaskExecutor, TaskContext, raw_executor, submit_raw pub(crate)
- Migrate all executor impls, spawn_child, and submit_raw call sites

Closes #65
@deepjoy deepjoy enabled auto-merge (squash) March 21, 2026 09:06
@deepjoy deepjoy merged commit 0a608a5 into main Mar 21, 2026
2 checks passed
@github-actions github-actions Bot mentioned this pull request Mar 21, 2026
deepjoy pushed a commit that referenced this pull request Mar 21, 2026
## 🤖 New release

* `taskmill`: 0.5.3 -> 0.6.0 (⚠ API breaking changes)

### ⚠ `taskmill` breaking changes

```text
--- failure inherent_method_missing: pub method removed or renamed ---

Description:
A publicly-visible method or associated fn is no longer available under its prior name. It may have been renamed or removed entirely.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.46.0/src/lints/inherent_method_missing.ron

Failed in:
  DomainHandle::submit_raw, previously in file /tmp/.tmpZpSjOB/taskmill/src/domain.rs:502
  DomainHandle::submit_raw, previously in file /tmp/.tmpZpSjOB/taskmill/src/domain.rs:502
  Domain::raw_executor, previously in file /tmp/.tmpZpSjOB/taskmill/src/domain.rs:349
  Domain::raw_executor, previously in file /tmp/.tmpZpSjOB/taskmill/src/domain.rs:349
  TaskTypeRegistry::register, previously in file /tmp/.tmpZpSjOB/taskmill/src/registry/mod.rs:170
  TaskTypeRegistry::register_with_ttl, previously in file /tmp/.tmpZpSjOB/taskmill/src/registry/mod.rs:179
  TaskTypeRegistry::register_with_retry_policy, previously in file /tmp/.tmpZpSjOB/taskmill/src/registry/mod.rs:190

--- failure struct_missing: pub struct removed or renamed ---

Description:
A publicly-visible struct cannot be imported by its prior path. A `pub use` may have been removed, or the struct itself may have been renamed or removed entirely.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.46.0/src/lints/struct_missing.ron

Failed in:
  struct taskmill::registry::TaskContext, previously in file /tmp/.tmpZpSjOB/taskmill/src/registry/context.rs:29
  struct taskmill::TaskContext, previously in file /tmp/.tmpZpSjOB/taskmill/src/registry/context.rs:29

--- failure trait_missing: pub trait removed or renamed ---

Description:
A publicly-visible trait cannot be imported by its prior path. A `pub use` may have been removed, or the trait itself may have been renamed or removed entirely.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.46.0/src/lints/trait_missing.ron

Failed in:
  trait taskmill::registry::TaskExecutor, previously in file /tmp/.tmpZpSjOB/taskmill/src/registry/mod.rs:56
  trait taskmill::TaskExecutor, previously in file /tmp/.tmpZpSjOB/taskmill/src/registry/mod.rs:56
```

<details><summary><i><b>Changelog</b></i></summary><p>

<blockquote>

## [0.6.0](v0.5.3...v0.6.0)
- 2026-03-21

### Added

- [**breaking**] replace `&TaskContext` with `DomainTaskContext<D>` for
type-safe child spawning
([#68](#68))

### Other

- migrate all tests/benches from TaskExecutor to TypedExecutor
([#66](#66))
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

Benchmark Comparison

Click to expand
group                                       current
-----                                       -------
backoff_delay/constant                      1.00     43.6±0.15ns        ? ?/sec
backoff_delay/exponential                   1.00    185.7±0.41ns        ? ?/sec
backoff_delay/exponential_jitter            1.00    452.6±1.45ns        ? ?/sec
backoff_delay/linear                        1.00     76.0±0.34ns        ? ?/sec
batch_submit_1000                           1.00     35.4±3.82ms        ? ?/sec
byte_progress/byte_reporting_500            1.00    263.5±5.78ms        ? ?/sec
byte_progress/noop_500                      1.00    260.5±4.01ms        ? ?/sec
byte_progress_snapshot_100_tasks            1.00     87.0±2.31ms        ? ?/sec
concurrency_scaling/1                       1.00    397.6±6.58ms        ? ?/sec
concurrency_scaling/2                       1.00    333.7±7.91ms        ? ?/sec
concurrency_scaling/4                       1.00    290.8±6.53ms        ? ?/sec
concurrency_scaling/8                       1.00    260.6±4.87ms        ? ?/sec
count_by_tags/100                           1.00    133.9±4.73µs        ? ?/sec
count_by_tags/1000                          1.00    221.6±4.16µs        ? ?/sec
count_by_tags/5000                          1.00    626.0±6.37µs        ? ?/sec
dep_chain_dispatch/10                       1.00     12.1±0.17ms        ? ?/sec
dep_chain_dispatch/25                       1.00     28.8±0.49ms        ? ?/sec
dep_chain_dispatch/50                       1.00     58.2±1.13ms        ? ?/sec
dep_chain_submit/10                         1.00      3.5±0.18ms        ? ?/sec
dep_chain_submit/200                        1.00     81.6±5.46ms        ? ?/sec
dep_chain_submit/50                         1.00     18.4±1.27ms        ? ?/sec
dep_fan_in_dispatch/10                      1.00      7.9±0.15ms        ? ?/sec
dep_fan_in_dispatch/100                     1.00     56.6±1.44ms        ? ?/sec
dep_fan_in_dispatch/50                      1.00     29.7±0.66ms        ? ?/sec
dispatch_and_complete_1000                  1.00    523.5±7.82ms        ? ?/sec
dispatch_group_scaling/1                    1.00    451.2±5.85ms        ? ?/sec
dispatch_group_scaling/10                   1.00    450.8±5.65ms        ? ?/sec
dispatch_group_scaling/100                  1.00    451.3±6.36ms        ? ?/sec
dispatch_group_scaling/50                   1.00    451.5±5.65ms        ? ?/sec
dispatch_no_groups_500                      1.00    260.3±4.58ms        ? ?/sec
dispatch_one_group_500                      1.00    451.1±6.41ms        ? ?/sec
dispatch_permanent_failure_500              1.00    396.2±5.62ms        ? ?/sec
history_by_type/100                         1.00   898.2±25.69µs        ? ?/sec
history_by_type/1000                        1.00   913.2±27.98µs        ? ?/sec
history_by_type/5000                        1.00   959.8±26.55µs        ? ?/sec
history_query/100                           1.00   559.0±11.77µs        ? ?/sec
history_query/1000                          1.00    563.5±6.30µs        ? ?/sec
history_query/5000                          1.00    575.2±8.21µs        ? ?/sec
history_stats/100                           1.00    152.3±1.46µs        ? ?/sec
history_stats/1000                          1.00    366.0±1.64µs        ? ?/sec
history_stats/5000                          1.00   1289.1±4.90µs        ? ?/sec
mixed_priority_dispatch_500                 1.00    289.3±5.90ms        ? ?/sec
peek_next/100                               1.00    125.4±3.45µs        ? ?/sec
peek_next/1000                              1.00    124.9±5.70µs        ? ?/sec
peek_next/5000                              1.00    124.3±3.81µs        ? ?/sec
query_by_tags/100                           1.00  1233.5±149.76µs        ? ?/sec
query_by_tags/1000                          1.00      9.6±0.24ms        ? ?/sec
query_by_tags/5000                          1.00     55.9±7.47ms        ? ?/sec
retryable_dead_letter/constant              1.00    161.1±1.73ms        ? ?/sec
retryable_dead_letter/exponential           1.00    161.3±1.83ms        ? ?/sec
retryable_dead_letter/exponential_jitter    1.00    160.8±1.82ms        ? ?/sec
retryable_dead_letter/linear                1.00    161.1±1.90ms        ? ?/sec
submit_1000_tasks                           1.00    190.3±6.21ms        ? ?/sec
submit_dedup_hit_1000                       1.00   253.6±11.34ms        ? ?/sec
submit_with_tags/0                          1.00     94.7±4.63ms        ? ?/sec
submit_with_tags/10                         1.00   252.7±16.47ms        ? ?/sec
submit_with_tags/20                         1.00   414.3±24.18ms        ? ?/sec
submit_with_tags/5                          1.00   175.5±10.60ms        ? ?/sec
tag_values/100                              1.00    138.6±5.71µs        ? ?/sec
tag_values/1000                             1.00    198.6±5.33µs        ? ?/sec
tag_values/5000                             1.00    473.6±6.26µs        ? ?/sec

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.

1 participant