Anonymous avatar Anonymous committed ac050dc

Add edocs to riak_eventer.

Comments (0)

Files changed (2)

src/riak_client.erl

     rpc:call(Node,riak_eventer,notify,
              [client_event, EventName, {ClientId, EventDetail}]).
 
-
-%% @doc Attach a new handler pid to Riak events. 
-%% See http://erlang.org/doc/apps/erts/match_spec.html for more 
-%% information about match head and match guard.
-%% Desc is simply a human readable string used by the WebUI.
+%% @equiv add_event_handler(Pid, Desc, {'_', '_', '_', '_'}, [])
 add_event_handler(Pid, Desc) -> 
     add_event_handler(Pid, Desc, {'_', '_', '_', '_'}).
-    
+
+%% @equiv add_event_handler(Pid, Desc, MatchHead, [])
 add_event_handler(Pid, Desc, MatchHead) -> 
     add_event_handler(Pid, Desc, MatchHead, []).
     
+%% @doc
+%% Register a process that will receive Riak events 
+%% generated by the cluster in the form of Erlang messages.
+%% See {@link riak_eventer:add_handler/4.} for more information.
 add_event_handler(Pid, Desc, MatchHead, MatchGuard) ->
     rpc:call(Node, riak_eventer, add_handler, [Pid, Desc, MatchHead, MatchGuard]). 
 
-%% remove_handler/N - 
-%% Remove a previously added handler, if it still exists.
-%% Handlers are automatically removed for dead processes
-%% every (gossip_interval) seconds, or upon adding
-%% or deleting.
+%% @doc
+%% Remove an event handler added by {@link add_event_handler/4}, if it exists.
+%% See {@link riak_eventer:remove_handler/3.} for more information.
 remove_event_handler(Pid, MatchHead, MatchGuard) ->
     rpc:call(Node, riak_eventer, remove_handler, [Pid, MatchHead, MatchGuard]). 
 

src/riak_eventer.erl

 %% specific language governing permissions and limitations
 %% under the License.    
 
-
+%%
 %% @doc
-%% riak_eventer allows you to attach event handlers to a running Riak cluster to
-%% receive event notifications (in the form of Erlang messages) about what is happening
-%% in the application. 
+%% Riak events provide information about what is happening behind-the-scenes
+%% in a Riak cluster. 
 %%
-%% Events are generated using notify/1 or notify/3. Each event consists
-%% of a Module, an EventName, the Node on which the event is generated,
-%% and additional detail about the event.
+%% Events are generated using {@link notify/1} or {@link notify/3}. 
+%% Each event consists of a Module, an EventName, the Node on which 
+%% the event is generated, and additional detail about the event. 
 %%
-%% This is stored in a tuple of the form {event, {Module, EventName, Node, EventDetail}}.
-%% For example, a 'put' operation will generate an event such as 
-%% {event,{riak_vnode,put, 'node@hostname', ...}}.
+%% A process can register to receive evets using
+%% {@link add_handler/4}. Full ETS MatchSpec style matching is supported, allowing
+%% the process to receive a subset of events, if desired. Filtering occurs at the
+%% server level. 
 %%
-%% Event handlers are added via add_handler(Pid, Description, MatchHead, MatchGuard),
-%% and can be removed via remove_handler(Pid, MatchHead, MatchGuard).
-%%
-%% Full MatchSpec style matching is allowed (see http://erlang.org/doc/apps/erts/match_spec.html)
-%% to filter events at the server level, and the system fully supports registering 
-%% a single process for multiple events.
+%% An application can register multiple event handlers, and can register multiple
+%% filters for a single pid.
 %%
 %% Riak monitors running handlers, and automatically removes 
-%% handlers of dead processors.
-
+%% handlers of dead processors. Alternatively, an event handler
+%% can be removed using {@link remove_handler/3}.
 
 -module(riak_eventer).
 -behaviour(gen_server2).
 	 terminate/2, code_change/3]).
 
 -export([notify/1, notify/3]).
--export ([add_handler/4]).
--export ([remove_handler/1, remove_handler/3]).
--export ([remove_dead_handlers/0]).
+-export ([add_handler/4, remove_handler/3]).
 
 -define(REMOVE_INTERVAL, 5 * 1000).
 
     matchguard  % MatchGuard, defaults to []
 }).
 
