SkillAgentSearch skills...

Floxy

Lightweight workflow engine for GoLang with Saga-like rollback mechanism

Install / Use

/learn @floxy-project/Floxy
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

floxy

Go Version Go Reference Go Report Card Coverage Status MIT License

boosty-cozy

A Go library for creating and executing workflows with a custom DSL. Implements the Saga pattern with orchestrator approach, providing transaction management and compensation capabilities.

floxy means "flow" + "flux" + "tiny".

⚠ Disclaimer

Floxy is an early-stage project. It is under active development and not battle-tested yet. The software is provided “as is”, without any warranties or guarantees of stability, correctness, or fitness for any particular purpose. By using this project, you acknowledge that all risks are your own, and the authors cannot be held responsible for any damages, data loss, or failures resulting from its use.

Join the discussion if you’re experimenting with Floxy or want to help test the engine in real-world scenarios.

<img src="docs/floxy_logo.png" width="500">

Table of Contents

Features

  • Workflow DSL: Declarative workflow definition using Builder pattern
  • Saga Pattern: Orchestrator-based saga implementation with compensation
  • Workflows Versioning: Safe changing flows using versions
  • Transaction Management: Built-in transaction support with rollback capabilities
  • Parallel Execution: Fork/Join patterns for concurrent workflow steps with dynamic wait-for detection
  • Error Handling: Automatic retry mechanisms and failure compensation
  • SavePoints: Rollback to specific points in workflow execution
  • Conditional branching with Condition steps. Smart rollback for parallel flows with condition steps
  • Human-in-the-loop: Interactive workflow steps that pause execution for human decisions
  • Cancel\Abort: Possibility to cancel workflow with rollback to the root step and immediate abort workflow
  • Dead Letter Queue (DLQ): Two modes for error handling - Classic Saga with rollback/compensation or DLQ Mode with paused workflow and manual recovery
  • Distributed Mode: Microservices can register only their handlers; steps without local handlers are returned to queue for other services to process
  • Priority Aging: Prevents queue starvation by gradually increasing step priority as waiting time increases
  • PostgreSQL Storage: Persistent workflow state and event logging
  • SQLite Storage: In-memory and persistent storage (unstable)
  • HTTP API: API for canceling workflows, dlq, human decision, etc.
  • Integration Tests: Fully integrated integration tests using testcontainers
  • Migrations: Embedded database migrations with go:embed

PlantUML diagrams of compensations flow: DIAGRAMS

Engine specification: ENGINE

Ecosystem

  • Pro Version includes advanced features. See more at Pro Version
  • Web UI for visualizing and managing workflows: Web UI
  • Web Manager: advanced Web UI with SSO, RBAC, etc.: Floxy Manager
  • GoLand Plugin: plugin
  • VS Code Extension: extension

Why Floxy?

Floxy is a lightweight, embeddable workflow engine for Go developers. It was born from the idea that not every system needs a full-blown workflow platform like Cadence or Temporal.

1. Lightweight, Not Heavyweight

Most workflow engines require you to deploy multiple services, brokers, and databases just to run a single flow. Floxy is different — it’s a Go library. You import it, initialize an engine, and define your workflow directly in Go code.

No clusters. No queues.

wf, _ := floxy.NewBuilder("order", 1).
    Step("reserve_stock", "stock.Reserve").
    Then("charge_payment", "payment.Charge").
    OnFailure("refund", "payment.Refund").
    Build()

That’s it — a complete Saga with compensation.

2. Pragmatic by Design

Floxy doesn’t try to solve every problem in distributed systems. It focuses on clear, deterministic workflow execution with the tools Go developers already use:

  • PostgreSQL as durable storage
  • Go’s standard net/http for API
  • Structured retries, compensation, and rollback

You don’t need to learn Cadence’s terminology. Everything is plain Go — just like your codebase.

3. Embedded

You can embed Floxy inside any Go service.

Floxy is for developers who love Go, simplicity, and control. No orchestration clusters. No external DSLs. Just workflows — defined in Go, executed anywhere.

Quick Start

package main

import (
    "context"
    "encoding/json"
    "log"
    
    "github.com/jackc/pgx/v5/pgxpool"
    "github.com/rom8726/floxy"
)

