Skip to content
This repository
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 1232 lines (417 sloc) 31.768 kb

Module gproc

Module gproc

Extended process registry
This module implements an extended process registry.

Behaviours: gen_server.

Authors: Ulf Wiger (ulf.wiger@erlang-consulting.com).

Description

For a detailed description, see erlang07-wiger.pdf.

Tuning Gproc performance

Gproc relies on a central server and an ordered-set ets table. Effort is made to perform as much work as possible in the client without sacrificing consistency. A few things can be tuned by setting the following application environment variables in the top application of gproc (usually gproc):

  • {ets_options, list()} - Currently, the options {write_concurrency, F} and {read_concurrency, F} are allowed. The default is [{write_concurrency, true}, {read_concurrency, true}]
  • {server_options, list()} - These will be passed as spawn options when starting the gproc and gproc_dist servers. Default is []. It is likely that {priority, high | max} and/or increasing min_heap_size will improve performance.

Data Types

context()

context() = {scope(), type()} | type()

{'all','all'} is the default

headpat()

headpat() = {keypat(), pidpat(), ValPat}

key()

key() = {type(), scope(), any()}

keypat()

keypat() = {sel_type() | sel_var(), l | g | sel_var(), any()}

pidpat()

pidpat() = pid() | sel_var()

sel_var() = DollarVar | '_'.

reg_id()

reg_id() = {type(), scope(), any()}

scope()

scope() = l | g

l = local registration; g = global registration

sel_pattern()

sel_pattern() = [{headpat(), Guards, Prod}]

sel_scope()

sel_scope() = scope | all | global | local

sel_type()

sel_type() = type() | names | props | counters | aggr_counters

type()

type() = n | p | c | a

n = name; p = property; c = counter; a = aggregate_counter

unique_id()

unique_id() = {n | a, scope(), any()}

Function Index

add_global_aggr_counter/1 Registers a global (unique) aggregated counter.
add_global_counter/2 Registers a global (non-unique) counter.
add_global_name/1 Registers a global (unique) name.
add_global_property/2 Registers a global (non-unique) property.
add_local_aggr_counter/1 Registers a local (unique) aggregated counter.
add_local_counter/2 Registers a local (non-unique) counter.
add_local_name/1 Registers a local (unique) name.
add_local_property/2 Registers a local (non-unique) property.
audit_process/1
await/1 Equivalent to await(Key, infinity).
await/2 Wait for a local name to be registered.
cancel_wait/2
default/1
first/1 Behaves as ets:first(Tab) for a given type of registration object.
get_env/3 Equivalent to get_env(Scope, App, Key, [app_env]).
get_env/4 Read an environment value, potentially cached as a gproc_env property.
get_set_env/3 Equivalent to get_set_env(Scope, App, Key, [app_env]).
get_set_env/4 Fetch and cache an environment value, if not already cached.
get_value/1 Read the value stored with a key registered to the current process.
give_away/2 Atomically transfers the key From to the process identified by To.
goodbye/0 Unregister all items of the calling process and inform gproc to forget about the calling process.
info/1 Similar to process_info(Pid) but with additional gproc info.
info/2 Similar to process_info(Pid, Item), but with additional gproc info.
last/1 Behaves as ets:last(Tab) for a given type of registration object.
lookup_global_aggr_counter/1 Lookup a global (unique) aggregated counter and returns its value.
lookup_global_counters/1 Look up all global (non-unique) instances of a given Counter.
lookup_global_name/1 Lookup a global unique name.
lookup_global_properties/1 Look up all global (non-unique) instances of a given Property.
lookup_local_aggr_counter/1 Lookup a local (unique) aggregated counter and returns its value.
lookup_local_counters/1 Look up all local (non-unique) instances of a given Counter.
lookup_local_name/1 Lookup a local unique name.
lookup_local_properties/1 Look up all local (non-unique) instances of a given Property.
lookup_pid/1 Lookup the Pid stored with a key.
lookup_pids/1 Returns a list of pids with the published key Key.
lookup_value/1 Lookup the value stored with a key.
lookup_values/1 Retrieve the {Pid,Value} pairs corresponding to Key.
mreg/3 Register multiple {Key,Value} pairs of a given type and scope.
munreg/3 Unregister multiple Key items of a given type and scope.
nb_wait/1 Wait for a local name to be registered.
next/2 Behaves as ets:next(Tab,Key) for a given type of registration object.
prev/2 Behaves as ets:prev(Tab,Key) for a given type of registration object.
reg/1 Equivalent to reg(Key, default(Key)).
reg/2 Register a name or property for the current process.
select/1 Equivalent to select(all, Pat).
select/2 Perform a select operation on the process registry.
select/3 Like select/2 but returns Limit objects at a time.
select_count/1 Equivalent to select_count(all, Pat).
select_count/2 Perform a select_count operation on the process registry.
send/2 Sends a message to the process, or processes, corresponding to Key.
set_env/5 Updates the cached value as well as underlying environment.
set_value/2 Sets the value of the registeration entry given by Key.
start_link/0 Starts the gproc server.
table/1 Equivalent to table(Context, []).
table/2 QLC table generator for the gproc registry.
unreg/1 Unregister a name or property.
unregister_name/1 Equivalent to unreg / 1.
update_counter/2 Updates the counter registered as Key for the current process.
where/1 Returns the pid registered as Key.
whereis_name/1 Equivalent to where / 1.

