I'm trying to figure out the best way to implement a real websocket app using akka-http and akka-streams. What I'm mostly looking for is simplicity, which I'm just not getting now.
Assume you have a fairly complex pipeline which needs to discriminate between multiple requests and sometimes send the request to an actor for processing, sometimes issue a mongo query and return the response, sometimes perform a PUT on a REST API, etc.
Unlike the simple chat application examples out there, there are at least 3 problems that arise which seem to not have a standard solution:
Conditionally skipping the response, e.g., because it is not expected by the client that this request will receive a response. If I use the typical Flow from Message to Message, once the request has hit its target, I need to stop it from propagating further back to the websocket. It can be done with a special filter (involves some pain) or using various other ways (e.g., Conditionally skip flow using akka streams), but this adds a lot of boilerplate and complexity. Ideally, I'd like to be able to insert 'Skip' messages that just skip everything else.
Routing incoming messages to the appropriate place (e.g., actor, mongo). Once again, I can find solutions to that which involve a lot of boilerplate (e.g., broadcast and filter out at branches which do not handle this kind of request). Ideally, I should be able to define something like: if the message is X, send it there, if the message is Y, send it there, etc.
Propagating errors back to the client. Very similar to the routing problem described above. For example, if the JSON parse fails, I need to add a separate path (broadcast + merge) along which I send an error message, but I cannot even easily reuse the same path if an error occurs at the next stage and I want to propagate that error to the user. Ideally, I should have one single separate path for error handling that can be used at any arbitrary point in the flow, bypasses the rest of the flow entirely and goes back to the client.
At the moment, I have this insanely complex graph spanning 15 lines with paths going through >20 different stages and I'm really worried about keeping the complexity of this solution in check. The DSL is mostly unreadable at this size. I could of course modularize a bit better, but this feels like an insane amount of trouble for something that should be a lot simpler.
Am I missing something? Am I insane for considering akka-streams for such a task? Any ideas or code examples that could allow me to rein in all that complexity?
Thanks in advance!
This is a very wide-ranging question and may not be answerable in its current form.
Akka HTTP addresses many of these concerns in its HTTP handling layers (e.g. empty responses, routing, returning errors). Could you use some of the lessons learnt there and apply them to your system? Or, perhaps better, could you convert your system from using websocket communication into using HTTP communication and use that code directly?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With