LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File 0233-ssh-Retry-and-exponentially-backoff-listener-restart.patch of Package erlang (Project home:Ledest:erlang:20)

From 7a86736c1e2bc0468acd18b1f84c7cbf055befc8 Mon Sep 17 00:00:00 2001
From: Hans Nilsson <hans@erlang.org>
Date: Tue, 6 Mar 2018 11:42:28 +0100
Subject: [PATCH] ssh: Retry and exponentially backoff listener restart

in case of eaddrinuse. This could happen if the acceptor process dies and is restarted immediatly.
---
 lib/ssh/src/ssh_acceptor.erl | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/lib/ssh/src/ssh_acceptor.erl b/lib/ssh/src/ssh_acceptor.erl
index d66a34c58a..27d4242dd4 100644
--- a/lib/ssh/src/ssh_acceptor.erl
+++ b/lib/ssh/src/ssh_acceptor.erl
@@ -86,7 +86,8 @@ acceptor_init(Parent, Port, Address, Opts, AcceptTimeout) ->
                     acceptor_loop(Callback, Port, Address, Opts, LSock, AcceptTimeout);
 
                 {error,_} -> % Not open, a restart
-                    {ok,NewLSock} = listen(Port, Opts),
+                    %% Allow gen_tcp:listen to fail 4 times if eaddrinuse:
+                    {ok,NewLSock} = try_listen(Port, Opts, 4),
                     proc_lib:init_ack(Parent, {ok, self()}),
                     Opts1 = ?DELETE_INTERNAL_OPT(lsocket, Opts),
                     {_, Callback, _} =  ?GET_OPT(transport, Opts1),
@@ -98,6 +99,19 @@ acceptor_init(Parent, Port, Address, Opts, AcceptTimeout) ->
     end.
 
 
+try_listen(Port, Opts, NtriesLeft) ->
+    try_listen(Port, Opts, 1, NtriesLeft).
+
+try_listen(Port, Opts, N, Nmax) ->
+    case listen(Port, Opts) of
+        {error,eaddrinuse} when N<Nmax ->
+            timer:sleep(10*N), % Sleep 10, 20, 30,... ms
+            try_listen(Port, Opts, N+1, Nmax);
+        Other ->
+            Other
+    end.
+
+
 request_ownership(LSock, SockOwner) ->
     SockOwner ! {request_control,LSock,self()},
     receive
-- 
2.16.2