Function Details

add_global_aggr_counter/1

add_global_aggr_counter(Name) -> any()

Equivalent to reg({a, g, Name}).

Registers a global (unique) aggregated counter.

add_global_counter/2

add_global_counter(Name, Initial) -> any()

Registers a global (non-unique) counter. @equiv reg({c,g,Name},Value)

add_global_name/1

add_global_name(Name) -> any()

Registers a global (unique) name. @equiv reg({n,g,Name})

add_global_property/2

add_global_property(Name, Value) -> any()

Registers a global (non-unique) property. @equiv reg({p,g,Name},Value)

add_local_aggr_counter/1

add_local_aggr_counter(Name) -> any()

Equivalent to reg({a, l, Name}).

Registers a local (unique) aggregated counter.

add_local_counter/2

add_local_counter(Name, Initial) -> any()

Registers a local (non-unique) counter. @equiv reg({c,l,Name},Value)

add_local_name/1

add_local_name(Name) -> any()

Registers a local (unique) name. @equiv reg({n,l,Name})

add_local_property/2

add_local_property(Name, Value) -> any()

Registers a local (non-unique) property. @equiv reg({p,l,Name},Value)

audit_process/1

audit_process(Pid::pid()) -> ok


await/1

await(Key::key()) -> {pid(), Value}


Equivalent to await(Key, infinity).

await/2

await(Key::key(), Timeout) -> {pid(), Value}
  • Timeout = integer() | infinity

Wait for a local name to be registered. The function raises an exception if the timeout expires. Timeout must be either an interger > 0 or 'infinity'. A small optimization: we first perform a lookup, to see if the name is already registered. This way, the cost of the operation will be roughly the same as of where/1 in the case where the name is already registered (the difference: await/2 also returns the value).

cancel_wait/2

cancel_wait(Key, Ref) -> any()

default/1

default(X1) -> any()

first/1

first(Context::context()) -> key() | '$end_of_table'


Behaves as ets:first(Tab) for a given type of registration object.

See http://www.erlang.org/doc/man/ets.html#first-1. The registry behaves as an ordered_set table.

get_env/3

get_env(Scope::scope(), App::atom(), Key::atom()) -> term()


Equivalent to get_env(Scope, App, Key, [app_env]).

get_env/4

get_env(Scope::scope(), App::atom(), Key::atom(), Strategy) -> term()
  • Strategy = [Alternative]
  • Alternative = app_env | os_env | inherit | {inherit, pid()} | {inherit, unique_id()} | init_arg | {mnesia, ActivityType, Oid, Pos} | {default, term()} | error

Read an environment value, potentially cached as a gproc_env property.

This function first tries to read the value of a cached property, {p, Scope, {gproc_env, App, Key}}. If this fails, it will try the provided alternative strategy. Strategy is a list of alternatives, tried in order.
Each alternative can be one of:

  • app_env - try application:get_env(App, Key)
  • os_env - try os:getenv(ENV), where ENV is Key converted into an uppercase string
  • {os_env, ENV} - try os:getenv(ENV)
  • inherit - inherit the cached value, if any, held by the parent process.
  • {inherit, Pid} - inherit the cached value, if any, held by Pid.
  • {inherit, Id} - inherit the cached value, if any, held by the process registered in gproc as Id.
  • init_arg - try init:get_argument(Key); expects a single value, if any.
  • {mnesia, ActivityType, Oid, Pos} - try mnesia:activity(ActivityType, fun() -> mnesia:read(Oid) end); retrieve the value in position Pos if object found.
  • {default, Value} - set a default value to return once alternatives have been exhausted; if not set, undefined will be returned.
  • error - raise an exception, erlang:error(gproc_env, [App, Key, Scope]).

While any alternative can occur more than once, the only one that might make sense to use multiple times is {default, Value}.

The return value will be one of:

  • The value of the first matching alternative, or error eception, whichever comes first
  • The last instance of {default, Value}, or undefined, if there is no matching alternative, default or error entry in the list.

The error option can be used to assert that a value has been previously cached. Alternatively, it can be used to assert that a value is either cached or at least defined somewhere, e.g. get_env(l, mnesia, dir, [app_env, error]).

get_set_env/3

get_set_env(Scope::scope(), App::atom(), Key::atom()) -> term()


Equivalent to get_set_env(Scope, App, Key, [app_env]).

get_set_env/4

get_set_env(Scope::scope(), App::atom(), Key::atom(), Strategy) -> Value


Fetch and cache an environment value, if not already cached.

This function does the same thing as get_env/4, but also updates the cache. Note that the cache will be updated even if the result of the lookup is undefined.

See also: get_env/4.

get_value/1

get_value(Key) -> Value


Read the value stored with a key registered to the current process.

If no such key is registered to the current process, this function exits.

give_away/2

give_away(From::key(), To::pid() | key()) -> undefined | pid()


Atomically transfers the key From to the process identified by To.

This function transfers any gproc key (name, property, counter, aggr counter)
from one process to another, and returns the pid of the new owner.

To must be either a pid or a unique name (name or aggregated counter), but does not necessarily have to resolve to an existing process. If there is no process registered with the To key, give_away/2 returns undefined, and the From key is effectively unregistered.

It is allowed to give away a key to oneself, but of course, this operation
will have no effect.

Fails with badarg if the calling process does not have a From key registered.

goodbye/0

goodbye() -> ok


Unregister all items of the calling process and inform gproc
to forget about the calling process.

This function is more efficient than letting gproc perform these cleanup operations.

info/1

info(Pid::pid()) -> ProcessInfo
  • ProcessInfo = [{gproc, [{Key, Value}]} | ProcessInfo]

Similar to process_info(Pid) but with additional gproc info.

Returns the same information as process_info(Pid), but with the addition of a gproc information item, containing the {Key,Value} pairs registered to the process.

info/2

info(Pid::pid(), Item::atom()) -> {Item, Info}


Similar to process_info(Pid, Item), but with additional gproc info.

For Item = gproc, this function returns a list of {Key, Value} pairs registered to the process Pid. For other values of Item, it returns the same as http://www.erlang.org/doc/man/erlang.html#process_info-2.

last/1

last(Context::context()) -> key() | '$end_of_table'


Behaves as ets:last(Tab) for a given type of registration object.

See http://www.erlang.org/doc/man/ets.html#last-1. The registry behaves as an ordered_set table.

lookup_global_aggr_counter/1

lookup_global_aggr_counter(Name::any()) -> integer()


Equivalent to where({a, g, Name}).

Lookup a global (unique) aggregated counter and returns its value. Fails if there is no such object.

lookup_global_counters/1

lookup_global_counters(Counter::any()) -> [{pid(), Value::integer()}]


Equivalent to lookup_values({c, g, Counter}).

Look up all global (non-unique) instances of a given Counter. Returns a list of {Pid, Value} tuples for all matching objects.

lookup_global_name/1

lookup_global_name(Name::any()) -> pid()


Equivalent to where({n, g, Name}).

Lookup a global unique name. Fails if there is no such name.

lookup_global_properties/1

lookup_global_properties(Property::any()) -> [{pid(), Value}]


Equivalent to lookup_values({p, g, Property}).

Look up all global (non-unique) instances of a given Property. Returns a list of {Pid, Value} tuples for all matching objects.

lookup_local_aggr_counter/1

lookup_local_aggr_counter(Name::any()) -> integer()


Equivalent to where({a, l, Name}).

Lookup a local (unique) aggregated counter and returns its value. Fails if there is no such object.

lookup_local_counters/1

lookup_local_counters(Counter::any()) -> [{pid(), Value::integer()}]


Equivalent to lookup_values({c, l, Counter}).

Look up all local (non-unique) instances of a given Counter. Returns a list of {Pid, Value} tuples for all matching objects.

lookup_local_name/1

lookup_local_name(Name::any()) -> pid()


Equivalent to where({n, l, Name}).

Lookup a local unique name. Fails if there is no such name.

lookup_local_properties/1

lookup_local_properties(Property::any()) -> [{pid(), Value}]


Equivalent to lookup_values({p, l, Property}).

Look up all local (non-unique) instances of a given Property. Returns a list of {Pid, Value} tuples for all matching objects.

lookup_pid/1

lookup_pid(Key) -> Pid


Lookup the Pid stored with a key.

lookup_pids/1

lookup_pids(Key::key()) -> [pid()]


Returns a list of pids with the published key Key

If the type of registration entry is either name or aggregated counter, this function will return either an empty list, or a list of one pid. For non-unique types, the return value can be a list of any length.

lookup_value/1

lookup_value(Key) -> Value


Lookup the value stored with a key.

lookup_values/1

lookup_values(Key::key()) -> [{pid(), Value}]


Retrieve the {Pid,Value} pairs corresponding to Key.

