EtsLock
EtsLock is an Elixir library for acquiring exclusive locks on data in ETS tables.
Using with_ets_lock/4, you can process all {key, value} tuples for a
given key while being sure other processes using with_ets_lock/4
are not mutating the data stored for this key.
Processing is performed in a separate process so that an execution
timeout (:exec_timeout) can be enforced.
For high concurrent performance, all locks are stored in a separate ETS table, and no GenServers or other processes are used to coordinate access. This is in contrast to the erlang-ets-lock library, which uses a single GenServer to serialize access to ETS.
Docs
Full documentation is available on Hexdocs.pm.
Example usage
iex> table = :ets.new(:whatever, [:set, :public])
iex> spawn(fn ->
...> ## Wait 50ms, try to acquire lock, then insert
...> Process.sleep(50)
...> EtsLock.with_ets_lock(table, :key, fn _ ->
...> :ets.insert(table, {:key, :yup})
...> end)
...> end)
iex> spawn(fn ->
...> ## Acquire lock immediately, hold it for 100ms, then insert
...> EtsLock.with_ets_lock(table, :key, fn _ ->
...> Process.sleep(100)
...> :ets.insert(table, {:key, :nope})
...> end)
...> end)
iex> Process.sleep(200)
iex> :ets.lookup(table, :key)
[{:key, :yup}]Options
:wait_timeout- Milliseconds to wait when acquiring a lock. Default 5000. Set to:infinityto try forever to acquire a lock.:exec_timeout- Milliseconds to allowfunto hold the lock before its execution is cancelled and the lock is released. Default 5000. Set to:infinityto hold the lock indefinitely untilfunhas finished.:fail_timeout- Milliseconds to wait before forcibly deleting a lock after it should have been released, but wasn't. Default 1000. Provides protection against permanently hanging locks in the case that both the caller and the spawned task crash. Set to:infinityto disable this protection (not recommended).:spin_delay- Milliseconds to wait between every attempt to acquire a lock. Default 2.:lock_table- ETS table in which to store locks. DefaultEtsLock.Locks.
Installation
Add ets_lock to your list of dependencies in mix.exs:
def deps do
[
{:ets_lock, "~> 0.2.0"}
]
endAuthorship and License
EtsLock is copyright 2019, Appcues, Inc.
EtsLock is released under the MIT License, available at LICENSE.txt.