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

[NotificationProducer] add pipeline support #708

Merged
merged 6 commits into from
Jan 30, 2023

Conversation

stepanblyschak
Copy link
Contributor

Added a pipeline support for NotificationProducer. NotificationProducer created with RedisPipeline will buffer published notifications untill a flush is called on RedisPipeline or RedisPipeline's command buffer is filled.

The motivation for this change is to optimize redis usage when using ResponsePublisher from sonic-swss for a lot of entries.

Signed-off-by: Stepan Blyschak <stepanb@nvidia.com>
Signed-off-by: Stepan Blyschak <stepanb@nvidia.com>
Signed-off-by: Stepan Blyschak <stepanb@nvidia.com>
Signed-off-by: Stepan Blyschak <stepanb@nvidia.com>
Signed-off-by: Stepan Blyschak <stepanb@nvidia.com>
@stepanblyschak
Copy link
Contributor Author

/azpw run

@mssonicbld
Copy link
Collaborator

/AzurePipelines run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@stepanblyschak
Copy link
Contributor Author

/azpw run

@mssonicbld
Copy link
Collaborator

/AzurePipelines run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@stepanblyschak
Copy link
Contributor Author

/azpw run

@mssonicbld
Copy link
Collaborator

/AzurePipelines run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@stepanblyschak
Copy link
Contributor Author

/azpw run

@mssonicbld
Copy link
Collaborator

/AzurePipelines run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@stepanblyschak
Copy link
Contributor Author

Fix for sairedis tests - sonic-net/sonic-sairedis#1169

@stepanblyschak
Copy link
Contributor Author

/azpw run

@mssonicbld
Copy link
Collaborator

/AzurePipelines run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@liat-grozovik
Copy link
Collaborator

@marian-pritsak @prsunny could you please help to review?

@@ -10,6 +10,7 @@ cc_library(
"common/*.hpp",
]),
copts = [
"-std=c++14",
Copy link
Contributor

@qiluo-msft qiluo-msft Jan 14, 2023

Choose a reason for hiding this comment

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

c++14

Other places are using c++11. Is it a concern?
Like: pyext/py3/Makefile.am
And sairedis using c++11 depends on swss-common. #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@qiluo-msft I don't see a problem. Everything builds successfully. I don't think other projects need to stay with c++11. c++14 has been around for a long time and adopted by compiler. As long as the headers are c++11 compatible and ABI does not change - everything works.

Copy link
Contributor

Choose a reason for hiding this comment

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

Is it a blocking issue?
If the change is really needed, I prefer changing the c++NN option in a consistent way, and change dependent libraries/applications first (swss->sairedis->swss-common). And change pyext/py[23]/Makefiles.am at the same time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sairedis is c++14 - https://github.com/sonic-net/sonic-sairedis/blob/master/configure.ac#L121
swss is c++14 - https://github.com/sonic-net/sonic-swss/blob/master/configure.ac#L57
I believe not every app using swss-common is now c++14, not to mention app extensions.
My point is that swss-common may use c++-14 in .cpp but must have c++-11 compatible headers for those apps that might not be able to migrate yet. Python swss-common bindings compile a wrapper cpp based of the headers, that's why py[23]/Makefile.am aren't changed and stay c++-11.

swss::NotificationProducer::NotificationProducer(swss::DBConnector *db, const std::string &channel):
m_db(db), m_channel(channel)
m_ownedpipe(std::make_unique<swss::RedisPipeline>(db, NON_BUFFERED_COMMAND_BUFFER_SIZE)), m_pipe(m_ownedpipe.get()), m_channel(channel), m_buffered(false)
Copy link
Contributor

@qiluo-msft qiluo-msft Jan 14, 2023

Choose a reason for hiding this comment

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

m_ownedpipe

You are assuming m_pipe initialized after m_ownedpipe initialized. The sequence is not well known knowledge. Suggest you move m_pipe to function body for simplicity purpose. #Closed

Copy link
Contributor Author

@stepanblyschak stepanblyschak Jan 14, 2023

Choose a reason for hiding this comment

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

@qiluo-msft The order of member initialization is defined by the standard and is well known. Member variables are initialized in the order they are defined in the class definition. If by any chance members are reordered in the definition any modern compiler will raise a warning (-Wreorder in gcc) and many of them should be treated as errors. Since we use -Wall + -Werror it is going to be catched.


if (m_buffered)
{
m_pipe->push(command, REDIS_REPLY_INTEGER);
Copy link
Contributor

@qiluo-msft qiluo-msft Jan 14, 2023

Choose a reason for hiding this comment

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

m_pipe

You may use m_ownedpipe directly. Are you defining two member variables for better performance? If yes, I prefer one variable for simplicity.
Then you can change var name to m_pipe. #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@qiluo-msft NotificationProducer has two invariants 1) Created from DBConnector and having it's own RedisPipeline in m_ownedpipe smart pointer and m_pipe pointing to it 2) NotificationProducer created from RedisPipeline which is not owned - m_ownedpipe is nullptr, m_pipe is a non-owning raw pointer to RedisPipeline object.
So, m_pipe is always pointing to RedisPipeline that needs to be used regardless of how NotificationProducer has been created.

I see the same pattern beeing used for Table class (https://github.com/sonic-net/sonic-swss-common/blob/master/common/table.cpp#L38) and it was a motivation to follow the same desing.

However, the table class uses raw pointer and manual memory allocation/deallocation + a flag to indicate wether we own the RedisPipeline object. So I came up with a bit simpler approach.


// if operating in buffered mode return -1 as we can't know the number
// of client's that have read the message immediately
return -1;
Copy link
Contributor

@qiluo-msft qiluo-msft Jan 14, 2023

Choose a reason for hiding this comment

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

-1

Is it better to use 1? Client will think it send it successsfully. #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@qiluo-msft As stated by the comment on send() method the return code does not indicate the success or failure but the number of clients that read the message. In buffered mode we can't imidatelly tell how many clients read the message, so returning 1 might fool the user of this API that his consumer has already read message.

@qiluo-msft
Copy link
Contributor

@bocon13 Could you also help review?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants