Operations for Laravel
Durable, multi-step operations for Laravel. Track a deploy, a provisioning run or an import as a first-class record with a strict state machine, per-step progress, idempotent retries and a stall sweep, instead of a black-box job.
Operations for Laravel is the engine behind long-running background work. Track a deploy, a provisioning run or an import as a first-class record with a strict state machine, per-step progress, idempotent retries and a stall sweep, instead of a black-box job. Background work that spans several steps usually collapses to a single job with no visible progress and no way to tell stuck from slow. This gives that work an auditable status, per-step timing, and a deadline so a crashed worker self-heals into a terminal failed rather than a stuck running forever.
What It Does
Strict State Machine
An operation moves pending to running to completed or failed. Illegal transitions throw, terminal states never move, and the status is auditable at every point.
Per-Step Progress
Declare the steps up front and advance them one by one. Each step carries its own timing, so a client can see exactly where a multi-step run is rather than a single opaque job.
Idempotent Retries
Re-running a step or a completion is a safe no-op, so at-least-once workers never double-apply. Retries are safe by construction, not by luck.
Stall Sweep
Give an operation a deadline. The operations:sweep-stalled command moves anything past its deadline to failed, so a crashed worker self-heals instead of leaving a run stuck forever.
Live Progress, No Polling
Every change dispatches an OperationUpdated event, a plain Laravel event you wire to your own transport, so a client can watch progress live without polling.
Dogfooded Testing
Ships InteractsWithOperations and FakeOperations. Fake the engine in your own suite and assert an operation started, advanced or completed, the same way you test mail.
A deadline that self-heals
Pass expiresAt when you start an operation and schedule operations:sweep-stalled to run every minute. A run that blows past its deadline is swept to failed automatically, so a stuck running state cannot linger after a worker dies mid-flight.
Contracts, not a concrete manager
Depend on the Operations contract, never the concrete manager, so you can decorate it and tests can swap the bundled fake. The state machine is deny-by-default: illegal transitions throw and terminal states are final. It is tenancy-agnostic, tenant_id is an optional column the package simply persists, bring your own scoping, and broadcast-agnostic, OperationUpdated is a plain event you route to whatever transport drives your live UI.