stjefim
Hello!
Suppose you are building workflow (order / task / payment) processing system with the following requirements:
- Each workflow consists of several steps.
- Each step can fail (throw exception or return error) or timeout and need to be retried according to retry policy.
- State machine - choice of next step in a workflow depends on the result of the previous step.
- Durable execution - workflows and steps taken and their success or failure are persisted to DB, so that workflows are never (e.g. if server fails) lost and can be resumed from the next step.
- State visibility - Web UI to monitor workflow progress.
- Other less important requirements, e.g. auto scaling of workers executing steps, cancellation of workflows, signalling to workflows, …
I believe this system is very often required for many websites and is a good fit to Elixir, however, I believe there is no ready to use solution in Elixir and developing such a system for each website separately is a waste of time and resources. Do you agree with this statement? How would you go about developing such a system in Elixir? Writing from ground up? May be some framework I have missed?
Solutions I have considered:
- Temporal - almost ideal fit to the system requirements, however, no SDK for Elixir (unofficial SDK in development, should be ready within 2-3 months) and I believe is not an ideal fit to Elixir. I think a better solution for Elixir would be to run Service managing state and Workers executing steps together in BEAM. This would allow to e.g., leverage BEAM’s message passing, use cache inside BEAM (e.g. Cachex) and in general have less dependencies.
- Oban - provides durable execution, retries, timeouts, however, not a state machine as is made for durable background job (not workflow) processing. While at first it seems that adding state machine is not a problem at all, I believe this would require many tricks and hacks, thus, poor code clarity and poor state visibility - Oban’s Web UI is not made for this use case. E.g., I have considered using Oban Workflows with ignore_discarded, however, this required scheduling steps for both cases (previous step failed or succeeded) and creates messy code as well as poor workflow visibility.
Trending in Questions
Hello!
Suppose you are building workflow (order / task / payment) processing system with the following requirements:
Each workflow con...
New
Hey guys,
I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly
Do you guys have any suggestions what is the best prac...
New
Kia ora,
We have been using elixir-google-api to connect to Google Drive. However, with the updates to Tesla due to CVEs this is now bro...
New
Hello!
Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app.
I creat...
New
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
Hello,
I’m developing a online persistent chat system (what’s app) like using elixir/dynamodb/aws for a mobile app(flutter).
The diffic...
New
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New
Other Trending Topics
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
There are three potential reasons for members of this forum to have a look at https://vutuv.de
You are tired or annoyed of LinkedIn.
Yo...
New
ICal is a library for interacting with iCalendar data. It parses iCalendars into typed Elixir structs via ICal.from_ics, and can prepare ...
New
Latest Oban Threads
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #ai
- #phoenix_html
- #elixirconf-us
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
sorentwo
This is something we plan to fix. A dedicated workflow view is slated for Oban Web.
There’s no need to schedule separate jobs for the result of the previous job. With recorded jobs it’s simple to fetch the result from the previous step, or even to check the status of the previous step if needed. Here’s an example:
stjefim
I agree, another option is to schedule single job which handles both cases, however, in that case at the next step (3rd one) job would need to handle 4 cases (1st failed 2nd succeeded; 1st failed 2nd failed, 1st succeeded 2nd succeeded; 1st succeeded 2nd failed). On the next step 8 cases. To sum up, if state transition graph is at least a bit complex, this solution creates messy code. As well as it decreases visibility as now single job could represent completely different operations (e.g. cleanup after previous job assuming it failed, or processing of the next step assuming previous job succeeded), thus, from the look at the single job (without looking at all previous this workflow jobs) in the Web UI it is unclear what is happening.
effinbanjos
I’ve been thinking about this a bit too, having just discovered Temporal recently. I have use-cases where I think I need python workers (not just an embedded script a la Pythonx) due to library support and it seems it would be pretty nice to use the same orchestration layer - no idea what it actually feels like in practice, of course. I suppose it provides Elixir with another path for integration within heterogeneous environments.
MrDoops
I’m building something like this on top of Runic. No guarantees on when the web UI & durable execution is at a production ready state though. I have a durable runner implemented but still working on check-pointing for long running workflows. There’s also quite a bit one would normally want in this sort of thing like triggers (e.g. webhooks, messaging system integrations), CRON / time scheduled workflows, and so on.
I’d recommend Oban if you want a durable execution with graph based workflows today.
While it’s not a DAG: GitHub - commanded/commanded: Use Commanded to build Elixir CQRS/ES applications · GitHub is also this sort of thing but with DDD/CQRS abstractions.
Paulo released handoff recently which uses dags: GitHub - polvalente/handoff: Distributed graph execution in Elixir · GitHub
effinbanjos
That’s a good point about CQRS and Commanded - quite a robust native Elixir option. I hadn’t even heard of handoff - very cool looking!
dimitarvp
Hey, I wonder if you ever returned to your idea to build a visual layer on top of Runic?
MrDoops
The sweet spot in most use cases is just doing a straight workflow → graph serialization with a viz tool like Mermaid / Cytoscape / DOT e.g. Runic.Workflow — Runic v0.1.0-alpha.8
Usually just throwing this in Livebook or mermaid.live is enough to debug or document the workflow. I’ve found a read-only view in an admin panel something like this to just render the graph on a show page that shows execution history, errors, traces, etc tends to solve most problems with the least effort.
I’ve also done more on drag and drop builders and have it working pretty well on top of Liveview and Reactflow but its still specific to that app moreso than a library that I can open source. It ends up being a full app because you kind of want a component library which means you have to store components, and some components need parameters or forms to materialize so you need to persist forms in the database and do data driven validation. Then some components are only compatible with other components so there’s dataflow contracts to worry about. Then undo/redo, and some view/model separation where certain components should be rendered on the canvas different than the underlying dataflow its compiled to, etc, etc…
Frankly its a ton of work and I wonder how valuable it is from a UI ROI perspective considering how much work it is to get something usable enough to be worthwhile over editing code or having an agent write your workflow (which I’ve been doing more and more with Runic).
There’s some new Elixir libraries like GitHub - thanos/ExFlowGraph: LiveView-native node editor for Elixir · GitHub and GitHub - rocket4ce/live_flow · GitHub but I haven’t tried them yet.
I’ll probably release some tools for this with Runic eventually but haven’t been happy with the ROI or how specific the UX decisions are to the application they’re for.
I’ve actually released Runic on Hex recently (currently in alpha): it has a scheduling and execution layer with durable execution and some neat event-sourced based check-pointing and re-hydration capabilities for long running workflows so its worth checking out: runic | Hex .
webofbits
I’ve been poking at this same problem space in Squid Mesh:
It’s still early, but the shape I’m experimenting with is durable workflow runs inside an existing Phoenix/OTP app: persisted runs/steps/attempts/audit events, retries, waits, approvals, replay, cancellation, and inspection.
The boundary is somewhere between a job queue and a separate Temporal-style service. The host app still owns the repo, deployment, and queue/executor; Squid Mesh owns the workflow state and recovery/inspection bits.
Lately I’ve been moving more of the runtime toward Jido primitives: actions for step execution, agents for rebuildable workflow/dispatch coordination, and Jido journals as the durable fact log. The goal is for the runtime to be replayable from durable facts instead of treating worker/job state as the source of truth.
Also, I’ve also been experimenting with a BedrockDB-backed execution path for leases, redelivery, and recovery semantics, while keeping the workflow layer embedded in the app.
There’s also a small read-only LiveView dashboard for it:
Not production-ready, and I’m still figuring out some of the runtime boundaries, but this thread is very close to the tradeoffs I’ve been thinking about. I’d be curious if this shape matches what others have wanted from an Elixir-native workflow layer, or if I’m drawing the boundary in the wrong place.
yoavgeva
This is very close to the direction I also ended up taking with FerricStore / FerricFlow.
The boundary I wanted is also somewhere between a job queue and a Temporal-style service, but with a bit
different tradeoff.
I dont want the runtime to own all my application code like Temporal. I also dont want to keep using
queues and then build workflow state around them every time.
What I wanted was a high throughput workflow engine where:
So the model is more explicit state machine than durable code replay.
Something like:
FerricStore keeps the durable state, lease/fencing token, retry info, history, values, signals, etc.
The thing you mention around persisted runs/steps/attempts/audit events, waits, approvals, cancellation
and inspection is exactly the pain I am trying to solve too. FerricFlow also added governance concepts
now: budgets, approvals, external effect tracking, distributed limits and circuit breakers.
I already use the HA cluster in my own projects, and in my company we started using it for small stuff
also. Feedback is very positive until now, but I still see it as beta and not finished 1.0.
Current repo:
GitHub - ferricstore/ferricstore: Durable KV and workflow state engine · GitHub
Yyeger
I’ve been working a lot on GitHub - Yyeger/Continuum: OTP-native durable execution engine for Elixir. · GitHub . i would say it covers something similar, it’s also avaiable on Hex continuum | Hex .