If attempt to open non-blocking connection results with EINPROGRESS,
further polling will trigger DISCONNECT action in case of failures.
While handling this action, jsonrpc python library closes the
connection but does not change the current remote. This leads to
subsequent connection to the same remote. And the story starts from
the beginning producing infinite attempts to connect to a single
remote regardless of existense of others. Like this:

 reconnect | DBG | tcp:127.0.0.1:45932: entering BACKOFF
 reconnect | INFO | tcp:127.0.0.1:45932: connecting...
 reconnect | DBG | tcp:127.0.0.1:45932: entering CONNECTING
 poller | DBG | 999-ms timeout
 reconnect | INFO | tcp:127.0.0.1:45932: connection attempt timed out
 reconnect | DBG | tcp:127.0.0.1:45932: entering BACKOFF
 poller | DBG | 0-ms timeout
 reconnect | INFO | tcp:127.0.0.1:45932: connecting...
 <...>
 reconnect | DBG | tcp:127.0.0.1:45932: entering CONNECTING
 poller | DBG | 1999-ms timeout
 reconnect | INFO | tcp:127.0.0.1:45932: connection attempt timed out
 reconnect | INFO | tcp:127.0.0.1:45932: waiting 4 seconds before reconnect
 reconnect | DBG | tcp:127.0.0.1:45932: entering BACKOFF
 <...>

Fix that by always picking the new remote on disconnect.
This mimics the behaviour of jsonrpc C library.

Fixes "multiple remotes" tests on FreeBSD.

CC: Numan Siddique <nusid...@redhat.com>
Fixes: 31e434fc985c ("python jsonrpc: Allow jsonrpc_session to have more than 
one remote.")
Signed-off-by: Ilya Maximets <i.maxim...@samsung.com>
---
 python/ovs/jsonrpc.py | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/python/ovs/jsonrpc.py b/python/ovs/jsonrpc.py
index 4873cff98..cc7b2cd52 100644
--- a/python/ovs/jsonrpc.py
+++ b/python/ovs/jsonrpc.py
@@ -448,11 +448,14 @@ class Session(object):
             self.rpc.error(EOF)
             self.rpc.close()
             self.rpc = None
-            self.seqno += 1
         elif self.stream is not None:
             self.stream.close()
             self.stream = None
-            self.seqno += 1
+        else:
+            return
+
+        self.seqno += 1
+        self.pick_remote()
 
     def __connect(self):
         self.__disconnect()
@@ -472,6 +475,7 @@ class Session(object):
                 self.reconnect.listening(ovs.timeval.msec())
             else:
                 self.reconnect.connect_failed(ovs.timeval.msec(), error)
+                self.pick_remote()
 
         self.seqno += 1
 
@@ -508,7 +512,6 @@ class Session(object):
             if error != 0:
                 self.reconnect.disconnected(ovs.timeval.msec(), error)
                 self.__disconnect()
-                self.pick_remote()
         elif self.stream is not None:
             self.stream.run()
             error = self.stream.connect()
-- 
2.17.1

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to