Skip to content

refactor!: builder pattern for TaskSubmission and accessor methods for TaskContext#6

Merged
deepjoy merged 1 commit into
mainfrom
builder-pattern-ergonomics
Mar 14, 2026
Merged

refactor!: builder pattern for TaskSubmission and accessor methods for TaskContext#6
deepjoy merged 1 commit into
mainfrom
builder-pattern-ergonomics

Conversation

@deepjoy
Copy link
Copy Markdown
Owner

@deepjoy deepjoy commented Mar 14, 2026

  • Replace TaskSubmission struct literal construction with a builder API: TaskSubmission::new("type").key("k").priority(p).payload_json(&data)?.expected_io(r, w)
  • Make TaskContext fields pub(crate) and expose them via accessor methods (.record(), .token(), .progress()) for a stable executor interface
  • Add scoped task submission from executors via ctx.submit() / ctx.submit_typed() — no need for a separate Scheduler handle in app state
  • Add a human-readable label field to TaskRecord, TaskHistoryRecord, TaskSubmission, and all SchedulerEvent variants (migration 002_add_label.sql)
  • Deprecate TaskSubmission::with_payload() in favour of the builder API

Breaking changes

  • TaskContext fields (record, token, progress, scheduler) are now pub(crate) — use the new accessor methods instead of direct field access
  • TaskSubmission struct literals now require the label field — prefer TaskSubmission::new() builder which sets it automatically
  • All SchedulerEvent variants now include a label: String field

…ssion and accessor methods for TaskContext

- Add TaskSubmission::new() builder with chainable .key(), .label(), .priority(),
  .payload_json(), .payload_raw(), .expected_io(), and .fail_fast() methods
- Make TaskContext fields pub(crate) with accessor methods: .record(), .token(), .progress()
- Add scoped task submission via ctx.submit() and ctx.submit_typed()
- Add human-readable `label` field to TaskRecord, TaskHistoryRecord, TaskSubmission,
  and all SchedulerEvent variants, with migration 002_add_label.sql
- Deprecate TaskSubmission::with_payload() in favor of builder API
- Update all docs, examples, and tests to use new ergonomic API

BREAKING CHANGE: TaskContext fields are now private (use accessor methods),
TaskSubmission struct literals require the new `label` field.
@deepjoy deepjoy enabled auto-merge (squash) March 14, 2026 04:44
@deepjoy deepjoy merged commit 68b301b into main Mar 14, 2026
1 check passed
@github-actions github-actions Bot mentioned this pull request Mar 14, 2026
deepjoy pushed a commit that referenced this pull request Mar 14, 2026
## 🤖 New release

* `taskmill`: 0.2.0 -> 0.3.0 (⚠ API breaking changes)

### ⚠ `taskmill` breaking changes

