Skip to content
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

Merged
merged 11 commits into from
Jul 24, 2020

Conversation

judyjoseph
Copy link
Collaborator

@judyjoseph judyjoseph commented Jul 9, 2020

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.

@judyjoseph judyjoseph marked this pull request as ready for review July 10, 2020 06:45
@@ -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);
Copy link
Contributor

@qiluo-msft qiluo-msft Jul 11, 2020

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

Copy link
Collaborator Author

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().

@@ -84,6 +104,7 @@ class DBConnector
redisContext *m_conn;
int m_dbId;
std::string m_dbName;
std::string m_nameSpace;
Copy link
Contributor

@qiluo-msft qiluo-msft Jul 11, 2020

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


namespace swss {

class DBConnector;

class SonicInstInfo
Copy link
Contributor

@qiluo-msft qiluo-msft Jul 11, 2020

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

class SonicInstInfo
{
public:
std::string socket;
Copy link
Contributor

@qiluo-msft qiluo-msft Jul 11, 2020

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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

camelCase will be better


In reply to: 453213014 [](ancestors = 453213014)

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);
Copy link
Contributor

@qiluo-msft qiluo-msft Jul 11, 2020

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

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,
Copy link
Contributor

@qiluo-msft qiluo-msft Jul 11, 2020

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

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,
Copy link
Contributor

@qiluo-msft qiluo-msft Jul 11, 2020

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

@qiluo-msft qiluo-msft requested a review from shi-su July 11, 2020 17:01
@qiluo-msft
Copy link
Contributor

qiluo-msft commented Jul 11, 2020

@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);
Copy link
Contributor

@qiluo-msft qiluo-msft Jul 11, 2020

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

Copy link
Contributor

@dzhangalibaba dzhangalibaba left a 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;
Copy link
Contributor

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 ?

Copy link
Collaborator Author

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 ?

Copy link
Contributor

@dzhangalibaba dzhangalibaba Jul 20, 2020

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.

@judyjoseph
Copy link
Collaborator Author

when to use m_global_init in get func ?

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.

qiluo-msft
qiluo-msft previously approved these changes Jul 20, 2020
Copy link
Contributor

@qiluo-msft qiluo-msft left a 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;
Copy link
Contributor

@dzhangalibaba dzhangalibaba Jul 20, 2020

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())
Copy link
Contributor

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.

Copy link
Collaborator Author

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 !

judyjoseph and others added 10 commits July 23, 2020 18:51
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()
@judyjoseph
Copy link
Collaborator Author

Rebased due to merge conflict .

Copy link
Contributor

@qiluo-msft qiluo-msft left a 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.

@qiluo-msft qiluo-msft merged commit c0ba527 into sonic-net:master Jul 24, 2020
@abdosi
Copy link
Contributor

abdosi commented Jul 26, 2020

@judyjoseph Please update submodule pointer of master for sonic-swss-common

abdosi pushed a commit that referenced this pull request Jul 26, 2020
* 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>
@judyjoseph
Copy link
Collaborator Author

@judyjoseph Please update submodule pointer of master for sonic-swss-common

@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.

@@ -73,32 +67,152 @@ void SonicDBConfig::initialize(const string &file)
}
}

string SonicDBConfig::getDbInst(const string &dbName)
void SonicDBConfig::initializeGlobalConfig(const string &file)
Copy link
Contributor

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.

Copy link
Collaborator Author

@judyjoseph judyjoseph Jul 27, 2020

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.

Copy link
Contributor

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)

https://github.com/judyjoseph/sonic-swss-common/blob/4be4c3970f8f70523ef85bc7e56b19f9b2d2b1d3/common/dbconnector.cpp#L336

Copy link
Collaborator Author

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().

Copy link
Contributor

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 ?

judyjoseph added a commit that referenced this pull request Aug 11, 2020
* 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.
judyjoseph added a commit that referenced this pull request Aug 12, 2020
abdosi added a commit that referenced this pull request Aug 19, 2020
@judyjoseph judyjoseph deleted the multi_ns_changes branch September 11, 2020 16:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants