-
Notifications
You must be signed in to change notification settings - Fork 272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DBConnector classes to understand the namespace. #364
Conversation
@@ -59,13 +78,14 @@ class DBConnector | |||
*/ | |||
DBConnector(int dbId, const std::string &hostname, int port, unsigned int timeout); | |||
DBConnector(int dbId, const std::string &unixPath, unsigned int timeout); | |||
DBConnector(const std::string &dbName, unsigned int timeout, bool isTcpConn = false); | |||
DBConnector(const std::string &dbName, unsigned int timeout, bool isTcpConn = false, const std::string &nameSpace = EMPTY_NAMESPACE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EMPTY_NAMESPACE [](start = 120, length = 15)
To make default value more efficient, check https://stackoverflow.com/a/32851509/2514803 #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Qi, have updated the #define EMPTY_NAMESPACE std::string().
common/dbconnector.h
Outdated
@@ -84,6 +104,7 @@ class DBConnector | |||
redisContext *m_conn; | |||
int m_dbId; | |||
std::string m_dbName; | |||
std::string m_nameSpace; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m_nameSpace [](start = 16, length = 11)
m_namespace or m_nsName (then getNamespace-> getNsName) #Closed
common/dbconnector.h
Outdated
|
||
namespace swss { | ||
|
||
class DBConnector; | ||
|
||
class SonicInstInfo |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SonicInstInfo [](start = 6, length = 13)
RedisInstInfo #Closed
common/dbconnector.h
Outdated
class SonicInstInfo | ||
{ | ||
public: | ||
std::string socket; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
socket [](start = 16, length = 6)
Please follow the names in config file "unixSocketPath" #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
common/dbconnector.h
Outdated
std::unordered_map<std::string, SonicDBInfo> &db_entry, | ||
std::unordered_map<int, std::string> &separator_entry); | ||
static void initialize(const std::string &file = DEFAULT_SONIC_DB_CONFIG_FILE, const std::string &nameSpace = EMPTY_NAMESPACE); | ||
static void initialize_global_config(const std::string &file = DEFAULT_SONIC_DB_GLOBAL_CONFIG_FILE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
initialize_global_config [](start = 16, length = 24)
initializeGlobalConfig #Closed
common/dbconnector.h
Outdated
static int getDbId(const std::string &dbName); | ||
static std::string getSeparator(const std::string &dbName); | ||
static std::string getSeparator(int dbId); | ||
static void parse_config(const std::string &file, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parse_config [](start = 16, length = 12)
Why public function? #Closed
common/dbconnector.h
Outdated
static int getDbId(const std::string &dbName); | ||
static std::string getSeparator(const std::string &dbName); | ||
static std::string getSeparator(int dbId); | ||
static void parse_config(const std::string &file, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parse_config [](start = 16, length = 12)
parseDatabaseConfig #Closed
@dzhangalibaba Please help review #Closed |
static std::string getDbInst(const std::string &dbName, const std::string &nameSpace = EMPTY_NAMESPACE); | ||
static int getDbId(const std::string &dbName, const std::string &nameSpace = EMPTY_NAMESPACE); | ||
static std::string getSeparator(const std::string &dbName, const std::string &nameSpace = EMPTY_NAMESPACE); | ||
static std::string getSeparator(int dbId, const std::string &nameSpace = EMPTY_NAMESPACE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getSeparator [](start = 23, length = 12)
Please cover new functionality in unit test. #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when to use m_global_init in get func ?
|
||
if(element["namespace"].empty()) | ||
{ | ||
ns_name = EMPTY_NAMESPACE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for the empty case, do we need set m_init somewhere ? otherwise, when using get func, it parse the database_config.json again ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here in this case when element["namespace"].empty(), I could add a check to see if the m_init flag is already set -- IF so don't do anything, as it is already loaded explicitly from database_config.json file earlier. Please let me know if this was what you were referring to ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw you added the m_init = true at the last. Just to confirm with you, database_global_config.json always has the namesapce EMPTY case in file, right ?
Thanks @abdosi for adding this as part of couple of fixes. Yes the database_global_config will have the first entry for the EMPTY namespace.
With the current approach using the flag m_init itself to cover the cases where initialization is already done once -- either with EMPTY namespace OR with a valid namespace name. m_global_init is getting used indirectly when a namespace argument is provided to initialize API. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check with other reviewers.
|
||
if(element["namespace"].empty()) | ||
{ | ||
ns_name = EMPTY_NAMESPACE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw you added the m_init = true at the last. Just to confirm with you, database_global_config.json always has the namesapce EMPTY case in file, right ?
Thanks @abdosi for adding this as part of couple of fixes. Yes the database_global_config will have the first entry for the EMPTY namespace.
local_file.append(dir_name); | ||
local_file.append(element["include"]); | ||
|
||
if(element["namespace"].empty()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw your changes, that fix one case, when initializeGlobalConfig() invoked first, initialize() won't parse empty case again. But when initialize() invoked first with empty namespace and then initializeGlobalConfig() is invoked, there is no check on m_init before handing empty case, double parsing again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, Dong -- I am currently adding that as well , thanks !
trying to try to connect multiple namespace DB. Signed-off-by: Abhishek Dosi <abdosi@microsoft.com>
It is helpful in application that are doing select and need to the event is generated from which DB and namespace so that any parituclar action can be taken if needed. Signed-off-by: Abhishek Dosi <abdosi@microsoft.com>
…torId() as it was clashing with swss::TableBase::getDbId()
418b541
to
4be4c39
Compare
Rebased due to merge conflict . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also check with other reviewers.
@judyjoseph Please update submodule pointer of master for sonic-swss-common |
* DBConnector classes to understand the namespace. * Updates to the initial commit * Updates for comments * Add UT tests for the namespace usecases * Updates to the unit tests * Derive the DIR of the config files from the file path itself. * Fixes when testing and trying to try to connect multiple namespace DB. * Added Support to get DB Id and DB Namespace from Selectable Object. It is helpful in application that are doing select and need to the event is generated from which DB and namespace so that any parituclar action can be taken if needed. * Review comments update, for the variable name. * Further fixes and updating unit tests * Renaming the newly added function in swss::RedisSelect to getDbConnectorId() as it was clashing with swss::TableBase::getDbId() Co-authored-by: Abhishek Dosi <abdosi@microsoft.com>
@abdosi , Will need to revert this commit temporarily - as this is causing a build issue in sonic-swss. This is the PR in swss to track that sonic-net/sonic-swss#1362. There are some test failures in swss which is preventing me from committing the fix. So please don't advance the submodule pointer in 201911 branch as well. |
This reverts commit c0ba527.
@@ -73,32 +67,152 @@ void SonicDBConfig::initialize(const string &file) | |||
} | |||
} | |||
|
|||
string SonicDBConfig::getDbInst(const string &dbName) | |||
void SonicDBConfig::initializeGlobalConfig(const string &file) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@judyjoseph Behavior is different when calling this api w.r.t sonic-py-swssdk for single-asic platforms.
In python version this is NOOP on single asic platforms but here it throws run-time exception of file not present.
I feel we should have same behavior.
For now we need to add check in caller to make sure to call this api for multi-asic platforms only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it is different here.
No need to explicitly call SonicDBConfig::initializeGlobalConfig API. If the user db_connects with a namespace parameter it loads the Global config file automatically (https://github.com/judyjoseph/sonic-swss-common/blob/4be4c3970f8f70523ef85bc7e56b19f9b2d2b1d3/common/dbconnector.cpp#L184)
The next time he calls it will be a NOOP as this variable m_global_init is set already. I felt this will be easier to user ?
If user needs to call this API SonicDBConfig::initializeGlobalConfig() explicitly he need to make sure the file exists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@judyjoseph
a) why it has to be different ? It has be consistent . Any particular reason why it need to be different ? Application should be doing same irrespective of library being used.
b)Also it does not work if we don't call SonicDBConfig::initializeGlobalConfig.
DBConnector Constructor with particular asic namespace gives seg fault
as SonicDBConfig::getDbId will fail since m_init will be set when call for host/global namespace and when next time called
it will not go for else condition (since m_init is already set)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok got the use-case, thanks ! here in this case the same application we invoke with the global namespace followed by the namespace specific ones. Will update to make it similar to how we have it in sonic-py-swssdk of explicitly calling SonicDBConfig::initializeGlobalConfig().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@judyjoseph is it possible to add test-case to cover above scenario ?
* Adding back PR#364 * Also changes to allign the dbConnector class here with that of sonic-py-swssdk 1. Ignore if the database_global.json file is not present. 2. validate the namespace before using it.
)" This reverts commit 1943e2b.
Why:
The dbconnector classes here need to understand the namespace, to connect to redis databases running in database containers in different linux network namespaces in case of multi-asic platforms.
What:
The class data structures are modified to handle the new dimension of namespace. New api's are added to parse the database_global.json file and to retrieve the list of namespaces + parse the respective database_config.json file. The namespaces will be ""(default namespace for the linux host) and "asic0", "aisic1" .... as present in the /var/run/redis/sonic-db/database_global.json file.
How verified:
Verification was done on a multi-asic platform with pmon scripts which uses swsscommon dbconnector classes.
Note : testcases to be updated, in this or in a follow up PR.