Packages

Flow-Based Programming with Elixir GenStage.

Current section

Files

Jump to
flowextra MIGRATION.md
Raw

MIGRATION.md

# Migrating from Flowex to FlowExtra
FlowExtra is the Factory-maintained continuation of Anton Mishchuk's
[Flowex](https://github.com/antonmi/flowex) (lineage `antonmi/flowex @ 3a9ebae`,
fork point `3ccf92e`, revived 2026). The rename is mechanical in code but
breaking at every binding site; **no compatibility modules are provided** —
the migration is explicit by design.
## Dependency
```elixir
# before (upstream's published package)
{:flowex, "~> 0.5"}
# after (the maintained fork)
{:flowextra, "~> 0.6"}
```
The fork's 0.6.0 line has not been published to hex.pm under either name;
the behavioral differences below are the effective changelog from upstream's
published 0.5.x.
## Namespace
| Flowex | FlowExtra |
| --- | --- |
| `use Flowex.Pipeline` | `use FlowExtra.Pipeline` |
| `use Flowex.Sync.Pipeline` | `use FlowExtra.Sync.Pipeline` |
| `%Flowex.Pipeline{}` struct | `%FlowExtra.Pipeline{}` |
| `Flowex.Client` | `FlowExtra.Client` |
| `Flowex.IP` | `FlowExtra.IP` |
| `Flowex.PipelineError` / `Flowex.PipeError` / `Flowex.AdmissionError` | same suffixes under `FlowExtra.` |
| `Flowex.Admission` (owner + ledger API) | `FlowExtra.Admission` |
| `Flowex.Registry` (internal process registry) | `FlowExtra.Registry` |
## Application configuration
The OTP application atom changes: `config :flowex, ...` becomes
`config :flowextra, ...`. Formatter consumers change
`import_deps: [:flowex]` to `import_deps: [:flowextra]` (the exported DSL
form is unchanged).
## Behavioral differences from upstream Flowex 0.5.x
All of these are pinned by the repository's suite:
- **Admission protocol.** The asynchronous engine bounds admitted work
(`admission_capacity`, default 100). `cast/2` acknowledges — `:ok` means
admitted and accounted — or refuses observably; outcomes carry named
certainty: `:overloaded`/`:unavailable` are definite refusals,
`{:unacknowledged, ref}` is an unknown outcome with a request identity
for inspection via `FlowExtra.Admission.report/1`.
- **One deadline per call.** Every `call/3` carries a deadline (default
5_000 ms — upstream waited forever) shared across client queueing,
admission, and execution; past the admission budget a 25 ms
acknowledgment allowance still hears a reply already on its way.
- **Supervised pipelines stop through the owner** — terminate then delete
the child spec; an intentional stop stays stopped (upstream's `:permanent`
spec resurrected it).
- **Error routing is honest.** Healthy packets skip error pipes entirely;
failed packets skip the remaining normal pipes and reach the designated
error handler. Exceptions render readable messages while keeping the
machine-readable `reason`.
- **Replies are revocable.** Calls own a process alias as the reply
destination; a late reply cannot rot in a caller's mailbox.
- **Initialization is startup work.** `init/1` runs on both engines once,
at start, in the starting caller — never per request; all declarations
are validated before any initializer runs.
- **The client is a boundary, not a liability.** `FlowExtra.Client.call/3`
raises expected request failures at the caller boundary and the reusable
client survives them; `Client.cast/2` is synchronous and returns the
pipeline's own answer instead of an unconditional `:ok`.
- **Topology failures retain permits.** No slot is reused under surviving
work; work destroyed with the topology stays admitted with an unknown
outcome until the pipeline is stopped and started again (see README,
"Admission and overload"). Upstream had no admission at all.
- **The sync engine stays a single-process debug engine**, deliberately
without admission.
## What did not change
The DSL (`pipe`/`error_pipe`, options, `count` replication), the GenStage
execution model, railway data semantics, and the Apache-2.0 license with
Anton Mishchuk's original attribution preserved.