I want to verify a theory I have about what at first struck me as unexpected behaviour.
Let’s say I have a single process broadcasting messages A, B and C, in that order, onto a channel with a few socket clients listening. Since the messages are sent from the same process, their order should be guaranteed within the BEAM. Now, say that message B is being intercepted (
intercept ["B"]) and has an associated
handle_out/3 clause in the corresponding channel module, which modifies the payload slightly before sending it away using
push/3. Can this affect the ordering of the messages? That is, while B was broadcasted before C, the modifed message is pushed onto the socket from within
handle_out/3 only after message C, meaning that C can arrive to the client prior to (the modified) message B.
I would expect that this can happen. Intercepts prevent fastlaneing, which essentially means a message is encoded once and sent to all sockets directly. So the channel process itself might not even be involved for any non intercepted messages.
This is correct. The transport process receives the fastened messages, so if you intercept in the channel process, you are concurrently running alongside the transport and anything fastened in the meantime (you may take arbitrary amount of time to handle_out the message) is going to be sent before your intercepted message. If you have several events that must be ordered then you’d need to intercept those as well which would guarantee ordering.
Thanks for confirming this!
And simply intercepting message C also is an appropriate solution, which I hadn’t thought of. I know intercepting introduces overhead, but it’s probably less-so than the solution I had in mind.