-
Notifications
You must be signed in to change notification settings - Fork 869
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
feat(AclFamily): load/store aclfile #1820
Conversation
src/facade/dragonfly_connection.cc
Outdated
dispatch_q_.push_front(std::move(msg)); | ||
// We need to reorder the queue, since multiple updates might happen before we | ||
// pop the message, invalidating the correct order since we always push at the front | ||
maybe_reorder_dispatch_q(std::move(msg)); |
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.
This was a bug if we pushed two messages one after the other before the queue is saturated (because the order would be messed up). This is fixed now :)
@@ -80,8 +80,8 @@ class Connection : public util::Connection { | |||
struct MonitorMessage : public std::string {}; | |||
|
|||
struct AclUpdateMessage { | |||
std::string_view username; | |||
uint64_t categories{0}; | |||
std::vector<std::string> username; |
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.
This was also a bug, std::string_view
could have been deleted if the queue item was not consumed and the string_view associated with the name got deallocated (e.g, user deletion)
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 remember I asked in the previous PR 😆
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 and I replied wrongly because I did not think about this case. It's fine, we caught it and I now know better.
P.s. you don't forget do you ? 👀
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.
No 🤣
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.
Just a few general comments 🧚🏻♂️
src/facade/dragonfly_connection.cc
Outdated
auto maybe_reorder_dispatch_q = [this](MessageHandle msg) { | ||
std::vector<MessageHandle> updates; | ||
while (std::holds_alternative<AclUpdateMessage>(dispatch_q_.front().handle)) { | ||
updates.push_back(std::move(dispatch_q_.front())); | ||
dispatch_q_.pop_front(); | ||
} | ||
updates.push_back(std::move(msg)); | ||
for (auto elem = updates.rbegin(); elem != updates.rend(); ++elem) { | ||
dispatch_q_.push_front(std::move(*elem)); | ||
} | ||
}; |
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.
you can insert into a deque with an iterator 🤓
@@ -80,8 +80,8 @@ class Connection : public util::Connection { | |||
struct MonitorMessage : public std::string {}; | |||
|
|||
struct AclUpdateMessage { | |||
std::string_view username; | |||
uint64_t categories{0}; | |||
std::vector<std::string> username; |
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 remember I asked in the previous PR 😆
src/server/acl/acl_family.cc
Outdated
auto acl_file = absl::GetFlag(FLAGS_aclfile); | ||
if (!acl_file.empty()) { | ||
Load({}, nullptr); | ||
} |
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.
If you don't want to add wrapper functions for this only case you can pass a capturing reply builder into ti
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.
But I suggest not to and instead make an error-reply returning internal function 🙂
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 just overloaded Load
:)
tests/dragonfly/acl_family_test.py
Outdated
@pytest.mark.asyncio | ||
async def test_bad_acl_file(df_local_factory): |
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.
you can use @dfly_args to pass an acl path
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.
and lets create a data folder inside the tests folder for your test acl configs
for (; it < dispatch_q_.end(); ++it) { | ||
if (!std::holds_alternative<AclUpdateMessage>(it->handle)) { | ||
break; | ||
} | ||
} |
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.
while (it < end && holds<Acl>(it)>) ++it
would be simpler 🙂
@@ -80,8 +80,8 @@ class Connection : public util::Connection { | |||
struct MonitorMessage : public std::string {}; | |||
|
|||
struct AclUpdateMessage { | |||
std::string_view username; | |||
uint64_t categories{0}; | |||
std::vector<std::string> username; |
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.
No 🤣
"aclfile": os.environ.get( | ||
"DRAGONFLY_PATH", os.path.join(SCRIPTS_DIR, "../../build-dbg/ok.acl") | ||
), |
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 meant keeping it inside the pytests folder... It looks kinda fragile. What if its not run from build-dbg? What if I want to edit it? Then I have to search it. And once I edit it the next re-build will overwrite it. So I need to update it in the src/folder... and re-build to apply 🤯
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.
Btw ok.acl is 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.
Btw ok.acl is empty
yes it's meant to be like that.
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.
It looks kinda fragile. What if its not run from build-dbg?
It is fragile but we use the exact same thing to run the tests so I guess it's fine ? (See df_factory
fixture)
Any other recommendation ?
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.
Also you can set the env variable DRAGONFLY_PATH which overwrites this, so it's fine. We do the exact same thing in the CI as well:
34 export DRAGONFLY_PATH="${GITHUB_WORKSPACE}/${{inputs.build-folder-name}}/${{inputs.dfly-executable}}"
void AclFamily::StreamUpdatesToAllProactorConnections(const std::vector<std::string>& user, | ||
const std::vector<uint32_t>& update_cat) { |
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.
This is called for load and acl changes that occur rarely right? If it ever becomes a bottleneck you can pass the message data inside a shared_ptr so you don't have to copy the vectors every time
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.
and single changes are now propagated with a vector...
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.
Single changes are indeed a vector with a single element, this is insignificant....
This is called for load and acl changes that occur rarely right? If it ever becomes a bottleneck you can pass the message data inside a shared_ptr so you don't have to copy the vectors every time
Yes but I don't think it will so I opted in for the simplest change!
void AclFamily::Load() { | ||
auto acl_file = absl::GetFlag(FLAGS_aclfile); | ||
LoadToRegistryFromFile(acl_file, true); | ||
} |
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.
So what if it fails? The instance will wrongfully start without acl
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.
Nope, it's fine, this is what Redis is doing. Otherwise we have to crash, I don't want to crash DF for that.
Moreover, you can set the ACL file dynamically, via CONFIG 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.
We issue a warning and that's enough information :)
template <typename T> | ||
std::variant<User::UpdateRequest, ErrorReply> ParseAclSetUser(T args, bool hashed = false) { |
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.
Small nit: Maybe use absl::Span<T>
Just a random thought, using the parser would solve the problem because it could hide the mutability (if an argslice constructor is added)
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 will refactor it at some point, I am expecting to add some changes here so I don't want to refactor right now
--aclfile
command@dranikpg
Feel free to review, but I would advice to do it tomorrow after I fix the tests.
Closes: #1807