func main() {
    ctx := context.Background()
    
    // Connect to PostgreSQL
    pool, err := pgxpool.New(ctx, "postgres://floxy:password@localhost:5432/floxy?sslmode=disable")
    if err != nil {
        log.Fatal(err)
    }
    defer pool.Close()
    
    // Run database migrations
    if err := floxy.RunMigrations(ctx, pool); err != nil {
        log.Fatal(err)
    }
    
    // Create engine
    engine := floxy.NewEngine(pool)
	defer engine.Shutdown()
    
    // Register step handlers
    engine.RegisterHandler(&PaymentHandler{})
    engine.RegisterHandler(&InventoryHandler{})
    engine.RegisterHandler(&ShippingHandler{})
    engine.RegisterHandler(&CompensationHandler{})
    
    // Define workflow using Builder DSL
    workflow, err := floxy.NewBuilder("order-processing", 1, floxy.WithDLQEnabled(true)).
        Step("process-payment", "payment", floxy.WithStepMaxRetries(3)).
        OnFailure("refund-payment", "compensation").
        SavePoint("payment-checkpoint").
        Then("reserve-inventory", "inventory", floxy.WithStepMaxRetries(2)).
        OnFailure("release-inventory", "compensation").
        Then("ship-order", "shipping").
        OnFailure("cancel-shipment", "compensation").
        Build()
    if err != nil {
        log.Fatal(err)
    }
    
    // Register and start workflow
    if err := engine.RegisterWorkflow(ctx, workflow); err != nil {
        log.Fatal(err)
    }
    
    order := map[string]any{
        "user_id": "user123",
        "amount":  100.0,
        "items":   []string{"item1", "item2"},
    }
    input, _ := json.Marshal(order)
    
    instanceID, err := engine.Start(ctx, "order-processing-v1", input)
    if err != nil {
        log.Fatal(err)
    }
    
    log.Printf("Workflow started: %d", instanceID)
    
    // Process workflow steps
    for {
        empty, err := engine.ExecuteNext(ctx, "worker1")
        if err != nil {
            log.Printf("ExecuteNext error: %v", err)
        }
        if empty {
            break
        }
    }
    
    // Check final status
    status, err := engine.GetStatus(ctx, instanceID)
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Workflow status: %s", status)
}

// Step handlers
type PaymentHandler struct{}
func (h *PaymentHandler) Name() string { return "payment" }
func (h *PaymentHandler) Execute(ctx context.Context, stepCtx floxy.StepContext, input json.RawMessage) (json.RawMessage, error) {
    // Process payment logic
    return json.Marshal(map[string]any{"status": "paid"})
}

type InventoryHandler struct{}
func (h *InventoryHandler) Name() string { return "inventory" }
func (h *InventoryHandler) Execute(ctx context.Context, stepCtx floxy.StepContext, input json.RawMessage) (json.RawMessage, error) {
    // Reserve inventory logic
    return json.Marshal(map[string]any{"status": "reserved"})
}

type ShippingHandler struct{}
func (h *ShippingHandler) Name() string { return "shipping" }
func (h *ShippingHandler) Execute(ctx context.Context, stepCtx floxy.StepContext, input json.RawMessage) (json.RawMessage, error) {
    // Ship order logic
    return json.Marshal(map[string]any{"status": "shipped"})
}

type CompensationHandler struct{}
func (h *CompensationHandler) Name() string { return "compensation" }
func (h *CompensationHandler) Execute(ctx context.Context, stepCtx floxy.StepContext, input json.RawMessage) (json.RawMessage, error) {
    // Compensation logic
    return json.Marshal(map[string]any{"status": "compensated"})
}

Examples

See the examples/ directory for complete workflow examples:

  • Hello World: Basic single-step workflow
  • E-commerce: Order processing with compensation flows
  • Data Pipeline: Parallel data processing with Fork/Join patterns
  • Microservices: Complex service orchestration with multiple branches
  • SavePoint Demo: Demonstrates SavePoint functionality and rollback
  • Rollback Demo: Shows full rollback mechanism
View on GitHub
GitHub Stars130
CategoryDevelopment
Updated15d ago
Forks7

Languages

Go

Security Score

100/100

Audited on Mar 18, 2026

No findings