Skip to content

seda://

Asynchronous in-process named-queue messaging — Helix's SEDA implementation. A to: seda://name enqueues the exchange on a bounded Go channel; one or more worker goroutines on the consumer side drain it and dispatch into the route. Reach for seda:// when you need decoupling (slow consumer must not block fast producer), worker-pool fan-in, or pub/sub fanout to multiple consumers — but you want it in-process, not via a real broker.

URI shape

seda://<name>[?size=1000&concurrentConsumers=1&blockWhenFull=false&...]

<name> is the queue identifier. Identical names within one Component share a single queue: the first CreateEndpoint call configures it, later calls return the same Endpoint (and an explicit size mismatch is rejected).

Parameters

Pulled directly from (*Component).Describe(). The flag triplet (blockWhenFull, discardWhenFull, offerTimeout) and the Helix-native overflowPolicy shortcut both work; overflowPolicy wins when both are set explicitly.

Queue sizing & workers

Param Type Default Side Description
name path — both Queue identifier.
size integer 1000 both Queue capacity. Set at creation; producer fills, consumer drains.
bufferSize integer 1000 both Legacy alias for size.
concurrentConsumers integer 1 consumer Number of worker goroutines draining the queue.
concurrency integer 1 consumer Legacy alias for concurrentConsumers.
limitConcurrentConsumers boolean true consumer Cap concurrentConsumers at 500 to prevent runaway pools.
multipleConsumers boolean false consumer Pub/sub fan-out — every registered consumer receives a copy of each message.

Producer overflow / no-consumer behaviour

Param Type Default Side Description
blockWhenFull boolean false producer Block (instead of erroring) when the queue is full.
discardWhenFull boolean false producer Silently drop (instead of erroring) when the queue is full. Mutually exclusive with blockWhenFull.
offerTimeout duration 0 producer When blockWhenFull=true, error out after this timeout instead of blocking forever.
failIfNoConsumers boolean false producer Return ConsumerNotAvailableError when no consumer is registered.
discardIfNoConsumers boolean false producer Silently drop when no consumer is registered. Mutually exclusive with failIfNoConsumers.
overflowPolicy enum fail producer Helix-native single-knob policy: fail / block / drop / newest (drop-oldest).
waitForTaskToComplete enum IfReplyExpected producer Wait policy — Always, Never, or IfReplyExpected (block on InOut, fire-forward on InOnly).
timeout duration 30s producer Maximum wait when waitForTaskToComplete dictates a wait.

Consumer

Param Type Default Side Description
pollTimeout duration 1s consumer Worker poll timeout — controls how quickly suspended-state and ctx-cancellation are observed.
purgeWhenStopping boolean false consumer Discard pending messages on Stop instead of draining them.

Durations accept Go format (30s, 500ms) or bare integer milliseconds (30000).

Body shape

Producer enqueues the exchange. The consumer worker dequeues and dispatches with the same In/Out/headers/properties. With multipleConsumers=true each registered consumer gets its own exchange.Copy().

Headers

seda:// sets no headers of its own.

Examples

Decouple a slow processor from a fast intake:

routes:
  - id: intake
    from: http-server://0.0.0.0:8080/events
    steps:
      - to: seda://to-process?size=10000&blockWhenFull=true

  - id: worker
    from: seda://to-process?concurrentConsumers=8
    steps:
      - to: postgres://events/insert

In-process pub/sub:

routes:
  - id: emit
    from: timer://heartbeat?period=10s
    steps:
      - to: seda://heartbeats?multipleConsumers=true

  - id: ui-sub
    from: seda://heartbeats?multipleConsumers=true
    steps:
      - to: ws-server://0.0.0.0:8081/heartbeat

  - id: metrics-sub
    from: seda://heartbeats?multipleConsumers=true
    steps:
      - to: log://heartbeat-metrics

InOut over seda (caller waits for reply):

- id: caller
  steps:
    - to: seda://heavy-compute?waitForTaskToComplete=Always&timeout=2m

Behavior notes

  • Backpressure. Default policy is fail (immediate QueueFullError). Set blockWhenFull=true for natural backpressure, optionally with offerTimeout to bound the wait.
  • Drop-oldest. overflowPolicy=newest is Helix-only: when the queue is full, the oldest pending exchange is discarded and the new one takes its slot — useful for "always reflect latest" sensors.
  • waitForTaskToComplete reply path. When a producer waits, the consumer's Out (or In, if Out not set) is copied back onto the caller's exchange after processing. Timeout fires seda: producer wait-for-reply timed out.
  • Suspend semantics. Suspend() flips a flag but workers keep polling — pending queue messages stay queued; new ones are skipped until Resume().
  • Queue sharing. Two endpoints with the same name share the queue and the configuration set at first creation. Later URI calls with a different size (or bufferSize) error out — explicit so a typo doesn't silently double the buffer.

Source

  • pkg/component/seda/seda.go — Component, Endpoint, Producer, Consumer, error types (ConsumerNotAvailableError, QueueFullError).
  • Bench: pkg/component/seda/seda_bench_test.go.

See also