diff options
author | Paul Jones <paulj@lshift.net> | 2009-08-10 15:13:18 +0100 |
---|---|---|
committer | Paul Jones <paulj@lshift.net> | 2009-08-10 15:13:18 +0100 |
commit | 5c553b6541e198faa6d04d7df037321e3f3617c4 (patch) | |
tree | 7a1d366b4741f64ae827ce69abdb0fe00e89f7b7 | |
parent | ea67ca82ef894396adc69ee6f7bdb7fa0d6f2e92 (diff) | |
download | rabbitmq-server-5c553b6541e198faa6d04d7df037321e3f3617c4.tar.gz |
Implementation of hook mechanism using ETS table for storage of hooks, along with test cases to validate functionality
-rw-r--r-- | src/rabbit.erl | 1 | ||||
-rw-r--r-- | src/rabbit_hooks.erl | 70 | ||||
-rw-r--r-- | src/rabbit_tests.erl | 35 |
3 files changed, 106 insertions, 0 deletions
diff --git a/src/rabbit.erl b/src/rabbit.erl index 088fa436..b0d62b5a 100644 --- a/src/rabbit.erl +++ b/src/rabbit.erl @@ -133,6 +133,7 @@ start(normal, []) -> {"core processes", fun () -> ok = start_child(rabbit_log), + ok = rabbit_hooks:start(), ok = rabbit_amqqueue:start(), diff --git a/src/rabbit_hooks.erl b/src/rabbit_hooks.erl new file mode 100644 index 00000000..454171ca --- /dev/null +++ b/src/rabbit_hooks.erl @@ -0,0 +1,70 @@ +%% The contents of this file are subject to the Mozilla Public License +%% Version 1.1 (the "License"); you may not use this file except in +%% compliance with the License. You may obtain a copy of the License at +%% http://www.mozilla.org/MPL/ +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +%% License for the specific language governing rights and limitations +%% under the License. +%% +%% The Original Code is RabbitMQ. +%% +%% The Initial Developers of the Original Code are LShift Ltd, +%% Cohesive Financial Technologies LLC, and Rabbit Technologies Ltd. +%% +%% Portions created before 22-Nov-2008 00:00:00 GMT by LShift Ltd, +%% Cohesive Financial Technologies LLC, or Rabbit Technologies Ltd +%% are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial +%% Technologies LLC, and Rabbit Technologies Ltd. +%% +%% Portions created by LShift Ltd are Copyright (C) 2007-2009 LShift +%% Ltd. Portions created by Cohesive Financial Technologies LLC are +%% Copyright (C) 2007-2009 Cohesive Financial Technologies +%% LLC. Portions created by Rabbit Technologies Ltd are Copyright +%% (C) 2007-2009 Rabbit Technologies Ltd. +%% +%% All Rights Reserved. +%% +%% Contributor(s): ______________________________________. +%% + +-module(rabbit_hooks). + +-export([start/0]). +-export([subscribe/3, unsubscribe/2, trigger/2]). + +-define(TableName, rabbit_hooks). + +-ifdef(use_specs). + +-type(hookfun() :: fun((list()) -> 'ok')). + +-spec(start/0 :: () -> 'ok'). +-spec(subscribe/3 :: (atom(), atom(), hookfun()) -> 'ok'). +-spec(unsubscribe/2 :: (atom(), atom()) -> 'ok'). +-spec(trigger/2 :: (atom(), list()) -> 'ok'). + +-endif. + +start() -> + ets:new(?TableName, [bag, public, named_table]), + ok. + +subscribe(Hook, HandlerName, Handler) -> + ets:insert(?TableName, {Hook, HandlerName, Handler}), + ok. + +unsubscribe(Hook, HandlerName) -> + ets:match_delete(?TableName, {Hook, HandlerName, '_'}), + ok. + +trigger(Hook, Args) -> + Hooks = ets:lookup(?TableName, Hook), + [case catch H(Args) of + {'EXIT', Reason} -> + rabbit_log:warning("Failed to execute handler ~p for hook ~p: ~p", + [Name, Hook, Reason]); + _ -> ok + end || {_, Name, H} <- Hooks], + ok. diff --git a/src/rabbit_tests.erl b/src/rabbit_tests.erl index 01757509..aef8c9d8 100644 --- a/src/rabbit_tests.erl +++ b/src/rabbit_tests.erl @@ -54,6 +54,7 @@ all_tests() -> passed = test_cluster_management(), passed = test_user_management(), passed = test_server_status(), + passed = test_hooks(), passed. test_priority_queue() -> @@ -601,6 +602,40 @@ test_server_status() -> passed. +test_hooks() -> + %% Firing of hooks calls all hooks in an isolated manner + rabbit_hooks:subscribe(test_hook, test, + fun(Args) -> + put(fired_testhook_handler, Args) + end), + rabbit_hooks:subscribe(test_hook, test2, + fun(Args) -> + put(fired_testhook_handler2, Args) + end), + rabbit_hooks:subscribe(test_hook2, test2, + fun(Args) -> + put(fired_testhook2_handler, Args) + end), + rabbit_hooks:trigger(test_hook, [arg1, arg2]), + [arg1, arg2] = get(fired_testhook_handler), + [arg1, arg2] = get(fired_testhook_handler2), + undefined = get(fired_testhook2_handler), + + %% Hook Deletion works + put(fired_testhook_handler, undefined), + put(fired_testhook_handler2, undefined), + rabbit_hooks:unsubscribe(test_hook, test), + rabbit_hooks:trigger(test_hook, [arg3, arg4]), + undefined = get(fired_testhook_handler), + [arg3, arg4] = get(fired_testhook_handler2), + undefined = get(fired_testhook2_handler), + + %% Catches exceptions from bad hooks + rabbit_hooks:subscribe(test_hook3, test, fun(Args) -> bad:bad() end), + ok = rabbit_hooks:trigger(test_hook3, []), + + passed. + %--------------------------------------------------------------------- control_action(Command, Args) -> control_action(Command, node(), Args). |