Rebus.Bus (rebus v0.4.0)
View SourceRequests and releases well-known bus names, such as "org.example.Calculator".
A connection to a message bus is known by its unique name, such as
":1.42", for its whole life. A service also asks the bus for a well-known
name, which clients address it by. request_name/4 asks for one and
release_name/3 gives it back. Both are calls to the bus driver,
org.freedesktop.DBus, with the driver's numeric answers turned into atoms.
Example
{:ok, conn} = Rebus.connect(:session)
{:ok, _ref} = Rebus.Service.export(conn, "/org/example/Calculator", [calculator])
{:ok, :primary_owner} = Rebus.Bus.request_name(conn, "org.example.Calculator")
receive do
{:rebus_name, ^conn, :acquired, "org.example.Calculator"} -> :ok
endExport before requesting
Export a service's objects before requesting its name. The bus announces a
new owner with NameOwnerChanged as soon as the name is granted, and a
client waiting for that, or one the bus activated, may call immediately.
The connection replies to calls on unknown paths with
org.freedesktop.DBus.Error.UnknownObject.
Ownership notices
The bus tells the owning connection when it gains or loses a name, with the
NameAcquired and NameLost signals. request_name/4 has them delivered
to its :owner, the calling process by default, as
{:rebus_name, conn, :acquired | :lost, name}A name can change hands at any time after it is requested. A connection
that asks with :replace_existing takes it from an owner that allowed
replacement, and a connection waiting in the queue gets it when the owner
releases it or disconnects. Each change arrives as a notice, so an owner
learns that it lost the name and a queued connection that it gained it.
Notices for a name continue until release_name/3 releases it, the owner
exits, or the connection closes. A first request answered :exists sets
up no notices, and requesting a name again for the same owner does not
duplicate them.
Make one request or release of a given name at a time on a connection. When two overlap, the earlier one's cleanup can stop the notices the later one set up.
Summary
Types
Failure reasons returned by request_name/4 and release_name/3.
A flag for request_name/4.
The message an owner receives when its connection gains or loses a name.
The bus's answer to release_name/3.
The bus's answer to request_name/4.
Functions
Releases the well-known name name, or leaves its queue.
Asks the bus for the well-known name name.
Types
@type error_reason() :: :invalid_name | :invalid_flags | :invalid_owner | :invalid_timeout | :not_a_bus | :invalid_bus_reply | {:bus_error, binary()} | Rebus.error_reason()
Failure reasons returned by request_name/4 and release_name/3.
:invalid_name,:invalid_flags,:invalid_ownerand:invalid_timeout- an invalid argument. Nothing was sent.:not_a_bus- the connection was opened withbus: falseand has no bus to ask. Nothing was sent.{:bus_error, error_name}- the bus refused the request, for example withorg.freedesktop.DBus.Error.AccessDeniedwhere its policy does not let this connection own the name.:invalid_bus_reply- the bus answered with something other than one of the documented values.- Any other reason is a failure of the call to the bus, as for
Rebus.call/3.:timeoutis delivery-ambiguous: the bus may have applied the request.
@type flag() :: :allow_replacement | :replace_existing | :do_not_queue
A flag for request_name/4.
:allow_replacement- let a later request with:replace_existingtake the name from this connection.:replace_existing- take the name from its current owner, if that owner allowed replacement.:do_not_queue- answer:existsrather than waiting in the queue for a name that cannot be taken now.
The message an owner receives when its connection gains or loses a name.
@type release_result() :: :released | :non_existent | :not_owner
The bus's answer to release_name/3.
:released- the connection owned the name, or waited in its queue, and no longer does.:non_existent- nobody owned the name.:not_owner- the name is owned by another connection, and this one was not in its queue.
@type request_result() :: :primary_owner | :in_queue | :exists | :already_owner
The bus's answer to request_name/4.
:primary_owner- the connection now owns the name.:in_queue- the name is owned elsewhere and the connection waits in its queue. It becomes the owner, and its owner receives an:acquirednotice, when the name comes free.:exists- the name is owned elsewhere and the connection did not queue for it.:already_owner- the connection already owned the name.
Functions
@spec release_name(pid(), binary(), keyword()) :: {:ok, release_result()} | {:error, error_reason()}
Releases the well-known name name, or leaves its queue.
The name's ownership notices end once the bus has answered, for every owner
that request_name/4 gave the connection. A :lost notice the bus sent
before its answer still arrives.
Options
:timeout- milliseconds for the whole request. Defaults to5000.
Return values
{:ok, result}- the bus's answer, arelease_result/0.{:error, reason}- seeerror_reason/0. The notices continue.
Examples
{:ok, :released} = Rebus.Bus.release_name(conn, "org.example.Calculator")
@spec request_name(pid(), binary(), [flag()], keyword()) :: {:ok, request_result()} | {:error, error_reason()}
Asks the bus for the well-known name name.
flags is a list of flag/0 values and defaults to [], which asks for
the name, queues for it if another connection owns it, and lets nobody take
it away.
Options
:owner- the local process that receives the name'sname_notice/0messages, ornilfor none. Defaults to the caller.:timeout- milliseconds for the whole request. Defaults to5000.
Return values
{:ok, result}- the bus's answer, arequest_result/0.{:error, reason}- seeerror_reason/0.
Examples
{:ok, :primary_owner} = Rebus.Bus.request_name(conn, "org.example.Calculator")
{:ok, :exists} =
Rebus.Bus.request_name(other_conn, "org.example.Calculator", [:do_not_queue])