Skip to main content

Design

Architecture

Time Wheel Engine

seqflow's Disruptor drives the tick clock. The wheel slots are a separate array exclusively owned by the handler goroutine.

seqflow Disruptor          Time Wheel Slots
(RingBuffer[int64]) (separate array)
Reserve(1) → Commit ──→ slots[cursor & mask]
process entries
fire expired tasks

Key invariant: only the handler goroutine reads/writes the slot array. Add() sends commands through a buffered channel. No locks on the wheel.

Lua Scripts

Four atomic scripts for state transitions:

ScriptOperationKeys
add.luaDuplicate check + SET + SADDtask key, index key
finish.luaCAS state check + SET + SREMtask key, index key
ready.luaState transition + RPUSHtask key, ready key
cancel.luaSET cancelled + SREMtask key, index key

All scripts use optimistic CAS: Go reads, validates, re-encodes, Lua compares-and-swaps.

Ready Queue

Two backends depending on mode:

  • Embedded (callback): background goroutine BLPOPs from Redis list, dispatches to callback function
  • HTTP (pull): Pop handler BLPOPs from Redis list directly

Redis List is the source of truth in both modes. Crash-safe: on restart, recovery re-pushes READY tasks.