diff options
| -rw-r--r-- | include/rabbit.hrl | 5 | ||||
| -rw-r--r-- | src/rabbit_exchange.erl | 64 |
2 files changed, 21 insertions, 48 deletions
diff --git a/include/rabbit.hrl b/include/rabbit.hrl index 418d6521a0..c23c5664b2 100644 --- a/include/rabbit.hrl +++ b/include/rabbit.hrl @@ -78,6 +78,7 @@ name :: name()}). -type(queue_name() :: r('queue')). -type(exchange_name() :: r('exchange')). +-type(key() :: binary()). -type(user() :: #user{username :: username(), password :: password()}). @@ -94,6 +95,10 @@ durable :: bool(), auto_delete :: bool(), arguments :: amqp_table()}). +-type(binding() :: + #binding{exchange_name :: exchange_name(), + queue_name :: queue_name(), + key :: key()}). %% TODO: make this more precise by tying specific class_ids to %% specific properties -type(undecoded_content() :: diff --git a/src/rabbit_exchange.erl b/src/rabbit_exchange.erl index c8eea77a74..faf9ca419a 100644 --- a/src/rabbit_exchange.erl +++ b/src/rabbit_exchange.erl @@ -29,7 +29,7 @@ -include("rabbit_framing.hrl"). -export([recover/0, declare/5, lookup/1, lookup_or_die/1, - list_vhost_exchanges/1, list_exchange_bindings/1, + list_vhost_exchanges/1, simple_publish/6, simple_publish/3, route/2]). -export([add_binding/1, delete_binding/1]). @@ -57,18 +57,14 @@ -spec(lookup/1 :: (exchange_name()) -> {'ok', exchange()} | not_found()). -spec(lookup_or_die/1 :: (exchange_name()) -> exchange()). -spec(list_vhost_exchanges/1 :: (vhost()) -> [exchange()]). --spec(list_exchange_bindings/1 :: (exchange_name()) -> - [{queue_name(), routing_key(), amqp_table()}]). -spec(simple_publish/6 :: (bool(), bool(), exchange_name(), routing_key(), binary(), binary()) -> publish_res()). -spec(simple_publish/3 :: (bool(), bool(), message()) -> publish_res()). -spec(route/2 :: (exchange(), routing_key()) -> [pid()]). -% -spec(add_binding/2 :: (binding_spec(), amqqueue()) -> -% 'ok' | not_found() | -% {'error', 'durability_settings_incompatible'}). -% -spec(delete_binding/2 :: (binding_spec(), amqqueue()) -> -% 'ok' | not_found()). +-spec(add_binding/1 :: (binding()) -> 'ok' | not_found() | + {'error', 'durability_settings_incompatible'}). +-spec(delete_binding/1 :: (binding()) -> 'ok' | not_found()). -spec(topic_matches/2 :: (binary(), binary()) -> bool()). -spec(delete/2 :: (exchange_name(), bool()) -> 'ok' | not_found() | {'error', 'in_use'}). @@ -148,22 +144,10 @@ list_vhost_exchanges(VHostPath) -> mnesia:dirty_match_object( #exchange{name = rabbit_misc:r(VHostPath, exchange), _ = '_'}). -list_exchange_bindings(Name) -> - exit(list_exchange_bindings). - % [{QueueName, RoutingKey, Arguments} || - % #binding{handlers = Handlers} <- bindings_for_exchange(Name), - % #handler{binding_spec = #binding_spec{routing_key = RoutingKey, - % arguments = Arguments}, - % queue = QueueName} <- Handlers]. - -% Maybe this named wrongly - it returns a route -bindings_for_exchange(Name) -> +routes_for_exchange(Name) -> qlc:e(qlc:q([R || R = #route{binding = #binding{exchange_name = N}} <- mnesia:table(route), N == Name])). -empty_handlers() -> - []. - %% Usable by Erlang code that wants to publish messages. simple_publish(Mandatory, Immediate, ExchangeName, RoutingKeyBin, ContentTypeBin, BodyBin) -> {ClassId, _MethodId} = rabbit_framing:method_id('basic.publish'), @@ -246,14 +230,9 @@ add_binding(Binding) -> delete_binding(Binding) -> call_with_exchange_and_queue( Binding, - fun (X,Q) -> ok = internal_delete_binding(Binding) + fun (X,Q) -> ok = internal_delete_binding(Binding), + ok = maybe_auto_delete(X) end). - % call_with_exchange( - % ExchangeName, - % fun (X) -> ok = internal_delete_binding( - % X, RoutingKey, make_handler(BindingSpec, Q)), - % maybe_auto_delete(X) - % end). %% Must run within a transaction. maybe_auto_delete(#exchange{auto_delete = false}) -> @@ -321,33 +300,22 @@ delete(ExchangeName, IfUnused) -> fun () -> internal_delete(ExchangeName, IfUnused) end). internal_delete(ExchangeName, _IfUnused = true) -> - exit(internal_delete); - % Bindings = bindings_for_exchange(ExchangeName), - % case Bindings of - % [] -> do_internal_delete(ExchangeName, Bindings); - % _ -> - % case lists:all(fun (#binding{handlers = H}) -> handlers_isempty(H) end, - % Bindings) of - % true -> - % %% There are no handlers anywhere in any of the - % %% bindings for this exchange. - % do_internal_delete(ExchangeName, Bindings); - % false -> - % %% There was at least one real handler - % %% present. It's still in use. - % {error, in_use} - % end - % end; + Routes = routes_for_exchange(ExchangeName), + case Routes of + [] -> do_internal_delete(ExchangeName, Routes); + _ -> {error, in_use} + end; + internal_delete(ExchangeName, false) -> - do_internal_delete(ExchangeName, bindings_for_exchange(ExchangeName)). + do_internal_delete(ExchangeName, routes_for_exchange(ExchangeName)). % Don't know if iterating over a list in process memory is cool % Maybe we should iterate over the DB cursor? -do_internal_delete(ExchangeName, Bindings) -> +do_internal_delete(ExchangeName, Routes) -> case mnesia:wread({exchange, ExchangeName}) of [] -> {error, not_found}; _ -> - lists:foreach(fun (B) -> ok = mnesia:delete_object(B) end, Bindings), + lists:foreach(fun (R) -> ok = mnesia:delete_object(R) end, Routes), ok = mnesia:delete({durable_exchanges, ExchangeName}), ok = mnesia:delete({exchange, ExchangeName}) end. |
