Skip to content

Refactor SchedulerDO source-specific dispatch behind a source-policy boundary #820

Description

@ColeMurray

Context

Surfaced during review of #819 (Slack channel triggers). The slack event source
adds source-specific dispatch logic to SchedulerDO.handleEvent /
handleRunComplete, gated behind event.source === "slack" checks:

  • candidate selection (getSlackAutomationsForChannel)
  • a per-automation hourly rate-limit branch
  • skipped-run recording (recordSlackSkip)
  • pre-insert run columns (slackRunColumns)
  • completion + concurrency-skip callback fan-out (notifySlackCompletion,
    notifySlackConcurrencySkip)

Today this is localized and readable, but SchedulerDO is where every future
source-specific exception would accumulate.

Proposal (when a second source needs custom dispatch hooks)

Introduce a small per-source policy/handler boundary so the central loop stays
boring — select candidates → evaluate conditions → ask the source policy whether
it may start → insert run → start session
— with per-source hooks for:

  • candidate selection
  • pre-insert run columns
  • "may start?" gating (rate limit / concurrency)
  • skip handling
  • completion notification

Why deferred (not in #819)

Slack is currently the only source with custom dispatch hooks; the other four
(github / linear / webhook / sentry) share the generic path with no overrides. A
5-method policy interface with four no-op implementors would be a speculative
abstraction shaped by a single caller. The right time to extract it is when a
second source needs source-specific dispatch behavior — that reveals the actual
shape the interface should take.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions