mfclarke
Let’s say I have the following:
[A]
|
|
|
[B]
|\
| \
| \
[C] [E]
| |
| |
| |
[D] [F]
A is a list of strings
B fetches data from an API using the given string
C performs some kind of work on the data
D writes to a db
E logs errors to a webservice
F posts a message to slack if there are a lot of errors in a small time window
Is it possible to handle errors like with Flow? As in, B can output 2 types of events: data and errors. Data is consumed by C and errors are consumed by E. In GenStage I know I can use a GenStage.PartitionDispatcher with a hash function that assigns events to one partition or the other depending on if they are regular data or errors. But I’m wondering if this is possible within the Flow API?
The best I can come up with is that B would send messages to a producer stage on error, which would be the start of a separate Flow (that consists of E and F). Is there a cleaner way?
Trending in Questions
Other Trending Topics
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
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #phoenix_html
- #iex
- #ai
- #graphql
- #genstage
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex











Showing Posts 1 to 3- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
mfclarke
I’ve been thinking about this a bit and come up with something I like, so I’m gonna answer my own question here in case other people run into this.
So, there’s 2 things to know. This is demand driven and I’m trying to utilise backpressure to avoid a build up of data when the next step in the flow is busy. By it’s very nature, if
So,
Cis busy andEhas run out of stuff to process,Ecan’t demand more data. Because there’s no way of knowing ifBwill produce data forCorE,Basking for demand could just add a build up of data onCeven thoughCis trying to apply backpressure to avoid that in the first place. Put simpler: you can’t ask an API (B) for errors (E)CandEmay as well be the same step so to speak. There’s no branch, at least ask far as Flow is concerned.Then how does the right data get to
CandE? This is the second thing. I makeBoutput “tagged tuples” like{:ok, data}and{:error, data}. This wayCandEcan pattern match to receive the data relevant for them. As long as they include a “pass through” default pattern match, the data for later steps flows down. So if you arrange the stepsA→B→C→EwithCpassing through (or “ignoring”){:error, data}s, then the data makes it toE. PutD→Fon the end and ensure they also passthrough and you’re done.It looks something like this (removing partitioning and simplifying to all
maps):There’s also different ways of arranging the overlapping steps. Like, if it’s really important that errors propagate to your services quickly, you’d arrange it
A→B→E→F→C→Dso thatCandDcan’t hold upEandF. And vice versa.I’m starting to wonder if there’s a way of abstracting this structure up into Flow. Like extending
mapand it’s friends to take an atom, and Flow handles the pattern matching and passthrough for you. Hmm.mfclarke
Actually, yes, abstracting this higher is possible and really straightforward:
Then we can go:
Then there’s no modifications for passthrough or tag pattern matching needed on the actual work modules.
justincjohnson
FWIW, I came to a similar conclusion separately at Handling errors in Flow using :ok, :error tuples, though yours is cleaner and allows the error handling to be pushed to the end of the flow. If you’ve come up with any other approaches or insights on Flow error handling I’d love to hear. Thanks.