Packages

Petri net analysis of Oban workflows, built on petrex. Does not depend on Oban.

Current section

Files

Jump to
petrex_oban README.md
Raw

README.md

# Petrex.Oban
Analyses Oban workflows as Petri nets, using [Petrex](https://hexdocs.pm/petrex). It takes a
plain description of a workflow — jobs, their dependencies, and the queue
limits they run under — and answers two questions before the workflow runs.
**Will it finish?** A dependency cycle is the one shape that never completes
however long it runs. Oban accepts such a workflow and leaves those jobs
pending; this names the jobs in each cycle.
```elixir
Petrex.Oban.cycles(%{
jobs: [
%{id: :fetch, deps: [:index]},
%{id: :parse, deps: [:fetch]},
%{id: :index, deps: [:parse]}
]
})
#=> [[:fetch, :index, :parse]]
```
**How much of each queue will it use?** The highest number of jobs a queue
ever runs at once, over every possible interleaving rather than one sampled
run. A limit well above that figure is workers that will sit idle for this
workflow; a queue that reaches its limit is where more capacity buys time.
```elixir
Petrex.Oban.max_concurrency(%{
jobs: [
%{id: :fetch, deps: [], queue: :network},
%{id: :thumbnail, deps: [:fetch], queue: :cpu},
%{id: :transcode, deps: [:fetch], queue: :cpu}
],
queues: %{network: 5, cpu: 8}
})
#=> {:ok, %{network: 1, cpu: 2}}
```
Eight CPU workers for a workflow that never runs more than two.
Both answers come from the analyser, so both hold for every interleaving,
and both say when a state space was too large to finish: a `{:partial,
counts}` figure is a lower bound, not a verdict. `from_workflow/1` returns
the net itself, for the rest of `Petrex.Analysis`.
## The model
Each job becomes `waiting`, `running` and `done` places with `start` and
`finish` transitions. A queue becomes a place holding as many tokens as its
limit, taken while a job runs and returned when it finishes, plus a place
counting the jobs it is running — the one whose bound `max_concurrency/2`
reports. A dependency is read rather than consumed, so any number of jobs
can depend on the same one.
The nets this package generates are cross-checked against
[TINA](https://projects.laas.fr/tina/) and
[LoLA](https://theo.informatik.uni-rostock.de/theo-forschung/tools/lola/),
like the core package's own.
## What it does not model
A job holds a queue slot only while it runs, and a running job can always
finish, so a positive queue limit slows a workflow down but cannot deadlock
it. Deadlock means an unsatisfiable dependency or a queue whose limit is
zero.
Nothing here covers what Oban does around the jobs: retries, timeouts, the
difference between a job failing and a job finishing, or workers competing
for a queue across nodes.
## Oban
This package does not depend on Oban. Producing the description from an Oban
Pro workflow is a few lines in an application that already has Oban; the
module documentation shows one.
## Installation
```elixir
def deps do
[{:petrex_oban, "~> 1.0"}]
end
```
It brings in `petrex`, which has no runtime dependencies of its own.