Skip to content

Pipeline behaviors: MediatR-style middleware around handler execution #60

Description

@GiampaoloGabba

Cross-cutting concerns today mean either per-handler code (every handler restores its own tenant/correlation context, times itself, wraps its own transaction) or monitoring-event subscribers, which observe but cannot wrap. There is no seam to run logic around handler execution. Given the MediatR heritage of the dispatch API, pipeline behaviors are the natural shape.

Design sketch

  • IEverTaskBehavior<TTask> (name TBD), registered as open generics and resolved from the delivery's own service scope in WorkerExecutor.DoWorkCore, composed around Handle with the handler innermost. Registration order = execution order.
  • Wraps Handle only: not the lifecycle callbacks, not the rate-limit gate, not storage writes. The pipeline runs inside the existing execution boundary, so a behavior that throws follows the standard failure path — retry policy included — exactly as if the handler had thrown.
  • A behavior can short-circuit by not calling next (veto/kill-switch); semantics of a vetoed run to define (proposal: completes without executing, with a monitoring event saying which behavior vetoed).
  • Applies to every delivery on the executing host: one-shot, recurring occurrences, recovered tasks.

Use cases

Tenant/correlation scope restore, timing and custom metrics in one place, unit-of-work/transaction around the handler, feature-flag kill-switch, exception enrichment. The OpenTelemetry execution span (see the OTel issue) is implemented as a built-in behavior on top of this.

Distribution compatibility

Neutral by construction: behaviors run wherever the handler runs, so #59 (single consumer) and #31 (leases) are unaffected.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions