sonic-net / sonic-py-swsssdk

Python SONiC switch state service sdk
Other
13 stars 86 forks source link

Exception seen when trying to connect and database service is not responding #72

Open rajendra-dendukuri opened 4 years ago

rajendra-dendukuri commented 4 years ago
  1. Stop all services including database and verify that none of the containers are running.

root@sonic:/home/admin# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES root@sonic:/home/admin#

2 Now try to initiate a connection with retry option. A py exception is observed.

root@sonic:/home/admin# cat test.py

!/usr/bin/env python2.7

from swsssdk import SonicV2Connector

state_db = SonicV2Connector(host='17.0.0.1') state_db.connect(state_db.STATE_DB,True) root@sonic:/home/admin#

root@sonic:/home/admin# ./test.py Traceback (most recent call last): File "./test.py", line 5, in state_db.connect(state_db.STATE_DB,True) File "/usr/local/lib/python2.7/dist-packages/swsssdk/dbconnector.py", line 255, in connect super(SonicV2Connector, self).connect(db_id, retry_on) File "/usr/local/lib/python2.7/dist-packages/swsssdk/interface.py", line 169, in connect self._persistent_connect(db_id) File "/usr/local/lib/python2.7/dist-packages/swsssdk/interface.py", line 198, in _persistent_connect self.close(db_id) File "/usr/local/lib/python2.7/dist-packages/swsssdk/dbconnector.py", line 258, in close db_id = self.get_dbid(db_name) File "/usr/local/lib/python2.7/dist-packages/swsssdk/dbconnector.py", line 277, in get_dbid return SonicDBConfig.get_dbid(db_name, self.namespace) File "/usr/local/lib/python2.7/dist-packages/swsssdk/dbconnector.py", line 215, in get_dbid SonicDBConfig.db_name_validation(db_name, namespace) File "/usr/local/lib/python2.7/dist-packages/swsssdk/dbconnector.py", line 143, in db_name_validation raise RuntimeError(msg) RuntimeError: 6 is not a valid database name in configuration file root@sonic:/home/admin#

rajendra-dendukuri commented 4 years ago

@dzhangalibaba Can you please take a look at this.

diff --git a/src/swsssdk/interface.py b/src/swsssdk/interface.py
index a3a13cb..fa0d530 100644
--- a/src/swsssdk/interface.py
+++ b/src/swsssdk/interface.py
@@ -194,7 +194,7 @@ class DBInterface(object):
             except RedisError:
                 t_wait = self.CONNECT_RETRY_WAIT_TIME
                 logger.warning("Connecting to DB '{}' failed, will retry in {}s".format(db_id, t_wait))
-                self.close(db_id)
+                DBInterface.close(self, db_id)
dzhangalibaba commented 4 years ago

Thanks finding that, will raise a PR to fix it.

dzhangalibaba commented 4 years ago

please help review the fix

rajendra-dendukuri commented 4 years ago

Another related issue..

When the database docker is down, the sonic-db-cli eternally waits for a response. Whereas redis-cli immediately errors out. I think we would want to bring in this parity.

diff --git a/src/swsssdk/scripts/sonic-db-cli b/src/swsssdk/scripts/sonic-db-cli
index ecdaa62..454fb5b 100755
--- a/src/swsssdk/scripts/sonic-db-cli
+++ b/src/swsssdk/scripts/sonic-db-cli
@@ -64,11 +64,15 @@ def execute_cmd(dbname, cmd, namespace, use_unix_socket=False):
     else:
         dbconn = swsssdk.SonicV2Connector(use_unix_socket_path=True, namespace=namespace, decode_responses=True)
     try:
-        dbconn.connect(dbname)
+        dbconn.connect(dbname, retry_on=False)
     except RuntimeError:
         msg = "Invalid database name input : '{}'".format(dbname)
         print(msg, file=sys.stderr)
         sys.exit(1)
+    except Exception as e:
+        msg = "Failed to connect.\nException :'{}'".format(str(e))
+        print(msg, file=sys.stderr)
+        sys.exit(1)

Apart from the above, maybe add another -p option for a continuous retry? Comments?