Skip to main content

🌊 hexastack-flow

Hexagonal workflow engine adapter integrating hexaflow with Hexastack CQRS, Relational Persistence, and Event Streaming.


🎯 Architectural Intent

hexastack-flow provides first-class hexagonal adapters connecting the lightweight hexaflow workflow engine to Hexastack:

  1. CQRS Bridge: CommandStep and QueryStep allow workflow steps to dispatch typed commands and queries directly onto the CommandBus and QueryBus, inheriting all CQRS middleware (auth, tracing, logging, metrics, retries).
  2. Durable Distributed Sagas: Workflows natively subsume the Saga pattern by pairing forward command execution stages with compensating rollback stages, backed by durable checkpoints.
  3. Enterprise Persistence: SqlAlchemyWorkflowStore persists workflow execution records and step checkpoints directly to PostgreSQL/SQLite/MySQL within transactional boundaries.
  4. Event Streaming: Emits domain events (WorkflowStartedEvent, WorkflowStepCompletedEvent, WorkflowSuspendedEvent, WorkflowCompletedEvent, WorkflowAbortedEvent) wrapped in standard CloudEventEnvelopes through hexastack-events.
  5. DevTools Visualizer: Backing engine for NiceGUI and Textual DAG monitoring.

🔄 Implementing the Saga Pattern as a Workflow

Historically, the Saga Pattern structures a distributed business transaction across multiple microservices or bounded contexts as a sequence of local transactions:

  • Forward transactions: $T_1, T_2, \dots, T_n$
  • Compensating transactions: $C_{k-1}, \dots, C_1$ executed in reverse (LIFO) order if step $k$ fails.

In hexastack-flow, you do not need a separate, restricted saga engine. A Saga is simply a workflow DAG that dispatches CQRS commands and executes compensating commands on failure.

Example: Trip Booking Saga with CQRS & Hexaflow

from hexaflow import Workflow
from hexastack_cqrs.ports.buses import CommandBusPort
from hexastack_flow.adapters.cqrs.runner import CqrsWorkflowRunner
from hexastack_flow.adapters.cqrs.steps import as_command_step

# 1. Define CQRS commands for forward actions & compensations
from my_domain.commands import (
    BookFlightCommand,
    CancelFlightCommand,
    BookHotelCommand,
    CancelHotelCommand,
    ChargePaymentCommand,
)

def build_trip_booking_workflow(bus: CommandBusPort, customer_id: str) -> Workflow:
    """Construct a durable distributed saga as a hexaflow Workflow."""
    workflow = (
        Workflow("trip-booking-saga")
        # Step 1: Reserve Flight
        .stage(
            "flight",
            as_command_step(
                lambda ctx: BookFlightCommand(customer_id=customer_id, destination="JFK"),
                bus,
                name="book_flight",
            ),
        )
        # Step 2: Reserve Hotel (runs after flight is confirmed)
        .stage(
            "hotel",
            as_command_step(
                lambda ctx: BookHotelCommand(customer_id=customer_id, room_type="deluxe"),
                bus,
                name="book_hotel",
            ),
            depends_on=["flight"],
        )
        # Step 3: Process Payment
        .stage(
            "payment",
            as_command_step(
                lambda ctx: ChargePaymentCommand(customer_id=customer_id, amount_cents=50000),
                bus,
                name="charge_payment",
            ),
            depends_on=["hotel"],
        )
    )
    return workflow

# 2. Execute via CqrsWorkflowRunner (with durable DB checkpoints)
runner = CqrsWorkflowRunner(engine=engine)
result = await runner.run(workflow.build())

Why Workflows are Superior to Linear Sagas

Feature Legacy In-Memory Saga hexastack-flow Workflow
Execution Topologies Strictly sequential ($T_1 \to T_2 \to T_3$) Arbitrary DAGs (e.g. reserve Flight & Hotel in parallel)
Crash Recovery In-memory only (lost if process restarts) Durable Checkpoints (SqlAlchemyWorkflowStore)
Step Retries Manual loop or fail immediately Configurable RetryPolicy (exponential backoff, jitter)
Observability Console logs CloudEvents (WorkflowStepCompletedEvent) + OTel spans
Human-in-the-Loop Not supported Pause / Resume (engine.suspend(), engine.resume())

📦 Installation

pip install hexastack[flow]

Or standalone:

pip install hexastack-flow

📄 License

Apache 2.0

Metadata

Release files for hexastack-flow 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hexastack-flow 0.5.0
File Size Uploaded
hexastack_flow-0.5.0.tar.gz 13.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hexastack-flow 0.5.0
File Interpreter ABI Platform
hexastack_flow-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 34.1 kB

Release files / hexastack_flow-0.5.0.tar.gz

Download URL hexastack_flow-0.5.0.tar.gz
Size 13.1 kB
Tags Source
SHA-256 checksum
How to use checksums
4c7a862081e56ffc6ad91c9cd3e3316ca435778e20b73ff29fbe0d64335d4e08
BLAKE2b-256 checksum
How to use checksums
ddebe4fe6a3828dc27d4c82f75e8dacd98cb25d5a9d8c0d8e149c6d3b64fd6c5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / hexastack_flow-0.5.0-py3-none-any.whl

Download URL hexastack_flow-0.5.0-py3-none-any.whl
Size 21.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
53bf953ab5e6108718a61e218c27b05f4e064e85adeaadfa0ae441353b05a2ad
BLAKE2b-256 checksum
How to use checksums
6921b9c66b58d339b8e055f87d85f71f4a1d04cd09a147f0da7217b92ed34932
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

This release

0.5.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page