flowkit

package module
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 4, 2026 License: MIT Imports: 2 Imported by: 0

README

Flowkit

Flowkit is a Go library for running expensive, repeatable work over a list of inputs — safely. If you have a batch of items and you need to call a slow function on each one (an LLM, an embeddings API, a parser, a transformer), Flowkit gives you the boring-but-critical production concerns for free:

  • Bounded concurrency — run N items at a time, not all at once.
  • Preserved input orderresults[i] always matches inputs[i].
  • Durable caching — completed items are saved to disk (or MySQL, or memory); re-running the same inputs is instant and free. "Resume" just means re-running and getting cache hits.
  • Budgets and rate limits — cap total spend and calls/sec; retries pay admission too, so a flaky endpoint can't silently escape your ceiling.
  • Retries with error classification — retry transient failures (HTTP 429/5xx), treat malformed responses as data, and fail fast on fatal errors.
  • Per-item failure policy — kill the run, quarantine the bad item as data, or drop it with a visible count.
  • Typed pipelines — compose steps that stream item-by-item.
  • Reports — cache hits/misses, work calls, retries, spend, and usage meters per step.

Stability: Flowkit is a v0.x library. Its on-disk cache format is compatibility-sensitive (it preserves the pre-extraction rag-ttc-execution-cache/v1 schema), but public APIs may evolve before v1.

What Flowkit is not

Flowkit is not a workflow engine, a DAG scheduler, or a distributed coordinator. It keeps no persisted control state. There is no database of "which step is running." Durability means memoization: each completed item is saved under a content-addressed key, so if a process dies you lose at most the one item each worker was mid-flight on, and everything else replays from cache.

The two-layer mental model

