The etsmgr application

Copyright © 2019 Fred Youhanaie

Version: 0.1.0

Authors: Fred Youhanaie (


etsmgr is a simple application that can act as the heir for ETS tables owned by other applications/processes. This allows the table owners to crash and restart without loosing the data stored in the table.

The implementation is inspired by the two blog posts from Steve Vinoski:

While adapting and embedding DeadZen's implementation , as referenced in the second article, would have sufficed, it was felt that a more generic and reusable approach would help future projects.


etsmgr can manage multiple ETS tables for multiple client processes.

Multiple instances of etsmgr can co-exist on the same node by starting the etsmgr applications with unique instance names.

An instance of etsmgr can run as a standalone application, or be embedded within the supervision tree of another application. The former allows a single server to look after tables belonging to independent applications, while the latter will let applications to have their own table manager.

A client can request etsmgr to take an ETS table under management with the new_table/3,4 or add_table/2,3 calls. The client will then use del_table/1,2 when table management is no longer required.

Internally, an instance of the etsmgr server maintains a directory of client pids and ETS table ids. We always use ETS table ids, even for named ETS tables. The directory entries will be indexed by a unique (within the instance) name supplied by the client.

If a client process with a table managed by etsmgr crashes/terminates, the table will not be lost. Once the client restarts, it can ask etsmgr for the ownership of the table.

If etsmgr crashes, and provided that the client has the trap_exit flag set, it will receive an EXIT message with the process id of etsmgr. This should trigger a mechanism within the client to reregister its ETS table(s) with the new instance of etsmgr as soon as the server restarts.

If the client does not set the trap_exit flag, then it will terminate as soon as etsmgr terminates. However, not setting trap_exit would be very unusual in an application that cares about resilience!

It is up to the client software on how to wait and/or check for the recovery of etsmgr. A single helper function, wait4etsmgr, has been provided for a very simple scenario.

If a client terminates without deleting its ETS table(s), etsmgr will inherit the managed client table(s) and keep the data alive until the client restarts, or etsmgr itself terminates. Hence, it is important for the client to delete the ETS table(s) prior to normal termination.

Simple operation

  1. An application (the client) starts, we assume etsmgr is already running.
  2. The client calls new_table, which
  3. The client needs the manager's pid in case the manager crashes
  4. Note that the client will also receive an ETS-TRANSFER message.
  5. Once the client has finished, it calls del_table, and deletes the table.

Client restart

  1. As with the simple case above, but at some point the client crashes, and in due course restarts.
  2. Following the client termination, etsmgr will receive the EXIT message and update its internal state for the table(s) owned by the client.
  3. The client restarts, and calls new_table for its table(s).
  4. etsmgr will see that the table entry already exists, and subject to some further checks, it will give the table to the client.
  5. etsmgr does not distinguish between a client that has recovered from a crash and a client that happens to have chosen the same table name as an existing application, hence the above checks to ensure there are no obvious conflicts.

etsmgr crashes

  1. As with the second case, but instead of the client it's the etsmgr server that crashes, and restarts.
  2. The client will receive an EXIT message, and should wait for the etsmgr server to come back up.
  3. Once etsmgr is back up, the client calls add_table, so that etsmgr can continue managing the ETS table.


The application consists of the following components

etsmgrclient API module
etsmgr_appThe main application for the standalone version
etsmgr_srvThe main gen_server managing the ETS tables
etsmgr_supThe supervisor managing the etsmgr_srv server.

For standalone mode, all four components are used. It is just a matter of ensuring that the etsmgr application is started with or before the client application.

For embedded mode, the main server, etsmgr_srv, can be put under the supervision of the client application's supervisor. The embedding can be done with or without the etsmgr_sup supervisor.

The client module, etsmgr, is used in both modes to communicate with the table manager.


The main component of etsmgr is the gen_server, etsmgr_srv. Below are the functions for accessing the services of the manager. There are two variants of each function, one for the unnamed instance, and one for a named instance.


This will create a new ETS table, and the manager will link to the client process. We expect this call to be made when the client has started, or restarted following a crash. In the latter case we would expect the manager to be aware of the entry. On successful completion, the client will be the owner of the ETS table, and etsmgr_srv will be the heir.


This is similar to new_table, except it will not create a new ETS table, but start managing an existing ETS table. We expect this call when a client prefers to create the ETS table itself, or when the manager has crashed and restarted and the client is reestablishing the arrangement. On successful completion, the client will be the owner of the ETS table, and etsmgr_srv will be the heir.


This call is used when the client no longer needs a table to be managed, such as prior to termination. It will be up to the client to delete the ETS table.


This is a helper function that can be used by the client to ensure etsmgr is up and running, either at start up or following the unexpected termination of etsmgr. The function will block until etsmgr is available.


This will return the tables currently under management as a map of maps, or an empty map.

Generated by EDoc