basho/riak_api — pull request #15 by seancribbs (2012-10-23 02:59:11+00:00)
Title: Convert registration process to use ets

Our previous strategy for (de-)registration used the application environment and a dict to store the mappings from message codes to service modules. This became problematic when the node is shutting down because you can't set the appenv at that time.

We already serialize changes to this state through a gen_server process, so there's no reason why it can't manage the state itself, rather than in the application environment. To make this happen, a few [process-gymnastics are needed](http://steve.vinoski.net/blog/2011/03/23/dont-lose-your-ets-tables/).

1. On application startup, the ets table is created by a new process `riak_api_pb_registration_helper` that serves solely as the table heir. The ets options allow read-only concurrent access from multiple processes. This simplifies management of message-code/service mappings and reduces the memory usage of each connection process (fewer dicts).
2. When the registrar crashes, the helper will inherit the table. On (re-)start, the registrar will request the table from the helper, at which point the helper will give away the table to the new registrar.
3. When the helper crashes, the heir setting on the table is nullified automatically by the emulator. On restart, the helper will attempt to create the table if it does not exist, or otherwise ask the registrar to become the heir.
4. The `services/0` and `dispatch_table/0` functions were removed from riak_api_pb_service as they are no longer necessary. `services/0` was added to `riak_api_pb_registrar`.
5. For additional safety, deregistration is wrapped in a try/catch so that if the registrar has already shut down, the `noproc` exit is silently ignored.