```text
--- failure constructible_struct_adds_field: externally-constructible struct adds field ---

Description:
A pub struct constructible with a struct literal has a new pub field. Existing struct literals must be updated to include the new field.
        ref: https://doc.rust-lang.org/reference/expressions/struct-expr.html
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.46.0/src/lints/constructible_struct_adds_field.ron

Failed in:
  field TaskHistoryRecord.label in /tmp/.tmpgCrMRt/taskmill/src/task.rs:147
  field TaskHistoryRecord.expected_net_rx_bytes in /tmp/.tmpgCrMRt/taskmill/src/task.rs:154
  field TaskHistoryRecord.expected_net_tx_bytes in /tmp/.tmpgCrMRt/taskmill/src/task.rs:156
  field TaskHistoryRecord.actual_net_rx_bytes in /tmp/.tmpgCrMRt/taskmill/src/task.rs:160
  field TaskHistoryRecord.actual_net_tx_bytes in /tmp/.tmpgCrMRt/taskmill/src/task.rs:162
  field TaskHistoryRecord.group_key in /tmp/.tmpgCrMRt/taskmill/src/task.rs:174
  field TaskHistoryRecord.label in /tmp/.tmpgCrMRt/taskmill/src/task.rs:147
  field TaskHistoryRecord.expected_net_rx_bytes in /tmp/.tmpgCrMRt/taskmill/src/task.rs:154
  field TaskHistoryRecord.expected_net_tx_bytes in /tmp/.tmpgCrMRt/taskmill/src/task.rs:156
  field TaskHistoryRecord.actual_net_rx_bytes in /tmp/.tmpgCrMRt/taskmill/src/task.rs:160
  field TaskHistoryRecord.actual_net_tx_bytes in /tmp/.tmpgCrMRt/taskmill/src/task.rs:162
  field TaskHistoryRecord.group_key in /tmp/.tmpgCrMRt/taskmill/src/task.rs:174
  field EstimatedProgress.label in /tmp/.tmpgCrMRt/taskmill/src/scheduler/progress.rs:95
  field EstimatedProgress.label in /tmp/.tmpgCrMRt/taskmill/src/scheduler/progress.rs:95
  field EstimatedProgress.label in /tmp/.tmpgCrMRt/taskmill/src/scheduler/progress.rs:95
  field TaskRecord.label in /tmp/.tmpgCrMRt/taskmill/src/task.rs:99
  field TaskRecord.expected_net_rx_bytes in /tmp/.tmpgCrMRt/taskmill/src/task.rs:106
  field TaskRecord.expected_net_tx_bytes in /tmp/.tmpgCrMRt/taskmill/src/task.rs:108
  field TaskRecord.group_key in /tmp/.tmpgCrMRt/taskmill/src/task.rs:123
  field TaskRecord.label in /tmp/.tmpgCrMRt/taskmill/src/task.rs:99
  field TaskRecord.expected_net_rx_bytes in /tmp/.tmpgCrMRt/taskmill/src/task.rs:106
  field TaskRecord.expected_net_tx_bytes in /tmp/.tmpgCrMRt/taskmill/src/task.rs:108
  field TaskRecord.group_key in /tmp/.tmpgCrMRt/taskmill/src/task.rs:123
  field ResourceSnapshot.net_rx_bytes_per_sec in /tmp/.tmpgCrMRt/taskmill/src/resource/mod.rs:34
  field ResourceSnapshot.net_tx_bytes_per_sec in /tmp/.tmpgCrMRt/taskmill/src/resource/mod.rs:36
  field ResourceSnapshot.net_rx_bytes_per_sec in /tmp/.tmpgCrMRt/taskmill/src/resource/mod.rs:34
  field ResourceSnapshot.net_tx_bytes_per_sec in /tmp/.tmpgCrMRt/taskmill/src/resource/mod.rs:36
  field TaskSubmission.dedup_key in /tmp/.tmpgCrMRt/taskmill/src/task.rs:332
  field TaskSubmission.label in /tmp/.tmpgCrMRt/taskmill/src/task.rs:335
  field TaskSubmission.expected_net_rx_bytes in /tmp/.tmpgCrMRt/taskmill/src/task.rs:341
  field TaskSubmission.expected_net_tx_bytes in /tmp/.tmpgCrMRt/taskmill/src/task.rs:343
  field TaskSubmission.group_key in /tmp/.tmpgCrMRt/taskmill/src/task.rs:357
  field TaskSubmission.dedup_key in /tmp/.tmpgCrMRt/taskmill/src/task.rs:332
  field TaskSubmission.label in /tmp/.tmpgCrMRt/taskmill/src/task.rs:335
  field TaskSubmission.expected_net_rx_bytes in /tmp/.tmpgCrMRt/taskmill/src/task.rs:341
  field TaskSubmission.expected_net_tx_bytes in /tmp/.tmpgCrMRt/taskmill/src/task.rs:343
  field TaskSubmission.group_key in /tmp/.tmpgCrMRt/taskmill/src/task.rs:357

--- failure enum_struct_variant_field_added: pub enum struct variant field added ---

Description:
An enum's exhaustive struct variant has a new field, which has to be included when constructing or matching on this variant.
        ref: https://doc.rust-lang.org/reference/attributes/type_system.html#the-non_exhaustive-attribute
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.46.0/src/lints/enum_struct_variant_field_added.ron

Failed in:
  field label of variant SchedulerEvent::Dispatched in /tmp/.tmpgCrMRt/taskmill/src/scheduler/mod.rs:82
  field label of variant SchedulerEvent::Completed in /tmp/.tmpgCrMRt/taskmill/src/scheduler/mod.rs:89
  field label of variant SchedulerEvent::Failed in /tmp/.tmpgCrMRt/taskmill/src/scheduler/mod.rs:96
  field label of variant SchedulerEvent::Preempted in /tmp/.tmpgCrMRt/taskmill/src/scheduler/mod.rs:105
  field label of variant SchedulerEvent::Cancelled in /tmp/.tmpgCrMRt/taskmill/src/scheduler/mod.rs:112
  field label of variant SchedulerEvent::Progress in /tmp/.tmpgCrMRt/taskmill/src/scheduler/mod.rs:119
  field label of variant SchedulerEvent::Dispatched in /tmp/.tmpgCrMRt/taskmill/src/scheduler/mod.rs:82
  field label of variant SchedulerEvent::Completed in /tmp/.tmpgCrMRt/taskmill/src/scheduler/mod.rs:89
  field label of variant SchedulerEvent::Failed in /tmp/.tmpgCrMRt/taskmill/src/scheduler/mod.rs:96
  field label of variant SchedulerEvent::Preempted in /tmp/.tmpgCrMRt/taskmill/src/scheduler/mod.rs:105
  field label of variant SchedulerEvent::Cancelled in /tmp/.tmpgCrMRt/taskmill/src/scheduler/mod.rs:112
  field label of variant SchedulerEvent::Progress in /tmp/.tmpgCrMRt/taskmill/src/scheduler/mod.rs:119

--- 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:
  TaskContext::deserialize_typed, previously in file /tmp/.tmpuPxM8D/taskmill/src/registry.rs:157
  TaskContext::deserialize_typed, previously in file /tmp/.tmpuPxM8D/taskmill/src/registry.rs:157

--- failure method_parameter_count_changed: pub method parameter count changed ---

Description:
A publicly-visible method now takes a different number of parameters, not counting the receiver (self) parameter.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#fn-change-arity
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.46.0/src/lints/method_parameter_count_changed.ron

Failed in:
  taskmill::store::TaskStore::fail now takes 5 parameters instead of 6, in /tmp/.tmpgCrMRt/taskmill/src/store.rs:591
  taskmill::TaskStore::fail now takes 5 parameters instead of 6, in /tmp/.tmpgCrMRt/taskmill/src/store.rs:591

--- 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::task::TaskResult, previously in file /tmp/.tmpuPxM8D/taskmill/src/task.rs:151
  struct taskmill::TaskResult, previously in file /tmp/.tmpuPxM8D/taskmill/src/task.rs:151

--- failure struct_pub_field_missing: pub struct's pub field removed or renamed ---

Description:
A publicly-visible struct has at least one public field that 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/struct_pub_field_missing.ron

Failed in:
  field actual_read_bytes of struct TaskError, previously in file /tmp/.tmpuPxM8D/taskmill/src/task.rs:161
  field actual_write_bytes of struct TaskError, previously in file /tmp/.tmpuPxM8D/taskmill/src/task.rs:162
  field actual_read_bytes of struct TaskError, previously in file /tmp/.tmpuPxM8D/taskmill/src/task.rs:161
  field actual_write_bytes of struct TaskError, previously in file /tmp/.tmpuPxM8D/taskmill/src/task.rs:162
  field key of struct TaskSubmission, previously in file /tmp/.tmpuPxM8D/taskmill/src/task.rs:222
  field key of struct TaskSubmission, previously in file /tmp/.tmpuPxM8D/taskmill/src/task.rs:222
  field record of struct TaskContext, previously in file /tmp/.tmpuPxM8D/taskmill/src/registry.rs:140
  field token of struct TaskContext, previously in file /tmp/.tmpuPxM8D/taskmill/src/registry.rs:143
  field progress of struct TaskContext, previously in file /tmp/.tmpuPxM8D/taskmill/src/registry.rs:145
  field record of struct TaskContext, previously in file /tmp/.tmpuPxM8D/taskmill/src/registry.rs:140
  field token of struct TaskContext, previously in file /tmp/.tmpuPxM8D/taskmill/src/registry.rs:143
  field progress of struct TaskContext, previously in file /tmp/.tmpuPxM8D/taskmill/src/registry.rs:145

--- failure struct_pub_field_now_doc_hidden: pub struct field is now #[doc(hidden)] ---

Description:
A pub field of a pub struct is now marked #[doc(hidden)] and is no longer part of the public API.
        ref: https://doc.rust-lang.org/rustdoc/write-documentation/the-doc-attribute.html#hidden
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.46.0/src/lints/struct_pub_field_now_doc_hidden.ron

Failed in:
  field TaskContext.record in file /tmp/.tmpgCrMRt/taskmill/src/registry.rs:182
  field TaskContext.token in file /tmp/.tmpgCrMRt/taskmill/src/registry.rs:182
  field TaskContext.progress in file /tmp/.tmpgCrMRt/taskmill/src/registry.rs:182
  field TaskContext.record in file /tmp/.tmpgCrMRt/taskmill/src/registry.rs:182
  field TaskContext.token in file /tmp/.tmpgCrMRt/taskmill/src/registry.rs:182
  field TaskContext.progress in file /tmp/.tmpgCrMRt/taskmill/src/registry.rs:182
```

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

<blockquote>

## [0.3.0](v0.2.0...v0.3.0)
- 2026-03-14

### Added

- add network IO pressure and per-group concurrency limiting
([#7](#7))

### Other

- [**breaking**] builder pattern for TaskSubmission and accessor methods
for TaskContext ([#6](#6))
- [**breaking**] simplify executor API with incremental IO tracking and
expanded docs ([#4](#4))
</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>
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