+%% @type eventmessage() = {event, Event::event()}
+%% @type event() = {EventModule::atom(), EventName::atom(), Node::atom(), EventData::term()}
+
+
+%% @spec notify(Event :: event()) -> ok
+%% @doc Generate an event that will be sent to all
+%% handlers whose MatchSpecs match the event.
+notify(Event) ->
+    gen_server2:cast(riak_local_logger, {event, Event}),
+    gen_server2:cast(?MODULE, {event, Event}).
+
+%% @spec notify(EventModule :: atom(), EventName :: atom(), EventDetail :: term()) -> ok
+%% @equiv notify({EventModule, EventName, node(), EventDetail})
+notify(EventModule, EventName, EventDetail) ->
+    notify({EventModule, EventName, node(), EventDetail}).
+    
+%% @spec 
+%% add_handler(Pid::pid(), Desc::string(), MatchHead::tuple(), MatchGuard::tuple()) -> ok
+%% EventMessage = eventmessage()
+%% @doc
+%% Register a process that will receive Riak events 
+%% generated by the cluster. Events are Erlang messages in the form 
+%% <code>{event, {EventModule, EventName, Node, EventData}}</code>.
+%%
+%% During operation, Riak generates events for reporting
+%% and monitoring purposes. By registering an event handler
+%% an application can choose to receive all or a subset of these events.
+%% Riak allows for an unlimited number of event handlers (bounded only by memory).
+%% When an event handler process dies, Riak automatically removes
+%% that event handler from the list of event handlers. Alternatively,
+%% an event handler can be programatically removed via the 
+%% {@link remove_handler/3} function.
+%%
+%% Event handlers are judged to be unique based on the Pid, MatchHead, and MatchGuard.
+%% In other words, multiple event handlers can be wired to the same pid so long as 
+%% either their MatchHead or MatchGuard is different. If add_handler/4 is called twice 
+%% with the same exact same Pid, MatchHead, and MatchGuard, then the old handler
+%% is replaced by the new handler.
+%% 
+%% In addition, while registering an event handler, a 
+%% developer can choose to filter the events that the 
+%% event handler will receive. This filtering happens on 
+%% the node generating the event. Riak generates a large number
+%% of events, so tight filtering is a good idea in order to minimize
+%% network traffic.
+%% 
+%% An event filter is specified using the MatchSpec syntax
+%% established by the ETS module. See 
+%% <a href="http://erlang.org/doc/apps/erts/match_spec.html">ETS MatchSpec</a>
+%% for more information.
+%%
+%% Register for all events generated by the node 'riak@127.0.0.1':
+%% <pre>
+%% RiakClient:add_event_handler(self(), "Description", {'_', '_', 'riak@127.0.0.1', '_'}, [])).
+%% </pre>
+%%
+%% Register for all events generated by the riak_vnode module:
+%% <pre>
+%% RiakClient:add_event_handler(self(), "Description", {riak_vnode, '_', '_', '_'}, []))
+%% </pre>
+%% 
+%% Register for all 'put', 'get', and 'delete' events generated by the riak_vnode module:
+%% <pre>
+%% MatchHead = {'$1', '$2', '_', '_'},
+%% MatchGuard = [
+%%   {'andalso', {'==', '$1', riak_vnode}, {'orelse', {'==', '$2', get}, {'==', '$2', put}, {'==', '$2', delete}}}
+%% ],
+%% RiakClient:add_event_handler(self(), "Description", MatchHead, MatchGuard).
+%% </pre>
+%%
+%% Events are sent once per matching filter. If a single process registers under more than
+%% one MatchSpecs, and an event matches both MatchSpecs, then the process will
+%% receive the event multiple times.
+%%
+%% The Description parameter is used to supply a human readable
+%% string used by monitoring software to displaying connected event handlers.
+%%
+%% Because of the way Riak shares information between clusters, it may be 
+%% a few seconds before events start being sent to the handler from all nodes.
+add_handler(Pid, Description, MatchHead, MatchGuard) ->
+    gen_server:call(?MODULE, {add_handler, Pid, Description, MatchHead, MatchGuard}).
+
+
+%% @spec remove_handler(Pid::pid(), MatchHead::tuple(), MatchGuard::list()) -> ok
+%% @doc
+%% Remove the previously registered event handler. The arguments
+%% supplied to remove_handler/3 must be the same arguments supplied to
+%% add_handler/4. remove_handler/3 returns 'ok' regardless of whether
+%% any event handlers are removed.
+%%
+%% Because of the way Riak shares information between clusters, it may be 
+%% a few seconds before events stop being sent to the handler.
+remove_handler(Pid, MatchHead, MatchGuard) ->
+    HandlerID = get_handler_id(Pid, MatchHead, MatchGuard),
+    gen_server:call(?MODULE, {remove_handler, HandlerID}).
+
 %% @private
 start_link() -> gen_server2:start_link({local, ?MODULE}, ?MODULE, [], []).
+
+%% @private
 start_link(test) -> % when started this way, run a mock server (nop)
     gen_server2:start_link({local, ?MODULE}, ?MODULE, [test], []).
 
 %% @private
 init([]) -> {ok, stateless_server};
 init([test]) -> {ok, test}.
-
-notify(Event) ->
-    gen_server2:cast(riak_local_logger, {event, Event}),
-    gen_server2:cast(?MODULE, {event, Event}).
-
-notify(Module, EventName, EventDetail) ->
-    notify({Module, EventName, node(), EventDetail}).
     
-add_handler(Pid, Desc, MatchHead, MatchSpec) ->
-    gen_server:call(?MODULE, {add_handler, Pid, Desc, MatchHead, MatchSpec}).
-
-remove_handler(Pid, MatchHead, MatchSpec) ->
-    HandlerID = get_handler_id(Pid, MatchHead, MatchSpec),
-    remove_handler(HandlerID).
-
-remove_handler(HandlerID) ->
-    gen_server:call(?MODULE, {remove_handler, HandlerID}).
-    
-remove_dead_handlers() ->
-    gen_server:call(?MODULE, {remove_dead_handlers, false}).
-
 %% @private (only used for test instances)
 stop() -> gen_server2:cast(?MODULE, stop).
 
 %% @private
-handle_call({add_handler, Pid, Desc, MatchHead, MatchSpec},_From,State) -> 
+handle_call({add_handler, Pid, Desc, MatchHead, MatchGuard},_From,State) -> 
     % Monitor the pid, we want to know when to remove it...
     erlang:monitor(process, Pid),
 
     % Add the handler...
     {ok, Ring} = riak_ring_manager:get_my_ring(),
-    Handler = make_handler(Pid, Desc, MatchHead, MatchSpec),
+    Handler = make_handler(Pid, Desc, MatchHead, MatchGuard),
     Ring1 = add_handler_to_ring(Handler, Ring),
     
     % Set and save the new ring...
     
 handle_cast(_, State) -> {noreply, State}.
 
+%% @private
 handle_info({'DOWN', _, process, Pid, _}, State) ->
     % Get a 'DOWN' message, so remove any handlers from this Pid...
     {ok, Ring} = riak_ring_manager:get_my_ring(),
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.