After hacking on various Phoenix projects, I’m building my first Elixir library and would appreciate some feedback. In particular, I’m looking for advice around fault-tolerance, and on introducing supervision such that individual component crashes don’t leave invalid state.
I’ve written ElixirJanus, an Elixir interface to the Janus Web RTC Gateway. One challenge is that, when I create a Janus session, there are in essence two parts. The first is an HTTP long-poll that retrieves events from the Janus server, then dispatches them to event handlers (there is a websockets API but, for a first attempt, I thought I’d stick to long-poll.) Next are individual HTTP calls to the API, which may modify state that the long-poll needs to access. Session/handle state is stored in Agent
, and I’ve tried to keep the agent-side code as simple as possible to minimize the likelihood of crashes. So, questions:
-
When a caller creates a
Session
, it gets a pid for theAgent
containing session state. The caller is expected to treat the pid as opaque (I.e. not to get its data and access struct members.) Unfortunately, if the agent crashes, this pid would then be invalid, and all code that needs to access it would be holding onto an invalid pid. I see two possible solutions–either return something else to the client, or introduce a supervisor. The second seems like a better option, but all the supervision examples I’ve seen seem to have a static list of supervisors, and my library lets clients create arbitrary sessions. Do I want to create a supervisor per session somehow, one large supervisor to track all created sessions, or something else? -
Should I be using
GenServer
forSession
andPlugin
handles? Right now I’m just storing it all in anAgent
, but maybe usingGenServer
would be more idiomatic, or better for supervision. -
I’m using Bypass for testing. Are there any examples of using Bypass when a library needs to queue up multiple requests? In this instance, every session starts a long-poll and fires off individual requests to make session changes. Bypass seems great for APIs where a request is sent and a response received, but I need to configure several request/response patterns that will trigger during a single call, and it isn’t immediately obvious to me how to do that. I’d hoped to build out the test suite so I can do things like refactor to GenServer and experiment with more confidence.
Thanks, and any additional feedback on this first attempt at a library would be very welcome.