Hacker News new | past | comments | ask | show | jobs | submit login

What I find amusing about this is that raw receives are actually kind of frowned upon in the Erlang community, but the creator is still using them, and the language is still kind of beautiful and cool.

This isn't in any way to talk negative about Joe Armstrong or Erlang, but more to show how cool the language is: even non-idiomatic code scales and is wonderful.




Slightly tangential, but, I think it's more not using gen* in a supervisor hierarchy is frowned upon. Using raw receives within ~that~ sometimes is the right solution.

For instance, I had an instance where I needed to serialize requests out to an external piece of hardware. Various user or system events would determine hardware control events that needed to be sent out, and then responses needed to be listened for to determine if they were successful or not, and return that error the user. Essentially an asynchronous, but serial, process. I had a gen_server to synchronize access to the hardware.

Now, the way I implemented this was, with each call that came into the gen_server, I'd send a message via gen_tcp, and then listen for the response as a raw receive inside of the same call. The alternative, to stay in the gen_* structure, would have been to send and finish, and then handle the response in the handle_info (since gen_* is coming back as a raw message). But that would have allowed more sends to occur in between the initial send and getting a response back, which would break the serialization we needed to ensure, and would have lost the reference to who had sent the initial request (since I was reusing the socket, and the acknowledgements from the hardware didn't include any sort of session), making it impossible for me to respond properly to the original caller.

So with a raw receive in there, it effectively became like a 'become' server, in that at the top it was a gen_server that implemented a gen_tcp "send" server, and then after sending it temporarily took on the characteristics of a gen_tcp "listen" server via a raw request (though obviously it was listening on the socket even before sending), before reverting back to the "send" server that waited for the next thing to send.

In fact, as I recall, while we were serializing our sends, there were certain types of events being broadcast by the hardware that we needed to drop even in the raw receive, so it was recursive. That is, our send server became a listen server, and stayed as a listen server until either we got the response we wanted, or a timeout was hit, at which point we'd revert back to the send server.


This is exactly how we are using a raw `receive` in one of our production systems -- multiple asynchronous, but serial within, processes.

Thanks for sharing this. It gives me more confidence in what we have done!




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: