Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tsharju/elixir_locker
https://github.com/tsharju/elixir_locker
Last synced: about 1 month ago
JSON representation
- Host: GitHub
- URL: https://github.com/tsharju/elixir_locker
- Owner: tsharju
- License: mit
- Created: 2015-05-13T12:36:41.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2015-11-26T14:31:25.000Z (about 9 years ago)
- Last Synced: 2024-10-08T09:39:50.260Z (2 months ago)
- Language: Elixir
- Size: 159 KB
- Stars: 16
- Watchers: 3
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- freaking_awesome_elixir - Elixir - Locker is an Elixir wrapper for the locker Erlang library that provides some useful libraries that should make using locker a bit easier. (Caching)
- fucking-awesome-elixir - elixir_locker - Locker is an Elixir wrapper for the locker Erlang library that provides some useful libraries that should make using locker a bit easier. (Caching)
- awesome-elixir - elixir_locker - Locker is an Elixir wrapper for the locker Erlang library that provides some useful libraries that should make using locker a bit easier. (Caching)
README
Locker
======[![Build Status](https://travis-ci.org/tsharju/elixir_locker.svg?branch=master)](https://travis-ci.org/tsharju/elixir_locker)
A quote from https://github.com/wooga/locker:
> `locker` is a distributed de-centralized consistent in-memory key-value store written in Erlang. An entry expires
> after a certain amount of time, unless the lease is extended. This makes it a good practical option for locks,
> mutexes and leader election in a distributed system.`Locker`is a Elixir wrapper for the `locker` Erlang library that provides some useful libraries that should make using `locker` a bit easier.
The `Locker` module implements an OTP application that runs `locker`. In addition to that is also provides a wrapper for the `locker` API, just for convenience.
Idea of `Locker` is to provide an abstraction for globally registering `GenServer` or `:gen_fsm` processes to `:locker` key-value store in a cluster of Erlang servers. These are implemented in `Locker.Server` and `Locker.Fsm` modules. In the simplest case, all you have to do is replace `use GenServer` with `use Locker.Server` and your process is automatically registered to global `:locker` cluster.
Installing
----------You can install `Locker` by adding it as a dependency to your project's `mix.exs` file:
```elixir
defp deps do
[
{:elixir_locker, "~> 0.1.4"}
]
end
```Also, remember to add `:elixir_locker` to your `:applications` list if you wish that the `Locker` application is started automatically.
Examples
--------### Globally registered processes
You can use `Locker` as a global process registry. The `Locker.Registry` module handles the API for registering processes in a way that `GenServer` or `:gen_fsm` can use it directly. Here is an example of an `GenServer` process that will be registered to `Locker` on startup:
```elixir
defmodule MyServer do
use Locker.Server, lease_length: 60000
def init(_) do
{:ok, %{}}
end
def handle_info(_info, state) do
{:noreply, state}
end
end
```You can start your process with name `"my_server_process"` the way you would start any `GenServer` process. For example, without supervision:
```elixir
iex> MyServer.start([], name: "my_server_process")
{:ok, #PID<0.166.0>}
```Once the process has been started, you can query the process id using `Locker.Registry` like this:
```elixir
iex> Locker.Registry.whereis_name("my_server_process")
#PID<0.166.0>
```If `Locker` cluster has been properly configured, you can query the process name from any node on your cluster. What `Locker.Server` does is that it updates the lease on the registered process name within the given `:lease_length`. If the lease expires, the process cannot be found from the registry anymore. Also, `Locker.Server` releases the registered name on `terminate/2`.
### Locking resources
It should not come as a surprise that you can use `Locker` to lock resources globally. For this, you can use `Locker` module that provides a direct mapping to the `:locker` Erlang module. Naturally, you can also use `:locker` directly. Here is how you can create a lock that expires in one minute and wait that the lock gets released.
```elixir
iex(1)> Locker.lock("my_lock", self, 60000)
{:ok, 1, 1, 1}
iex(2)> Locker.wait_for_release("my_lock", 2 * 60000)
{:ok, :released}
```So what we did here was that we registered a lock called `"my_lock"` and set the value to our own process id and timeout to 60000 milliseconds, i.e. one minute. Then we called `wait_for_release` that will block until the lock is released.