summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.hgignore1
-rw-r--r--README2
-rwxr-xr-xcheck_xref20
-rw-r--r--ebin/rabbit_app.in4
-rw-r--r--packaging/RPMS/Fedora/rabbitmq-server.spec3
-rw-r--r--packaging/common/README20
-rw-r--r--packaging/debs/Debian/debian/rules1
-rw-r--r--src/rabbit_amqqueue.erl12
-rw-r--r--src/rabbit_channel.erl3
-rw-r--r--src/rabbit_exchange.erl12
-rw-r--r--src/rabbit_file.erl2
-rw-r--r--src/rabbit_limiter.erl16
-rw-r--r--src/rabbit_mirror_queue_slave.erl41
-rw-r--r--src/rabbit_policy.erl49
-rw-r--r--src/rabbit_runtime_parameters.erl22
-rw-r--r--src/vm_memory_monitor.erl4
16 files changed, 125 insertions, 87 deletions
diff --git a/.hgignore b/.hgignore
index cd017298ba..05850b030e 100644
--- a/.hgignore
+++ b/.hgignore
@@ -4,6 +4,7 @@ syntax: glob
*.swp
*.patch
*.orig
+*.tmp
erl_crash.dump
deps.mk
diff --git a/README b/README
index 67e3a66ad6..90e99e622a 100644
--- a/README
+++ b/README
@@ -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.