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

Add config-read and run thread_birds with arguments. #265

Open
wants to merge 13 commits into
base: bird-import-proto
Choose a base branch
from

Conversation

Markuu-s
Copy link
Collaborator

No description provided.

Comment on lines +114 to +115
inline static const std::string socketStr = "socket";
inline static const std::string vrfStr = "vrf";
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
inline static const std::string socketStr = "socket";
inline static const std::string vrfStr = "vrf";
static constexpr auto socketStr = "socket";
static constexpr auto vrfStr = "vrf";

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

  1. "constexpr" doesn`t include "inline" in all compilers
  2. I thought about "constexpr" instead of "const" buf std::string doesn`t support it
  3. auto give us const char[N], I think in C++ it worst

Copy link
Collaborator

@ol-imorozko ol-imorozko Feb 4, 2025

Choose a reason for hiding this comment

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

  1. Yeah, I think we do need inline here because we need that field to be ODR-usable: link

A static data member may be declared inline. An inline static data member can be defined in the class definition and may specify an initializer. It does not need an out-of-class definition:

struct X
{
    inline static int fully_usable = 1; // No out-of-class definition required, ODR-usable
    inline static const std::string class_name{"X"}; // Likewise
 
    static const int non_addressable = 1; // C.f. non-inline constants, usable
                                          // for its value, but not ODR-usable
    // static const std::string class_name{"X"}; // Non-integral declaration of this
                                                 // form is disallowed entirely
};

We're binding it to a reference by passing it to exist function => ODR-usage => we must provide exactly one definition of that static data member in the entire program and the simplest way to do so -- use inline here.

  1. Yeah, that's correct. Here you can use std::string_view for string literals, but the issue with it is that nlohmann::json doesn't have an overload for operator[] with std::string_view. However, it does have overloads for std::string and const char*. So you could either use the change I suggested, or go with std::string_view and pass .data() like this:
if (exist(elemJson, BirdImport::socketStr))
{
    import.socket = elemJson[BirdImport::socketStr.data()];
}

if (exist(elemJson, BirdImport::vrfStr))
{
    import.vrf = elemJson[BirdImport::vrfStr.data()];
}

Either way works for me.

  1. Why do you think so? IMHO using array types isn't inherently bad in C++. It's quite common and valid (as long as we don't decay them into pointers and/or perform pointer arithmetic :) ). I don't see any issues with using array types in this context.

Comment on lines +956 to 964
for (auto& module : modules)
{
if (rib_t* rib = dynamic_cast<rib_t*>(module))
{
rib->bird_import_get();
rib->moduleStart();
}
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is every module is also a rib module? I don't quite understand.
Also, dynamic_cast will inevitably lead to some errors, if, for example, we decide to change class hierarchy.
Can we use other things here? Like maybe we can utilize one or two virtual functions?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

At this stage, I need to call one method that is only in rib_t (bird_import_get()), using a virtual function for all classes is somehow strange. I'll think about it, or I'm ready to discuss what's best.

Copy link
Collaborator

@ol-imorozko ol-imorozko Feb 4, 2025

Choose a reason for hiding this comment

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

modules is a vector of cModule pointers. So what you can do is add a new field to the class that will point to the required module, and here just call it's methods.
Something like an iterator to the modules will suffice (but be aware of invalidation). Or just a pointer/reference to rib_t.
Either way it's better than what we have how.

Copy link
Collaborator

@ol-imorozko ol-imorozko left a comment

Choose a reason for hiding this comment

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

We try to avoid "merge commits" in the history. You can simply squash that commit with "Add config-read and run thread_birds with arguments." In fact, commits like "Fix PR" are not desirable either. Commits should be self-contained, i.e., if you are improving/changing something after a review, it's better to introduce those changes within the commit itself. Here, you can just squash your four commits into one: "Add config-read and run thread_birds with arguments."

Also, could you please add a small description to commit body? It's hard to grasp what "run thread_birds with arguments" mean from commit title.

Comment on lines +209 to +217
if (exist(elemJson, BirdImport::socketStr))
{
import.socket = elemJson[BirdImport::socketStr];
}

if (exist(elemJson, BirdImport::vrfStr))
{
import.vrf = elemJson[BirdImport::vrfStr];
}
Copy link
Collaborator

@ol-imorozko ol-imorozko Feb 4, 2025

Choose a reason for hiding this comment

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

What if those keys do not exist? We need to use some default value then, right? Otherwise I think it will be two empty strings.
It's better to use value(const typename object_t::key_type& key, const ValueType& default_value) method of nlohmann::json like so:

Suggested change
if (exist(elemJson, BirdImport::socketStr))
{
import.socket = elemJson[BirdImport::socketStr];
}
if (exist(elemJson, BirdImport::vrfStr))
{
import.vrf = elemJson[BirdImport::vrfStr];
}
import.socket = elemJson.value(BirdImport::socketStr, "some_default_value");
import.vrf = elemJson.value(BirdImport::vrfStr, "some_default_value");

@stal76 stal76 force-pushed the bird-import-proto branch 5 times, most recently from 2416df2 to b12ac9a Compare February 13, 2025 08:34
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