diff options
| -rw-r--r-- | .hgignore | 1 | ||||
| -rw-r--r-- | README | 2 | ||||
| -rwxr-xr-x | check_xref | 20 | ||||
| -rw-r--r-- | ebin/rabbit_app.in | 4 | ||||
| -rw-r--r-- | packaging/RPMS/Fedora/rabbitmq-server.spec | 3 | ||||
| -rw-r--r-- | packaging/common/README | 20 | ||||
| -rw-r--r-- | packaging/debs/Debian/debian/rules | 1 | ||||
| -rw-r--r-- | src/rabbit_amqqueue.erl | 12 | ||||
| -rw-r--r-- | src/rabbit_channel.erl | 3 | ||||
| -rw-r--r-- | src/rabbit_exchange.erl | 12 | ||||
| -rw-r--r-- | src/rabbit_file.erl | 2 | ||||
| -rw-r--r-- | src/rabbit_limiter.erl | 16 | ||||
| -rw-r--r-- | src/rabbit_mirror_queue_slave.erl | 41 | ||||
| -rw-r--r-- | src/rabbit_policy.erl | 49 | ||||
| -rw-r--r-- | src/rabbit_runtime_parameters.erl | 22 | ||||
| -rw-r--r-- | src/vm_memory_monitor.erl | 4 |
16 files changed, 125 insertions, 87 deletions
@@ -4,6 +4,7 @@ syntax: glob *.swp *.patch *.orig +*.tmp erl_crash.dump deps.mk @@ -1 +1 @@ -Please see http://www.rabbitmq.com/build-server.html for build instructions. +Please see http://www.rabbitmq.com/build-server.html for build instructions.
\ No newline at end of file diff --git a/check_xref b/check_xref index 24307fdb60..21eb14b9ca 100755 --- a/check_xref +++ b/check_xref @@ -133,16 +133,20 @@ process_analysis(Query, Tag, Severity, Analysis) when is_list(Query) -> checks() -> [{"(XXL)(Lin) ((XC - UC) || (XU - X - B))", "has call to undefined function(s)", - error, filters()}, - {"(Lin) (L - LU)", "has unused local function(s)", - error, filters()}, + error, filters()}, + {"(Lin) (L - LU)", + "has unused local function(s)", + error, filters()}, + {"(E | \"(rabbit|amqp).*\":_/_ || \"gen_server2?\":call/2)", + "has 5 sec timeout in", + error, filters()}, {"(Lin) (LU * (X - XU))", - "has exported function(s) only used locally", - warning, filters()}, + "has exported function(s) only used locally", + warning, filters()}, {"(Lin) (DF * (XU + LU))", "used deprecated function(s)", - warning, filters()}]. -% {"(Lin) (X - XU)", "possibly unused export", -% warning, fun filter_unused/1}]. + warning, filters()}]. +%% {"(Lin) (X - XU)", "possibly unused export", +%% warning, fun filter_unused/1}]. %% %% noise filters (can be disabled with -X) - strip uninteresting analyses diff --git a/ebin/rabbit_app.in b/ebin/rabbit_app.in index 6ee0115b67..a10bad450d 100644 --- a/ebin/rabbit_app.in +++ b/ebin/rabbit_app.in @@ -1,4 +1,4 @@ -{application, rabbit, %% -*- erlang -*- +{application, rabbit, %% -*- erlang -*- [{description, "RabbitMQ"}, {id, "RabbitMQ"}, {vsn, "%%VSN%%"}, @@ -25,7 +25,7 @@ %% 0 ("no limit") would make a better default, but that %% breaks the QPid Java client {frame_max, 131072}, - {heartbeat, 600}, + {heartbeat, 580}, {msg_store_file_size_limit, 16777216}, {queue_index_max_journal_entries, 65536}, {default_user, <<"guest">>}, diff --git a/packaging/RPMS/Fedora/rabbitmq-server.spec b/packaging/RPMS/Fedora/rabbitmq-server.spec index ff2d18aa99..05140e3c78 100644 --- a/packaging/RPMS/Fedora/rabbitmq-server.spec +++ b/packaging/RPMS/Fedora/rabbitmq-server.spec @@ -10,6 +10,7 @@ Source1: rabbitmq-server.init Source2: rabbitmq-script-wrapper Source3: rabbitmq-server.logrotate Source4: rabbitmq-server.ocf +Source5: README URL: http://www.rabbitmq.com/ BuildArch: noarch BuildRequires: erlang >= R13B-03, python-simplejson, xmlto, libxslt @@ -41,6 +42,7 @@ scalable implementation of an AMQP broker. %build cp %{S:2} %{_rabbit_wrapper} cp %{S:4} %{_rabbit_server_ocf} +cp %{S:5} %{_builddir}/rabbitmq-server-%{version}/README make %{?_smp_mflags} %install @@ -121,6 +123,7 @@ done %{_initrddir}/rabbitmq-server %config(noreplace) %{_sysconfdir}/logrotate.d/rabbitmq-server %doc LICENSE* +%doc README %doc docs/rabbitmq.config.example %clean diff --git a/packaging/common/README b/packaging/common/README new file mode 100644 index 0000000000..0a29ee2753 --- /dev/null +++ b/packaging/common/README @@ -0,0 +1,20 @@ +This is rabbitmq-server, a message broker implementing AMQP, STOMP and MQTT. + +Most of the documentation for RabbitMQ is provided on the RabbitMQ web +site. You can see documentation for the current version at: + +http://www.rabbitmq.com/documentation.html + +and for previous versions at: + +http://www.rabbitmq.com/previous.html + +Man pages are installed with this package. Of particular interest are +rabbitmqctl(1), to interact with a running RabbitMQ server, and +rabbitmq-plugins(1), to enable and disable plugins. These should be +run as the superuser. + +An example configuration file is provided in the same directory as +this README. Copy it to /etc/rabbitmq/rabbitmq.config to use it. The +RabbitMQ server must be restarted after changing the configuration +file or enabling or disabling plugins. diff --git a/packaging/debs/Debian/debian/rules b/packaging/debs/Debian/debian/rules index a1498979c3..b3c96069fe 100644 --- a/packaging/debs/Debian/debian/rules +++ b/packaging/debs/Debian/debian/rules @@ -9,6 +9,7 @@ RABBIT_BIN=$(DEB_DESTDIR)usr/lib/rabbitmq/bin/ DOCDIR=$(DEB_DESTDIR)usr/share/doc/rabbitmq-server/ DEB_MAKE_INSTALL_TARGET := install TARGET_DIR=$(RABBIT_LIB) SBIN_DIR=$(RABBIT_BIN) DOC_INSTALL_DIR=$(DOCDIR) MAN_DIR=$(DEB_DESTDIR)usr/share/man/ DEB_MAKE_CLEAN_TARGET:= distclean +DEB_INSTALL_DOCS_ALL=debian/README install/rabbitmq-server:: mkdir -p $(DOCDIR) diff --git a/src/rabbit_amqqueue.erl b/src/rabbit_amqqueue.erl index 8a84c9f4a6..8306f13461 100644 --- a/src/rabbit_amqqueue.erl +++ b/src/rabbit_amqqueue.erl @@ -466,10 +466,16 @@ check_dlxrk_arg({Type, _}, _Args) -> list() -> mnesia:dirty_match_object(rabbit_queue, #amqqueue{_ = '_'}). +%% Not dirty_match_object since that would not be transactional when used in a +%% tx context list(VHostPath) -> - mnesia:dirty_match_object( - rabbit_queue, - #amqqueue{name = rabbit_misc:r(VHostPath, queue), _ = '_'}). + mnesia:async_dirty( + fun () -> + mnesia:match_object( + rabbit_queue, + #amqqueue{name = rabbit_misc:r(VHostPath, queue), _ = '_'}, + read) + end). info_keys() -> rabbit_amqqueue_process:info_keys(). diff --git a/src/rabbit_channel.erl b/src/rabbit_channel.erl index dc37959bc8..a3a0c7543b 100644 --- a/src/rabbit_channel.erl +++ b/src/rabbit_channel.erl @@ -177,7 +177,8 @@ info_all(Items) -> refresh_config_local() -> rabbit_misc:upmap( - fun (C) -> gen_server2:call(C, refresh_config) end, list_local()), + fun (C) -> gen_server2:call(C, refresh_config, infinity) end, + list_local()), ok. ready_for_close(Pid) -> diff --git a/src/rabbit_exchange.erl b/src/rabbit_exchange.erl index fc13151958..bb5b63e912 100644 --- a/src/rabbit_exchange.erl +++ b/src/rabbit_exchange.erl @@ -244,10 +244,16 @@ lookup_or_die(Name) -> {error, not_found} -> rabbit_misc:not_found(Name) end. +%% Not dirty_match_object since that would not be transactional when used in a +%% tx context list(VHostPath) -> - mnesia:dirty_match_object( - rabbit_exchange, - #exchange{name = rabbit_misc:r(VHostPath, exchange), _ = '_'}). + mnesia:async_dirty( + fun () -> + mnesia:match_object( + rabbit_exchange, + #exchange{name = rabbit_misc:r(VHostPath, exchange), _ = '_'}, + read) + end). lookup_scratch(Name, App) -> case lookup(Name) of diff --git a/src/rabbit_file.erl b/src/rabbit_file.erl index 4cf314cae2..1a766b05b0 100644 --- a/src/rabbit_file.erl +++ b/src/rabbit_file.erl @@ -181,8 +181,8 @@ with_synced_copy(Path, Modes, Fun) -> {ok, Hdl} -> try Result = Fun(Hdl), - ok = prim_file:rename(Bak, Path), ok = prim_file:sync(Hdl), + ok = prim_file:rename(Bak, Path), Result after prim_file:close(Hdl) diff --git a/src/rabbit_limiter.erl b/src/rabbit_limiter.erl index 12a13c0011..22da465b88 100644 --- a/src/rabbit_limiter.erl +++ b/src/rabbit_limiter.erl @@ -197,24 +197,25 @@ start_link() -> gen_server2:start_link(?MODULE, [], []). new(Pid) -> %% this a 'call' to ensure that it is invoked at most once. - ok = gen_server:call(Pid, {new, self()}), + ok = gen_server:call(Pid, {new, self()}, infinity), #lstate{pid = Pid, prefetch_limited = false, blocked = false}. limit_prefetch(L, PrefetchCount, UnackedCount) when PrefetchCount > 0 -> - ok = gen_server:call(L#lstate.pid, - {limit_prefetch, PrefetchCount, UnackedCount}), + ok = gen_server:call( + L#lstate.pid, + {limit_prefetch, PrefetchCount, UnackedCount}, infinity), L#lstate{prefetch_limited = true}. unlimit_prefetch(L) -> - ok = gen_server:call(L#lstate.pid, unlimit_prefetch), + ok = gen_server:call(L#lstate.pid, unlimit_prefetch, infinity), L#lstate{prefetch_limited = false}. block(L) -> - ok = gen_server:call(L#lstate.pid, block), + ok = gen_server:call(L#lstate.pid, block, infinity), L#lstate{blocked = true}. unblock(L) -> - ok = gen_server:call(L#lstate.pid, unblock), + ok = gen_server:call(L#lstate.pid, unblock, infinity), L#lstate{blocked = false}. is_prefetch_limited(#lstate{prefetch_limited = Limited}) -> Limited. @@ -224,7 +225,8 @@ is_blocked(#lstate{blocked = Blocked}) -> Blocked. is_active(L) -> is_prefetch_limited(L) orelse is_blocked(L). get_prefetch_limit(#lstate{prefetch_limited = false}) -> 0; -get_prefetch_limit(L) -> gen_server:call(L#lstate.pid, get_prefetch_limit). +get_prefetch_limit(L) -> + gen_server:call(L#lstate.pid, get_prefetch_limit, infinity). ack(#lstate{prefetch_limited = false}, _AckCount) -> ok; ack(L, AckCount) -> gen_server:cast(L#lstate.pid, {ack, AckCount}). diff --git a/src/rabbit_mirror_queue_slave.erl b/src/rabbit_mirror_queue_slave.erl index 367269694c..6f78d1d2b5 100644 --- a/src/rabbit_mirror_queue_slave.erl +++ b/src/rabbit_mirror_queue_slave.erl @@ -293,32 +293,41 @@ handle_info({bump_credit, Msg}, State) -> handle_info(Msg, State) -> {stop, {unexpected_info, Msg}, State}. -%% If the Reason is shutdown, or {shutdown, _}, it is not the queue -%% being deleted: it's just the node going down. Even though we're a -%% slave, we have no idea whether or not we'll be the only copy coming -%% back up. Thus we must assume we will be, and preserve anything we -%% have on disk. terminate(_Reason, #state { backing_queue_state = undefined }) -> %% We've received a delete_and_terminate from gm, thus nothing to %% do here. ok; -terminate({shutdown, dropped} = R, #state { backing_queue = BQ, - backing_queue_state = BQS }) -> +terminate({shutdown, dropped} = R, State = #state{backing_queue = BQ, + backing_queue_state = BQS}) -> %% See rabbit_mirror_queue_master:terminate/2 + terminate_common(State), BQ:delete_and_terminate(R, BQS); -terminate(Reason, #state { q = Q, - gm = GM, - backing_queue = BQ, - backing_queue_state = BQS, - rate_timer_ref = RateTRef }) -> - ok = gm:leave(GM), - QueueState = rabbit_amqqueue_process:init_with_backing_queue_state( - Q, BQ, BQS, RateTRef, [], pmon:new(), dict:new()), - rabbit_amqqueue_process:terminate(Reason, QueueState); +terminate(shutdown, State) -> + terminate_shutdown(shutdown, State); +terminate({shutdown, _} = R, State) -> + terminate_shutdown(R, State); +terminate(Reason, State = #state{backing_queue = BQ, + backing_queue_state = BQS}) -> + terminate_common(State), + BQ:delete_and_terminate(Reason, BQS); terminate([_SPid], _Reason) -> %% gm case ok. +%% If the Reason is shutdown, or {shutdown, _}, it is not the queue +%% being deleted: it's just the node going down. Even though we're a +%% slave, we have no idea whether or not we'll be the only copy coming +%% back up. Thus we must assume we will be, and preserve anything we +%% have on disk. +terminate_shutdown(Reason, State = #state{backing_queue = BQ, + backing_queue_state = BQS}) -> + terminate_common(State), + BQ:terminate(Reason, BQS). + +terminate_common(State) -> + ok = rabbit_memory_monitor:deregister(self()), + stop_rate_timer(stop_sync_timer(State)). + code_change(_OldVsn, State, _Extra) -> {ok, State}. diff --git a/src/rabbit_policy.erl b/src/rabbit_policy.erl index db6d042bf1..cd55381a18 100644 --- a/src/rabbit_policy.erl +++ b/src/rabbit_policy.erl @@ -208,46 +208,25 @@ notify_clear(VHost, <<"policy">>, _Name) -> %%---------------------------------------------------------------------------- +%% [1] We need to prevent this from becoming O(n^2) in a similar +%% manner to rabbit_binding:remove_for_{source,destination}. So see +%% the comment in rabbit_binding:lock_route_tables/0 for more rationale. update_policies(VHost) -> - F = fun() -> - Policies = list_tx(VHost), - Xs = mnesia:match_object( - rabbit_exchange, - #exchange{name = rabbit_misc:r(VHost, exchange), - _ = '_'}, - read), - Qs = mnesia:match_object( - rabbit_queue, - #amqqueue{name = rabbit_misc:r(VHost, queue), - _ = '_'}, - read), - {[update_exchange(X, Policies) || X <- Xs], - [update_queue(Q, Policies) || Q <- Qs]} - end, - {Xs, Qs} = rabbit_misc:execute_mnesia_transaction(F), + Tabs = [rabbit_queue, rabbit_durable_queue, + rabbit_exchange, rabbit_durable_exchange], + {Xs, Qs} = rabbit_misc:execute_mnesia_transaction( + fun() -> + [mnesia:lock({table, T}, write) || T <- Tabs], %% [1] + Policies = list(VHost), + {[update_exchange(X, Policies) || + X <- rabbit_exchange:list(VHost)], + [update_queue(Q, Policies) || + Q <- rabbit_amqqueue:list(VHost)]} + end), [catch notify(X) || X <- Xs], [catch notify(Q) || Q <- Qs], ok. -list_tx(VHost) -> - [p(P, fun ident/1) || P <- list_p(VHost, <<"policy">>)]. - -list_p(VHost, Component) -> - case VHost of - '_' -> ok; - _ -> rabbit_vhost:assert(VHost) - end, - Match = #runtime_parameters{key = {VHost, Component, '_'}, _ = '_'}, - [p_p(P) || #runtime_parameters{key = {_VHost, Comp, _Name}} = P <- - mnesia:match_object(rabbit_runtime_parameters, Match, read), - Comp =/= <<"policy">> orelse Component =:= <<"policy">>]. - -p_p(#runtime_parameters{key = {VHost, Component, Name}, value = Value}) -> - [{vhost, VHost}, - {component, Component}, - {name, Name}, - {value, Value}]. - update_exchange(X = #exchange{name = XName, policy = OldPolicy}, Policies) -> case match(XName, Policies) of OldPolicy -> no_change; diff --git a/src/rabbit_runtime_parameters.erl b/src/rabbit_runtime_parameters.erl index c13c333ed4..bcde0078f6 100644 --- a/src/rabbit_runtime_parameters.erl +++ b/src/rabbit_runtime_parameters.erl @@ -139,15 +139,21 @@ list() -> list(VHost) -> list(VHost, '_'). list_component(Component) -> list('_', Component). +%% Not dirty_match_object since that would not be transactional when used in a +%% tx context list(VHost, Component) -> - case VHost of - '_' -> ok; - _ -> rabbit_vhost:assert(VHost) - end, - Match = #runtime_parameters{key = {VHost, Component, '_'}, _ = '_'}, - [p(P) || #runtime_parameters{key = {_VHost, Comp, _Name}} = P <- - mnesia:dirty_match_object(?TABLE, Match), - Comp =/= <<"policy">> orelse Component =:= <<"policy">>]. + mnesia:async_dirty( + fun () -> + case VHost of + '_' -> ok; + _ -> rabbit_vhost:assert(VHost) + end, + Match = #runtime_parameters{key = {VHost, Component, '_'}, + _ = '_'}, + [p(P) || #runtime_parameters{key = {_VHost, Comp, _Name}} = P <- + mnesia:match_object(?TABLE, Match, read), + Comp =/= <<"policy">> orelse Component =:= <<"policy">>] + end). list_formatted(VHost) -> [pset(value, format(pget(value, P)), P) || P <- list(VHost)]. diff --git a/src/vm_memory_monitor.erl b/src/vm_memory_monitor.erl index a07f6c6545..369ec65596 100644 --- a/src/vm_memory_monitor.erl +++ b/src/vm_memory_monitor.erl @@ -221,11 +221,11 @@ get_vm_limit({win32,_OSname}) -> 8 -> 8*1024*1024*1024*1024 %% 8 TB for 64 bits 2^42 end; -%% On a 32-bit machine, if you're using more than 4 gigs of RAM you're +%% On a 32-bit machine, if you're using more than 2 gigs of RAM you're %% in big trouble anyway. get_vm_limit(_OsType) -> case erlang:system_info(wordsize) of - 4 -> 4*1024*1024*1024; %% 4 GB for 32 bits 2^32 + 4 -> 2*1024*1024*1024; %% 2 GB for 32 bits 2^31 8 -> 256*1024*1024*1024*1024 %% 256 TB for 64 bits 2^48 %%http://en.wikipedia.org/wiki/X86-64#Virtual_address_space_details end. |
