Просмотр исходного кода

Stop/restart acceptors during the upgrade process

Loïc Hoguin 5 лет назад
Родитель
Сommit
19696a7e5b
2 измененных файлов с 33 добавлено и 2 удалено
  1. 6 2
      src/ranch.appup
  2. 27 0
      src/ranch.erl

+ 6 - 2
src/ranch.appup

@@ -3,6 +3,7 @@
 
 {"2.0.0-rc.2",
 	[{<<"2\\.0\\.[0-9]+.*">>, [
+		{apply, {ranch, stop_all_acceptors, []}},
 		{load_module, ranch},
 		{load_module, ranch_acceptor},
 		{update, ranch_acceptors_sup, supervisor},
@@ -19,9 +20,11 @@
 		{load_module, ranch_ssl},
 		{update, ranch_sup, supervisor},
 		{load_module, ranch_tcp},
-		{load_module, ranch_transport}
+		{load_module, ranch_transport},
+		{apply, {ranch, restart_all_acceptors, []}}
 	]}],
 	[{<<"2\\.0\\.[0-9]+.*">>, [
+		{apply, {ranch, stop_all_acceptors, []}},
 		{load_module, ranch},
 		{load_module, ranch_acceptor},
 		{update, ranch_acceptors_sup, supervisor},
@@ -38,6 +41,7 @@
 		{load_module, ranch_ssl},
 		{update, ranch_sup, supervisor},
 		{load_module, ranch_tcp},
-		{load_module, ranch_transport}
+		{load_module, ranch_transport},
+		{apply, {ranch, restart_all_acceptors, []}}
 	]}]
 }.

+ 27 - 0
src/ranch.erl

@@ -19,6 +19,8 @@
 -export([stop_listener/1]).
 -export([suspend_listener/1]).
 -export([resume_listener/1]).
+-export([stop_all_acceptors/0]).
+-export([restart_all_acceptors/0]).
 -export([child_spec/5]).
 -export([handshake/1]).
 -export([handshake/2]).
@@ -192,6 +194,31 @@ maybe_resumed({ok, _, _}) ->
 maybe_resumed(Res) ->
 	Res.
 
+-spec stop_all_acceptors() -> ok.
+stop_all_acceptors() ->
+	_ = [ok = do_acceptors(Pid, terminate_child)
+		|| {_, Pid} <- ranch_server:get_listener_sups()],
+	ok.
+
+-spec restart_all_acceptors() -> ok.
+restart_all_acceptors() ->
+	_ = [ok = do_acceptors(Pid, restart_child)
+		|| {_, Pid} <- ranch_server:get_listener_sups()],
+	ok.
+
+do_acceptors(ListenerSup, F) ->
+	ListenerChildren = supervisor:which_children(ListenerSup),
+	case lists:keyfind(ranch_acceptors_sup, 1, ListenerChildren) of
+		{_, AcceptorsSup, _, _} when is_pid(AcceptorsSup) ->
+			AcceptorChildren = supervisor:which_children(AcceptorsSup),
+			%% @todo What about errors?
+			_ = [supervisor:F(AcceptorsSup, AcceptorId)
+				|| {AcceptorId, _, _, _} <- AcceptorChildren],
+			ok;
+		{_, Atom, _, _} ->
+			{error, Atom}
+	end.
+
 -spec child_spec(ref(), module(), opts(), module(), any())
 	-> supervisor:child_spec().
 child_spec(Ref, Transport, TransOpts0, Protocol, ProtoOpts) ->