Key refer to any type of registry object. If it refers to a unique object, the list will be of length 0 or 1. If it refers to a non-unique object, the return value can be a list of any length.

mreg/3

mreg(T::type(), X2::scope(), KVL::[{Key::any(), Value::any()}]) -> true


Register multiple {Key,Value} pairs of a given type and scope.

This function is more efficient than calling reg/2 repeatedly. It is also atomic in regard to unique names; either all names are registered or none are.

munreg/3

munreg(T::type(), X2::scope(), L::[Key::any()]) -> true


Unregister multiple Key items of a given type and scope.

This function is usually more efficient than calling unreg/1 repeatedly.

nb_wait/1

nb_wait(Key::key()) -> Ref


Wait for a local name to be registered. The caller can expect to receive a message, {gproc, Ref, registered, {Key, Pid, Value}}, once the name is registered.

next/2

next(Context::context(), Key::key()) -> key() | '$end_of_table'


Behaves as ets:next(Tab,Key) for a given type of registration object.

See http://www.erlang.org/doc/man/ets.html#next-2. The registry behaves as an ordered_set table.

prev/2

prev(Context::context(), Key::key()) -> key() | '$end_of_table'


Behaves as ets:prev(Tab,Key) for a given type of registration object.

See http://www.erlang.org/doc/man/ets.html#prev-2. The registry behaves as an ordered_set table.

reg/1

reg(Key::key()) -> true


Equivalent to reg(Key, default(Key)).

reg/2

reg(Key::key(), Value) -> true


Register a name or property for the current process

select/1

select(Pat::select_pattern()) -> [sel_object()]


Equivalent to select(all, Pat).

select/2

select(Context::context(), Pat::sel_pattern()) -> [{Key, Pid, Value}]


Perform a select operation on the process registry.

The physical representation in the registry may differ from the above, but the select patterns are transformed appropriately.

select/3

select(Context::context(), Pat::sel_patten(), Limit::integer()) -> [{Key, Pid, Value}]


Like select/2 but returns Limit objects at a time.

See http://www.erlang.org/doc/man/ets.html#select-3.

select_count/1

select_count(Pat::select_pattern()) -> [sel_object()]


Equivalent to select_count(all, Pat).

select_count/2

select_count(Context::context(), Pat::sel_pattern()) -> [{Key, Pid, Value}]


Perform a select_count operation on the process registry.

The physical representation in the registry may differ from the above, but the select patterns are transformed appropriately.

send/2

send(Key::key(), Msg::any()) -> Msg


Sends a message to the process, or processes, corresponding to Key.

If Key belongs to a unique object (name or aggregated counter), this function will send a message to the corresponding process, or fail if there is no such process. If Key is for a non-unique object type (counter or property), Msg will be send to all processes that have such an object.

set_env/5

set_env(Scope::scope(), App::atom(), Key::atom(), Value::term(), Strategy) -> Value
  • Strategy = [Alternative]
  • Alternative = app_env | os_env | {os_env, VAR} | {mnesia, ActivityType, Oid, Pos}

Updates the cached value as well as underlying environment.

This function should be exercised with caution, as it affects the larger
environment outside gproc. This function modifies the cached value, and then
proceeds to update the underlying environment (OS environment variable or
application environment variable).

When the mnesia alternative is used, gproc will try to update any existing object, changing only the Pos position. If no such object exists, it will create a new object, setting any other attributes (except Pos and the key) to undefined.

set_value/2

set_value(Key::key(), Value) -> true


Sets the value of the registeration entry given by Key

Key is assumed to exist and belong to the calling process.
If it doesn't, this function will exit.

Value can be any term, unless the object is a counter, in which case it must be an integer.

start_link/0

start_link() -> {ok, pid()}


Starts the gproc server.

This function is intended to be called from gproc_sup, as part of starting the gproc application.

table/1

table(Context::context()) -> any()


Equivalent to table(Context, []).

table/2

table(Context::context(), Opts) -> any()


QLC table generator for the gproc registry. Context specifies which subset of the registry should be queried. See http://www.erlang.org/doc/man/qlc.html.

unreg/1

unreg(Key::key()) -> true


Unregister a name or property.

unregister_name/1

unregister_name(Key) -> any()

Equivalent to unreg / 1.

update_counter/2

update_counter(Key::key(), Incr::integer()) -> integer()


Updates the counter registered as Key for the current process.

This function works like ets:update_counter/3 (see http://www.erlang.org/doc/man/ets.html#update_counter-3), but will fail if the type of object referred to by Key is not a counter.

where/1

where(Key::key()) -> pid()


Returns the pid registered as Key

The type of registration entry must be either name or aggregated counter. Otherwise this function will exit. Use lookup_pids/1 in these cases.

whereis_name/1

whereis_name(Key) -> any()

Equivalent to where / 1.

Something went wrong with that request. Please try again.