diff options
| author | Michael Klishin <michael@clojurewerkz.org> | 2016-01-09 20:30:04 +0300 |
|---|---|---|
| committer | Michael Klishin <michael@clojurewerkz.org> | 2016-01-09 20:30:04 +0300 |
| commit | 438f16d2b8af9099c36bb2cac36621dcb932786d (patch) | |
| tree | 762f8a14db2316786cd8fd95c558d8d472ea7493 /src | |
| parent | 26b670a90e2b27e8d09fcba34a8f2e59d9a47147 (diff) | |
| download | rabbitmq-server-git-438f16d2b8af9099c36bb2cac36621dcb932786d.tar.gz | |
Ensure exchange-delete-in-progress is always cleared
Diffstat (limited to 'src')
| -rw-r--r-- | src/rabbit_exchange.erl | 47 |
1 files changed, 29 insertions, 18 deletions
diff --git a/src/rabbit_exchange.erl b/src/rabbit_exchange.erl index fe1fa1a19e..28222c54fd 100644 --- a/src/rabbit_exchange.erl +++ b/src/rabbit_exchange.erl @@ -166,6 +166,10 @@ declare(XName, Type, Durable, AutoDelete, Internal, Args) -> XT = type_to_module(Type), %% We want to upset things if it isn't ok ok = XT:validate(X), + %% Avoid a channel exception if there's a race condition + %% with an exchange.delete operation. + %% + %% See rabbitmq/rabbitmq-federation#7. case rabbit_runtime_parameters:lookup(XName#resource.virtual_host, <<"exchange-delete-in-progress">>, XName#resource.name) of @@ -435,24 +439,31 @@ delete(XName, IfUnused) -> true -> fun conditional_delete/2; false -> fun unconditional_delete/2 end, - rabbit_runtime_parameters:set(XName#resource.virtual_host, - <<"exchange-delete-in-progress">>, - XName#resource.name, true, none), - call_with_exchange( - XName, - fun (X) -> - case Fun(X, false) of - {deleted, X, Bs, Deletions} -> - rabbit_binding:process_deletions( - rabbit_binding:add_deletion( - XName, {X, deleted, Bs}, Deletions)); - {error, _InUseOrNotFound} = E -> - rabbit_misc:const(E) - end - end), - rabbit_runtime_parameters:clear(XName#resource.virtual_host, - <<"exchange-delete-in-progress">>, - XName#resource.name). + try + %% guard exchange.declare operations from failing when there's + %% a race condition between it and an exchange.delete. + %% + %% see rabbitmq/rabbitmq-federation#7 + rabbit_runtime_parameters:set(XName#resource.virtual_host, + <<"exchange-delete-in-progress">>, + XName#resource.name, true, none), + call_with_exchange( + XName, + fun (X) -> + case Fun(X, false) of + {deleted, X, Bs, Deletions} -> + rabbit_binding:process_deletions( + rabbit_binding:add_deletion( + XName, {X, deleted, Bs}, Deletions)); + {error, _InUseOrNotFound} = E -> + rabbit_misc:const(E) + end + end) + after + rabbit_runtime_parameters:clear(XName#resource.virtual_host, + <<"exchange-delete-in-progress">>, + XName#resource.name) + end. validate_binding(X = #exchange{type = XType}, Binding) -> Module = type_to_module(XType), |
