[erlang-questions] Replacing ets tables - renaming and race condition

Richard Carlsson richardc@REDACTED
Wed Apr 4 13:54:04 CEST 2007


Paulo Sérgio Almeida wrote:
> I work on a temporary table and then rename it to the 
> one looked up by other processes. But if I do:
> 
> Tab = ets:new(tmp, [named_table]),
> compute(Tab),
> ets:rename(tmp, used_table)
> 
> this causes an exception if used_table already exists. On the other 
> hand, if I delete the original table:
> 
> Tab = ets:new(tmp, [named_table]),
> compute(Tab),
> ets:delete(used_table),
> ets:rename(tmp, used_table)
> 
> there is the possible race of someone trying to look it up before the 
> rename. I assume this pattern must have occurred to someone. How can the 
> race be avoided?

The obvious long-term solution is that ets could use an atomic switch 
operation. Since the intention is that clients call ets:...() functions 
directly, it is also the responsibility of the ets API to provide the 
necessary primitives.

A short term solution (if you have control over the code for the 
clients) is to _not_ let them call ets directly. (But for efficiency 
reasons, you probably don't want to hide the ets tables behind a 
serialising server process.) A reasonable solution, then, is to have the 
clients access the ets tables solely through your own lookup functions, 
which implement a catch-wait-retry loop (with incremental back-off and 
some limit on the number of retries) around the actual ets calls, to 
hide the fact that once in a while the table might be missing for a 
brief moment.

     /Richard




More information about the erlang-questions mailing list