Paxtor (paxtor v0.3.0)

Paxtor is the API module of the Paxtor application.

This application provides two models of usage. For more information look at:

  1. Paxtor.lock/1
  2. Paxtor.name/2

Summary

Functions

Returns true if the process described by the argument is running, otherwise it returns false.

Acquires a cluser-wide lock for the key.

Returns the pid that belongs to the given name or it returns nil if the process has not been started, or crashed.

It returns a via tuple that can be used anywhere where a process name is adequate.

Resolves a name or name tuple to an actual pid (or port).

Functions

alive?(arg)

Returns true if the process described by the argument is running, otherwise it returns false.

If you also need to know the pid of the process, please have a look at lookup/1. Both of these functions accepts via tuples generated by name/2.

lock(key, opts \\ [])

Acquires a cluser-wide lock for the key.

It will return the atom :acquired if the lock is acquired by the caller process.

The function call will not return until the lock is acquired, unless the block: false option is given. In case the lock is not available right now, and the block: false option was used, the tuple {:held_by, pid} is returned, where pid is the process identifier of the process currently holding the lock.

Another option you can use is no_quorum: :retry.

  • :retry: silently retry as long as it takes to acquire the lock. (This is the default.)
  • :fail: crash if no quorum is available
  • :return: returns :no_quorum if there are not enough nodes available in the cluster

lookup(arg)

Returns the pid that belongs to the given name or it returns nil if the process has not been started, or crashed.

lookup does not start the process. If you want to ensure the process is running, and also get it's pid, use Paxtos.whereis instead.

name(key, child_spec, opts \\ [])

It returns a via tuple that can be used anywhere where a process name is adequate.

It does not start a process by itself, just creates a reference. In order to start the process you can make a request to it (like a GenServer.call) or you can use Paxtor.whereis(via_tuple) to ensure it is started.

Options:

  • restart: It controls whether the process will be restarted or not. Two possible atoms can be the value of it:
    1. :temporary -- the process can go down without triggering any actions. The next event call will ensure the process is started. This is the default.
    2. :permanent -- the process is restarted when it fails. If the hosting node goes down, the process is restarted on another node.

child_spec can have an option about restarts, but Paxtor does not care about it. It does not matter if you set that in the child_spec. What matters is this option. By default Paxtor starts a temporary process, which means it is never restarted, no matter if it stops normally, or fails. Permanent processes are always restarted when they exit. In Erlang/OTP there's a 3rd category called transient, which means processes are only restarted when they fail, but are not restarted when they exit normally. This is not supperted in Paxtor.

Please stick with the default option if it is possible. The restart: :permanent option makes a lot of effort to restart the child process, but most of the time it makes sense to only restart failed processes when you want to send messages to them later. This autorestart functionality is what Paxtor provides when restart: :temprary is in effect.

whereis(pid)

Resolves a name or name tuple to an actual pid (or port).

While lookup/1 and alive?/1 only accepts via tuples generated by name/2, this function accepts any kind of :via tuples, locally registered process (or port) names and also {name, node} tuples. It is a deliberate decision not to support {:global, name} tuples because:

  1. they interfere with {name, node} tuples
  2. there's no reason to use :global if you have Paxtor
  3. if you absolutely need :global, you can fall back to {:via, :global, name} and get the pid you need