Skip to main content

A lightweight process tracker (Process / ProcessStep) for long-running, distributed workflows.

Project description

trellis logo

trellis-process

A lightweight process tracker for long-running, distributed workflows.

trellis-process gives you a small, reusable Process / ProcessStep domain model you can use to track business workflows across services and bounded contexts.

It works great for:

  • High-level journeys (e.g. referral lifecycle)
  • Sub-processes (e.g. authorization flow or notification delivery)
  • Any long-running process where multiple steps must eventually complete
  • Operations that need timeout and retry handling

Trellis is intentionally storage-agnostic: you bring your own database (PostgreSQL, DynamoDB, etc.) and wire it via a repository interface. The core library focuses on the domain model and invariants.


Features

  • ✅ Generic Process + ProcessStep model
  • Step-level timeout and retry support (based on Vaughn Vernon's pattern)
  • ✅ Supports multiple process_types (e.g. "ReferralJourney", "ClaimAdjudication")
  • ✅ Tracks required steps, state (pending, in_progress, completed, failed)
  • ✅ Simple API: start_step, complete_step, fail_step
  • TimeoutCheckerService for automatic timeout detection
  • ✅ Storage-agnostic: integrate with Postgres, DynamoDB, etc.
  • ✅ In-memory repositories for demos and unit tests

Installation

pip install trellis-process

With DynamoDB support:

pip install trellis-process[dynamodb]

Quick Start

Basic Process Tracking

from trellis_process import Process, ProcessStep, ProcessService
from trellis_process import InMemoryProcessRepository

repo = InMemoryProcessRepository()
service = ProcessService(repo)

# Create a process with steps
process = service.start_process(
    tenant_id="tenant-1",
    process_type="ReferralNotification",
    aggregate_type="Referral",
    aggregate_id="ref-123",
    steps=[
        ProcessStep(name="send_email"),
        ProcessStep(name="send_in_app"),
    ],
)

# Mark steps as completed
service.complete_step(process, "send_email")
service.complete_step(process, "send_in_app")

assert process.is_completed()

With Timeout and Retry

from trellis_process import (
    Process, ProcessStep, ProcessService,
    TimeoutCheckerService, ProcessStepTimedOut,
    InMemoryProcessRepository, InMemoryStepTrackerRepository,
)

process_repo = InMemoryProcessRepository()
tracker_repo = InMemoryStepTrackerRepository()
service = ProcessService(process_repo, tracker_repo)

# Create process with timeout-enabled steps
process = service.start_process(
    tenant_id="tenant-1",
    process_type="CaseCreation",
    aggregate_type="Referral",
    aggregate_id="ref-123",
    steps=[
        ProcessStep(name="create_case", timeout_ms=30000, retries_permitted=3),
    ],
)

# Start the step (creates tracker)
service.start_step(process, "create_case")

# Set up timeout checker (run on a schedule)
def handle_timeout(event: ProcessStepTimedOut):
    if event.has_fully_timed_out():
        service.fail_step(process, event.step_name, "Max retries exceeded")
    else:
        # Retry the operation
        retry_create_case(process)

checker = TimeoutCheckerService(tracker_repo, handle_timeout)

# Run periodically (e.g., every 30 seconds)
checker.check_for_timed_out_steps()

Architecture

Process (container)
├── ProcessStep: "send_email"     → StepTracker (timeout=30s, retries=3)
├── ProcessStep: "send_in_app"    → StepTracker (timeout=10s, retries=2)
└── ProcessStep: "create_case"    → StepTracker (timeout=60s, retries=5)
  • Process: Container for steps, tracks overall state
  • ProcessStep: Individual step with optional timeout config
  • StepTracker: Infrastructure object that monitors timeout and retry state
  • TimeoutCheckerService: Scans for timed-out trackers, publishes events

API Reference

ProcessStep

ProcessStep(
    name="step_name",
    timeout_ms=30000,        # Optional: timeout per attempt (ms)
    retries_permitted=3,     # Optional: number of retries
)

Process

process = Process.start(
    tenant_id="tenant-1",
    process_type="MyWorkflow",
    aggregate_type="MyAggregate",
    aggregate_id="id-123",
    steps=[...],
)

process.start_step("step_name")      # Returns StepTracker if timeout configured
process.complete_step("step_name")
process.fail_step("step_name", "error message")
process.is_completed()
process.has_failed()

ProcessService

service = ProcessService(process_repo, tracker_repo)  # tracker_repo optional

service.start_process(...)
service.start_step(process, "step_name")
service.complete_step(process, "step_name")
service.fail_step(process, "step_name", "error")

TimeoutCheckerService

checker = TimeoutCheckerService(tracker_repo, publish_event)
checker.check_for_timed_out_steps()  # Run on schedule

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

trellis_process-0.4.1.tar.gz (11.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

trellis_process-0.4.1-py3-none-any.whl (14.5 kB view details)

Uploaded Python 3

File details

Details for the file trellis_process-0.4.1.tar.gz.

File metadata

  • Download URL: trellis_process-0.4.1.tar.gz
  • Upload date:
  • Size: 11.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.11.14 Linux/6.11.0-1018-azure

File hashes

Hashes for trellis_process-0.4.1.tar.gz
Algorithm Hash digest
SHA256 410a4913d5a3765ab0e0dad5ffc35d8a0edf95185c644a254b9ab70b5887d3b2
MD5 c44f07f5f5af3068ebede217aff1da02
BLAKE2b-256 432ae6782da06c7009955798ace7ebef8159344c637637a4a2cc2801153d77d6

See more details on using hashes here.

File details

Details for the file trellis_process-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: trellis_process-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 14.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.11.14 Linux/6.11.0-1018-azure

File hashes

Hashes for trellis_process-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6b1a109b8bad3bdefc30239cfc881f4c077213c116c8dbcb0a08bf4d70fe0df4
MD5 f4fe3e60087279d414f67a3aa37673f6
BLAKE2b-256 8bd4d02719805cf67003fb607a6c5ba3313eff0f251439bff755605f08318161

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page