Hi,
I’m new to elixir - have read Elixir in Action and the Designing Systems with OTP books.
Looking to use the BEAM and all it’s goodness for a project which isn’t a server with a request/response format (which is what the books talk most about, understandably).
I have some sensors (ARTag detector, rain sensor, weather sensor, pocketlab, w/e it doesn’t matter) that generate data, and I want to build an “environment” that allows those sensor inputs to be combined and sent to an output. Each detector spits out information per frame, at around 15FPS or so.
I also have some outputs - for now, a screen and a speaker (although i also want to add some kind of persistence like a database or filesystem).
One of these detectors is linked as a “program detector” whose job it is to identify which program ids should be running in the space. So every frame, one UDP port gets packets with info about which programs are “active”. Maybe it looks like: [[id, x-position, y-position], [id, x-position, y-position]...]
if the program sensor is an ARTag detector.
Now I want to dynamically start the programs I see and run them for as long as I see them (in other words if I don’t see the program for 3-5 frames I will quit it, if it comes back i will restart it).
Each program will take in the sensor input and spit out some data to send to an output process.
This feels like a dynamic version of the producer/consumer model that GenStage allows for, with a couple differences:
- I want a “real time” Gen Stage - every stage holds onto the most recent value and when its consumer requests the next data point it gets the most recent data available (so if there’s one stage running at 2fps for some reason it will not pile up events, just get whatever is latest). i’m not interested in piping all the data through the system. the outputs should have as recent data as possible, and all messages that could not be processed are dropped. It’s like UDP in the UDP/TCP relationship I guess.
- there is a many:many relationship between inputs:programs. I’m not clear how this works with genstage. Messages have to be processed 1 at a time, and say the “program” (basically a function) needs input from more than 1 sensor in order to form its output. In the reactive world this would be accomplished by
combine_latest
or similar functionality - there is a many:many relationship between programs:outputs - each output will receive commands from many programs, how do they maintain the overall state? In this case, it may be possible to structure the output as a series of patches that can be applied.
- how does the output clean up state if the program is removed? can i send some special message from the supervisor that “cleans up” anything drawn to the screen, for example?
If elixir/erlang are the wrong tool for this kind of work then please let me know that too and what might be the right tool. Prior to reading about erlang, my main exposure to “concurrency” was as reactivex streams in frontend, which are totally different. I’m probably thinking about this backwards or something.
thank you! happy to provide any other information, samples of what inputs/programs/outputs could look like if it helps.