Flowkit is split into two packages you can adopt independently:

                 your application / provider adapters
                          |
          +---------------+---------------+
          |                               |
   flow (typed steps)            execution (mechanics)
   - Step[I,O] + Run             - Map (bounded parallelism)
   - Identity + Policy            - FileCache / MySQLCache
   - Pipe2/3/4 pipelines          - Budget / TokenBucket / Chain
   - Bulk / Batched              - MapCached / MapCachedBatches
   - Retry + Classifier           - ResourcePlan preflight
   - Report / Meter / Ledger
          |                               |
          +---------------+---------------+
                          |
                 internal/* (digest, json, fs)
  • execution is a toolbox of small, focused primitives. You can grab just Map for bounded parallelism, or just FileCache for memoization, without buying into any opinionated model.
  • flow is an opinionated layer that combines those mechanics behind one typed Step[I, O]. A step bundles what identifies the work (its cache key), how it runs (workers, retry, admission, failure mode), and what it does (the function). Use this when a unit of work needs caching + retry + policy together.

Install

go get github.com/go-go-golems/flowkit@latest

30-second tour

Bounded parallelism (execution.Map) — run a function over items, at most Workers at a time, results in input order:

results, err := execution.Map(ctx, []int{1, 2, 3, 4},
    execution.MapOptions[int]{Workers: 2},
    func(_ context.Context, v int) (int, error) { return v * v, nil })
// results = [1 4 9 16]

A cached, retryable step (flow.Step + flow.Run) — identity controls reuse, policy controls execution:

step := flow.Step[Request, Response]{
    Name: "summarize",
    Identity: flow.Identity[Request]{
        Kind: "summary", Version: "v2",
        Key: func(r Request) ([]byte, error) { return json.Marshal(r) },
    },
    Policy: flow.Policy{
        Workers: 4,
        Retry:   flow.RetrySpec{Attempts: 3},
        OnError: flow.Quarantine,
    },
    Do: summarize,
}
results, report, err := flow.Run(ctx, step, requests, flow.Options{Store: cache})

The first run computes and stores each result; the second run is all cache hits. Duplicate inputs in one run execute once and fill every matching position. A cache hit costs zero admission budget.

Run the examples

This repository ships runnable, verified examples in scripts/ — each is a Go Example function with a checked // Output: block:

go test ./scripts/ -v          # run and verify every example
go test ./scripts/ -run ExampleMapCached -v   # one example

They cover: bounded map, budget+rate chains, durable cache-and-resume, fail-closed corruption, cached/uncached steps, duplicate suppression, retry + classification, all three failure modes, admission budgets, the monetary preflight, shared budgets, streaming pipelines, Bulk, Batched (group + repair), metering, the event ledger, and a custom Store swap.

There is also one complete, runnable end-to-end program in examples/full-run — it wires a cached, retryable, budgeted step against an on-disk FileCache and runs it twice so you can watch "resume = replay", retry, and quarantine happen:

go run ./examples/full-run

The relationship between the two example homes is deliberate:

  • examples/one complete, runnable main() program that ties the whole story together (go run ./examples/full-run).
  • scripts/ — the exhaustive, verified per-API reference (go test ./scripts/ -v), with checked // Output: blocks.

The one invariant that makes everything work

A step's Identity (cache key) is kept strictly separate from its Policy (how it runs). Workers, Retry, Admission, and Budget never affect the cache key — only Kind, Version, and the exact semantic input bytes do. That discipline is what makes replays byte-exact: change the model or prompt and you get a new key (correct); change the worker count and you get cache hits (also correct).

Choosing the right API

You want… Use
Bounded ordered parallelism execution.Map
Per-item durable memoization execution.MapCached
Batched misses, per-item cache entries execution.MapCachedBatches
Finite spend / rate admission execution.Budget, TokenBucket, Chain
Cached work + retries + item policy flow.Step + flow.Run
Typed streaming stages flow.Pipe2 / Pipe3 / Pipe4
One provider call for many cache misses flow.Bulk
Group response with missing-item repair flow.Batched
Swap the durable storage implement flow.Store (2 methods)

Live progress

Configure a flow.Reporter to receive deep-cloned initial, periodic, and terminal snapshots without parsing logs. Exact item and lifecycle events remain available through flow.Ledger; configured sink failures fail closed.

options := flow.Options{
    Reporter: flow.ReporterFunc(writeSnapshot),
    ReportInterval: 2 * time.Second,
}
results, report, err := flow.Run(ctx, step, inputs, options)

Run the complete example with go run ./examples/progress-reporter.

Documentation

Compatibility contract

The durable cache retains the pre-extraction rag-ttc-execution-cache/v1 schema so moving module paths does not invalidate expensive work. Existing entries validate their full key, value digest, strict JSON shape, and size. Corrupt existing entries fail closed (return ErrCorruptCache) rather than recomputing silently.

Flowkit must not import ragkit. A repository boundary test enforces this direction:

ragkit adapters -> flowkit/flow -> flowkit/execution -> flowkit/internal/*

Development

gofmt -w ./execution ./flow ./internal ./examples ./scripts
GOWORK=off go test ./... -count=1
GOWORK=off go test -race ./... -count=1
GOWORK=off go vet ./...
make ci-check

When changing cache identity or persistence, update compatibility fixtures deliberately. When changing concurrent execution, run race tests and verify order, admission rollback, duplicate suppression, and commit-after-cancellation behavior.

License

See LICENSE.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DocFS embed.FS

DocFS embeds Flowkit's help/documentation markdown sections (the docs/ directory). It is loaded into the Glazed help system during CLI initialization so that `flowkit help` and `flowkit help export` work.

See cmd/flowkit/main.go.

Functions

func AddDocToHelpSystem

func AddDocToHelpSystem(hs *help.HelpSystem) error

AddDocToHelpSystem loads Flowkit's embedded help sections into hs.

Types

This section is empty.

Directories

Path Synopsis
cmd
flowkit command
examples
full-run command
Command full-run is a single, end-to-end Flowkit program: it builds a cached, retryable, budgeted step over a durable on-disk FileCache, runs it twice, and prints the report so you can see "resume = replay" happen.
Command full-run is a single, end-to-end Flowkit program: it builds a cached, retryable, budgeted step over a durable on-disk FileCache, runs it twice, and prints the report so you can see "resume = replay" happen.
Package execution provides small, reusable concurrency, admission, and recoverable-work controls.
Package execution provides small, reusable concurrency, admission, and recoverable-work controls.
Package flow is the one typed step/pipeline layer over pkg/execution: it unifies bounded parallelism, fail-closed admission, retry with error classification, content-addressed per-item caching, batching-with-repair, per-item failure policy, exact lifecycle journaling, and immutable live progress snapshots behind a single Step type.
Package flow is the one typed step/pipeline layer over pkg/execution: it unifies bounded parallelism, fail-closed admission, retry with error classification, content-addressed per-item caching, batching-with-repair, per-item failure policy, exact lifecycle journaling, and immutable live progress snapshots behind a single Step type.
internal
digest
Package digest provides the stable SHA-256 operation used by Flowkit cache identities.
Package digest provides the stable SHA-256 operation used by Flowkit cache identities.
testsupport/mysqltest
Package mysqltest provides a disposable MySQL integration-test environment.
Package mysqltest provides a disposable MySQL integration-test environment.
Package examples holds runnable, verified examples of the Flowkit public API.
Package examples holds runnable, verified examples of the Flowkit public API.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL