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

[PINS] Add ConsumerNotifier for PINS response path #547

Closed
wants to merge 5 commits into from

Conversation

donNewtonAlpha
Copy link
Contributor

No description provided.

@qiluo-msft
Copy link
Contributor

Please change the PR title to more descriptive. People in the swss-common context do not know Pr3

common/dbconnector.cpp Outdated Show resolved Hide resolved
.bazelrc Outdated Show resolved Hide resolved
common/json.hpp Outdated
@@ -5394,7 +5394,7 @@ class basic_json
{
assert(lhs.m_value.array != nullptr);
assert(rhs.m_value.array != nullptr);
return *lhs.m_value.array < *rhs.m_value.array;
return (*lhs.m_value.array) < *rhs.m_value.array;
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 necessary change?

Copy link
Contributor

Choose a reason for hiding this comment

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

This is a fix from upstream: nlohmann/json#590

Copy link
Contributor

Choose a reason for hiding this comment

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

Addressed in #545

@qiluo-msft
Copy link
Contributor

qiluo-msft commented Nov 8, 2021

Please give a link to HLD for this change.

common/schema.h Outdated Show resolved Hide resolved
@kcudnik
Copy link
Contributor

kcudnik commented Nov 8, 2021

this seems to me to be too big change like for a single PR

BUILD Outdated
@@ -0,0 +1,31 @@
package(default_visibility = ["//visibility:public"])
Copy link
Contributor

Choose a reason for hiding this comment

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

Integrate Bazel build into PR checker (update the build pipeline) to help catch errors for breaking this in the future

Copy link
Contributor

Choose a reason for hiding this comment

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

Move to separate PR

@mint570
Copy link
Contributor

mint570 commented Nov 8, 2021

@qiluo-msft
About the performance impact we discussed in the meeting, this is only used in P4RT code currently. For existing SONiC codes, they are unchanged (They use the real class instead of the interface. So there shouldn't be performance impact.)

Also, the interface won't change the existing swss-common unit test. They still need to test with the Redis instance. The interface mocking is only helpful for testing codes that use the swss-common libraries. (Such as P4RT, so that P4RT does not need a Redis instance when doing unit test.)

@bocon13
Copy link
Contributor

bocon13 commented Nov 9, 2021

In modern C++, there is no performance penalty for virtual functions when the compiler can guarantee the runtime type. In our case, the implementation class can be inferred by the compiler, resulting in no additional instructions added by virtual.

The compiler option involved here is: -fdevirtualize which is automatically enabled at -O2.
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

The function may be inlined or called directly without a vtable lookup.

Here's a relevant blog post on the topic of virtual functions:
https://devblogs.microsoft.com/cppblog/the-performance-benefits-of-final-classes/

Anyway, I ran an experiment with and without virtual functions, and my implementation class (DBConnector) was NOT final. The result is effectively identical assembly code.

With virtual functions:

        call    std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<std::allocator<char> >(char const*, std::allocator<char> const&)
        mov     rsi, rsp
        mov     rdi, r12
        call    DBConnector::del(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
        mov     rdi, rsp
        mov     ebp, eax

Without virtual functions:

        call    std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<std::allocator<char> >(char const*, std::allocator<char> const&)
        mov     rsi, rsp
        mov     rdi, rbp
        call    DBConnector::del(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
        mov     rdi, rsp
        mov     r12d, eax

@@ -0,0 +1,32 @@
#pragma once
Copy link
Contributor

Choose a reason for hiding this comment

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

Qi concerned about performance penalty for virtual functions. Can this be done without this interface and virtual functions?

If this is needed for new feature, then it's okay. But we shouldn't incur a performance penalty just for testing.

Copy link
Contributor

@bocon13 bocon13 Nov 9, 2021

Choose a reason for hiding this comment

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

Update: See comment on main PR conversation regarding virtual functions: #547 (comment)

.bazelrc Outdated Show resolved Hide resolved
common/json.hpp Outdated
@@ -5394,7 +5394,7 @@ class basic_json
{
assert(lhs.m_value.array != nullptr);
assert(rhs.m_value.array != nullptr);
return *lhs.m_value.array < *rhs.m_value.array;
return (*lhs.m_value.array) < *rhs.m_value.array;
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a fix from upstream: nlohmann/json#590

bocon13 and others added 2 commits November 9, 2021 23:25
* Add ConsumerNotifier for response path
* Introduce interfaces for DBConnector, NotificationConsumer,
  ConsumerNotifier, NotificationProducer, ProducerStateTable
  to make it easier to test these classes

Submission containing materials of a third party:
    Copyright Google LLC; Licensed under Apache 2.0

Co-authored-by: Akarsh Gupta <[email protected]>
Co-authored-by: Ashish Singh <[email protected]>
Co-authored-by: Jay Hu <[email protected]>
Co-authored-by: Manali Kumar <[email protected]>
Co-authored-by: Richard Yu <[email protected]>
Co-authored-by: Robert J. Halstead <[email protected]>
Co-authored-by: Runming Wu <[email protected]>
Co-authored-by: Srikishen Pondicherry Shanmugam <[email protected]>
Co-authored-by: Vivek Ramamoorthy <[email protected]>
Co-authored-by: Yilan Ji <[email protected]>

Signed-off-by: Don Newton [email protected]
@donNewtonAlpha donNewtonAlpha changed the title Pr3 acl schema [PINS] Add ConsumerNotifier for PINS response path Nov 10, 2021
@donNewtonAlpha
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Commenter does not have sufficient privileges for PR 547 in repo Azure/sonic-swss-common

@@ -358,4 +358,9 @@ void ProducerStateTable::apply_temp_view()
m_tempViewActive = false;
}

std::string ProducerStateTable::get_table_name() const
Copy link
Contributor

Choose a reason for hiding this comment

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

This function does not add value, can you remove?

Copy link
Contributor

Choose a reason for hiding this comment

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

We use this in the P4RT server application.

@rhalstea what do you think?

Choose a reason for hiding this comment

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

It's useful at various points in P4RT App to know the table name. Particularly around logging. The function was added here to make it available as part of the interface.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's already defined in TableBase::getTableName(), and TableBase could be treated as an interface.

@@ -750,6 +751,19 @@ int64_t DBConnector::decr(const string &key)
return r.getContext()->integer;
}

#ifndef SWIG
std::unordered_map<std::string, std::string> DBConnector::hgetall(
Copy link
Contributor

Choose a reason for hiding this comment

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

hgetall

The template version is a general solution for all STL container types. Why we need to specialize it to unordered_map?

Copy link
Contributor

Choose a reason for hiding this comment

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

@rhalstea what do you think?

Choose a reason for hiding this comment

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

The templates didn't work with the virtual interfaces.

Where this is needed in the P4RT App could be updated to the Table class. We can remove this once that happens, but that change may be difficult with the MVP timelines. However, internally we do want it planned for the next push.

return false;
}
}
notification_consumer_->pop(op, data, values);
Copy link
Contributor

Choose a reason for hiding this comment

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

This logic is applicable to any Selectable or Select, which contains multiple Selectable. Could you move it to their class?

{

// Wrapper class to use swss::NotificationConsumer.
class ConsumerNotifierInterface
Copy link
Contributor

Choose a reason for hiding this comment

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

ConsumerNotifierInterface

I feel the *Interface classes just mark some functions as virtual. Can we remove all the classes?

Choose a reason for hiding this comment

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

We can, but the other issue these interface classes address is the base class constructors requiring a redis db to be active. If we remove this do you have any objections to having a protected constructor that doesn't initialize a redis connection?

@qiluo-msft
Copy link
Contributor

On the proposal of not adding virtual, I find a discussion https://stackoverflow.com/a/45636400/2514803. Will it help keep production code intact?


In reply to: 963804275

@@ -358,4 +358,9 @@ void ProducerStateTable::apply_temp_view()
m_tempViewActive = false;
}

std::string ProducerStateTable::get_table_name() const
{
return getTableName();
Copy link
Contributor

Choose a reason for hiding this comment

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

return

Please follow the code format convention in existing code. Such as 1. use 4-space indentation. 2. m_ prefix for non-public member variables.

@@ -199,11 +200,14 @@ class DBConnector : public RedisContext
ReturnType hgetall(const std::string &key);

#ifndef SWIG
std::unordered_map<std::string, std::string> hgetall(
Copy link
Contributor

@bocon13 bocon13 Nov 12, 2021

Choose a reason for hiding this comment

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

Qi's suggestion: make this a standalone function in sonic-pins; first parameter is DBConnector; implementation calls the template version.


bool WaitForNotificationAndPop(std::string &op, std::string &data, std::vector<FieldValueTuple> &values,
int64_t timeout_ms = 60000LL) override;

Copy link
Contributor

Choose a reason for hiding this comment

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

Robert's proposal

protected:
  ConsumerNotifier();  // used for testing

Alternative:

  • Provide a fake/mock DBConnector as a subclass and use that; need to create a testing only constructor there

@donNewtonAlpha
Copy link
Contributor Author

/azpw run

@mssonicbld
Copy link
Collaborator

/AzurePipelines run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@rhalstea
Copy link

@bocon13 @qiluo-msft

I've updated sonic-pins to include the fakes/mocks so this pull request shouldn't be needed anymore.

@donNewtonAlpha
Copy link
Contributor Author

donNewtonAlpha commented Nov 17, 2021 via email

@donNewtonAlpha
Copy link
Contributor Author

Closing PER @rhalstea (Google)

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.

None yet

8 participants