Skip to content

feat: add tag key prefix queries for namespace-scoped discovery#71

Merged
deepjoy merged 4 commits into
mainfrom
prefix-tag-search
Mar 22, 2026
Merged

feat: add tag key prefix queries for namespace-scoped discovery#71
deepjoy merged 4 commits into
mainfrom
prefix-tag-search

Conversation

@deepjoy
Copy link
Copy Markdown
Owner

@deepjoy deepjoy commented Mar 22, 2026

Summary

  • Add four new query methods (tag_keys_by_prefix, tasks_by_tag_key_prefix, count_by_tag_key_prefix, cancel_by_tag_key_prefix) across TaskStore, Scheduler, ModuleHandle, and DomainHandle for discovering and operating on tasks by tag key prefix (e.g. "billing.")
  • Add escape_like_prefix() helper that escapes SQL LIKE wildcards (%, _, \) in user-supplied input before appending the trailing %, ensuring only true prefix matching
  • Add domain-scoped _with_prefix store variants that additionally filter by task_type LIKE 'domain%', consistent with the existing tag query pattern
  • Document the new APIs in crate-level docs, docs/query-apis.md, and docs/multi-module-apps.md

Motivation

When multiple independent libraries share a single scheduler, each naturally namespaces its tags with a prefix (billing.customer_id, media.pipeline, etc.). The existing exact-match tag API cannot answer namespace-scoped questions like "how many billing tasks are active?" without knowing every possible billing.* key upfront. The new prefix queries fill this gap.

Closes #41

deepjoy added 3 commits March 21, 2026 19:01
Support querying, counting, and cancelling tasks by tag key prefix
(e.g. "billing.") across all layers: TaskStore, Scheduler, ModuleHandle,
and DomainHandle. LIKE wildcards in user-supplied prefixes are escaped.
@github-actions
Copy link
Copy Markdown
Contributor

Benchmark Comparison

Click to expand
group                                       current
-----                                       -------
backoff_delay/constant                      1.00     44.0±2.13ns        ? ?/sec
backoff_delay/exponential                   1.00    190.6±0.50ns        ? ?/sec
backoff_delay/exponential_jitter            1.00    407.7±3.21ns        ? ?/sec
backoff_delay/linear                        1.00     76.3±0.22ns        ? ?/sec
batch_submit_1000                           1.00     33.5±2.62ms        ? ?/sec
byte_progress/byte_reporting_500            1.00    242.9±4.50ms        ? ?/sec
byte_progress/noop_500                      1.00    242.8±4.49ms        ? ?/sec
byte_progress_snapshot_100_tasks            1.00     80.3±3.35ms        ? ?/sec
concurrency_scaling/1                       1.00    376.7±5.83ms        ? ?/sec
concurrency_scaling/2                       1.00    312.7±5.54ms        ? ?/sec
concurrency_scaling/4                       1.00    269.4±5.19ms        ? ?/sec
concurrency_scaling/8                       1.00    240.6±4.14ms        ? ?/sec
count_by_tags/100                           1.00    127.8±2.76µs        ? ?/sec
count_by_tags/1000                          1.00    218.7±8.37µs        ? ?/sec
count_by_tags/5000                          1.00   625.1±16.02µs        ? ?/sec
dep_chain_dispatch/10                       1.00     11.1±0.12ms        ? ?/sec
dep_chain_dispatch/25                       1.00     26.6±0.48ms        ? ?/sec
dep_chain_dispatch/50                       1.00     52.9±0.98ms        ? ?/sec
dep_chain_submit/10                         1.00      3.3±0.15ms        ? ?/sec
dep_chain_submit/200                        1.00     76.8±3.70ms        ? ?/sec
dep_chain_submit/50                         1.00     17.4±0.98ms        ? ?/sec
dep_fan_in_dispatch/10                      1.00      7.5±1.12ms        ? ?/sec
dep_fan_in_dispatch/100                     1.00     52.5±0.80ms        ? ?/sec
dep_fan_in_dispatch/50                      1.00     27.3±0.64ms        ? ?/sec
dispatch_and_complete_1000                  1.00    485.4±8.33ms        ? ?/sec
dispatch_group_scaling/1                    1.00    409.2±5.12ms        ? ?/sec
dispatch_group_scaling/10                   1.00    408.5±5.42ms        ? ?/sec
dispatch_group_scaling/100                  1.00    410.0±7.45ms        ? ?/sec
dispatch_group_scaling/50                   1.00    408.8±6.00ms        ? ?/sec
dispatch_no_groups_500                      1.00    242.0±4.93ms        ? ?/sec
dispatch_one_group_500                      1.00    404.8±6.44ms        ? ?/sec
dispatch_permanent_failure_500              1.00    360.0±7.48ms        ? ?/sec
history_by_type/100                         1.00   935.2±26.55µs        ? ?/sec
history_by_type/1000                        1.00   948.6±29.18µs        ? ?/sec
history_by_type/5000                        1.00   943.1±19.73µs        ? ?/sec
history_query/100                           1.00   545.7±14.49µs        ? ?/sec
history_query/1000                          1.00    549.2±6.06µs        ? ?/sec
history_query/5000                          1.00    561.9±7.68µs        ? ?/sec
history_stats/100                           1.00    145.7±1.13µs        ? ?/sec
history_stats/1000                          1.00    357.6±5.48µs        ? ?/sec
history_stats/5000                          1.00   1284.4±4.85µs        ? ?/sec
mixed_priority_dispatch_500                 1.00    269.3±4.93ms        ? ?/sec
peek_next/100                               1.00    118.4±2.10µs        ? ?/sec
peek_next/1000                              1.00    118.8±2.68µs        ? ?/sec
peek_next/5000                              1.00    119.1±5.87µs        ? ?/sec
query_by_tags/100                           1.00  1288.1±175.75µs        ? ?/sec
query_by_tags/1000                          1.00     10.8±1.57ms        ? ?/sec
query_by_tags/5000                          1.00     57.3±8.03ms        ? ?/sec
retryable_dead_letter/constant              1.00    146.3±3.30ms        ? ?/sec
retryable_dead_letter/exponential           1.00    146.2±4.59ms        ? ?/sec
retryable_dead_letter/exponential_jitter    1.00    146.2±1.94ms        ? ?/sec
retryable_dead_letter/linear                1.00    147.8±4.69ms        ? ?/sec
submit_1000_tasks                           1.00    180.5±5.69ms        ? ?/sec
submit_dedup_hit_1000                       1.00   240.5±10.28ms        ? ?/sec
submit_with_tags/0                          1.00     89.8±2.83ms        ? ?/sec
submit_with_tags/10                         1.00   240.4±10.95ms        ? ?/sec
submit_with_tags/20                         1.00   389.6±16.14ms        ? ?/sec
submit_with_tags/5                          1.00    165.6±6.50ms        ? ?/sec
tag_values/100                              1.00    133.6±3.56µs        ? ?/sec
tag_values/1000                             1.00    193.8±3.61µs        ? ?/sec
tag_values/5000                             1.00    458.2±4.52µs        ? ?/sec

@deepjoy deepjoy enabled auto-merge (squash) March 22, 2026 02:40
@deepjoy deepjoy merged commit fc98428 into main Mar 22, 2026
1 of 2 checks passed
@github-actions github-actions Bot mentioned this pull request Mar 22, 2026
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.

Feature: Tag key prefix queries for multi-library namespacing

1 participant