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

Improve ACL SETUSER Thread Handling Alternate Approach #1007

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

kevinmichaelbowersox
Copy link
Member

@kevinmichaelbowersox kevinmichaelbowersox commented Feb 9, 2025

This pull requests fixes issue #988 . Please see the detailed discussion provided in the issue for a deeper discussion of the problem this PR addresses.

Quick Problem Overview

The ACL SETUSER command may produce inconsistent results when multiple clients/threads attempt to concurrently modify the same user. Please find test cases in this PR that demonstrate the concurrency issues this PR addresses.

Solution Overview

This PR addresses the issue by implementing the following changes:

  • The ACL SETUSER implementation was modified to perform a thread-safe read, copy, replace sequence of the User. This avoids mangling of details about the User when under load and receiving simultaneous updates from multiple clients to update the same user.
  • A UserHandle object was introduced that is used for all access to a User and used for replacing the User with a modified version of the User object. Types that rely upon User obtain the UserHandle and then call GetUser to retrieve the most recent version of the user including any modifications. UserHandle provides a SetUser method that can perform a thread safe replacement of the User referred to by the UserHandle.
  • Updates to types that previously depended on User to now use UserHandle and UserHandle#GetUser().
  • Added a try-catch block in ACL SETUSER implementation that handles concurrent attempts to create the same user, avoiding an exception that was previously thrown when the user already existed in the map.
  • Updates to the AdminCommands to leverage the UserHandle for obtaining the User during access control decisions. See benchmarks below.

Testing and Verification

  • Added unit tests that repro the situation prior to making changes and verified existence of the issue.
  • Performed local testing manually to verify expected results used in test cases.
  • Verified new and existing tests passed once fix was implemented.

Other
Additional discussion regarding this issue can be seen in this draft PR where another solution was evaluated and discarded: #989

@kevinmichaelbowersox
Copy link
Member Author

Benchmark with Changes from SHA (977bcb4)

Method Params Mean Error StdDev Allocated
Set ACL 14.41 us 0.148 us 0.115 us -
SetEx ACL 20.03 us 0.064 us 0.060 us -
SetNx ACL 21.66 us 0.050 us 0.044 us -
SetXx ACL 23.39 us 0.064 us 0.057 us -
GetFound ACL 15.52 us 0.066 us 0.062 us -
GetNotFound ACL 10.66 us 0.022 us 0.021 us -
Increment ACL 22.12 us 0.049 us 0.043 us -
Decrement ACL 21.74 us 0.051 us 0.045 us -
IncrementBy ACL 26.26 us 0.123 us 0.116 us -
DecrementBy ACL 26.16 us 0.063 us 0.056 us -
Set AOF 21.32 us 0.096 us 0.085 us -
SetEx AOF 27.83 us 0.197 us 0.165 us -
SetNx AOF 28.04 us 0.225 us 0.211 us -
SetXx AOF 29.43 us 0.105 us 0.093 us -
GetFound AOF 15.84 us 0.028 us 0.025 us -
GetNotFound AOF 10.60 us 0.016 us 0.013 us -
Increment AOF 27.27 us 0.055 us 0.052 us -
Decrement AOF 28.56 us 0.071 us 0.063 us -
IncrementBy AOF 32.46 us 0.163 us 0.136 us -
DecrementBy AOF 34.28 us 0.182 us 0.170 us -
Set None 14.33 us 0.024 us 0.023 us -
SetEx None 19.56 us 0.049 us 0.046 us -
SetNx None 20.45 us 0.035 us 0.031 us -
SetXx None 23.25 us 0.066 us 0.055 us -
GetFound None 15.21 us 0.157 us 0.139 us -
GetNotFound None 11.03 us 0.020 us 0.019 us -
Increment None 22.11 us 0.084 us 0.074 us -
Decrement None 22.69 us 0.149 us 0.140 us -
IncrementBy None 27.65 us 0.133 us 0.118 us -
DecrementBy None 27.63 us 0.192 us 0.180 us -

@kevinmichaelbowersox
Copy link
Member Author

Baseline Benchmark from Main from SHA (61567d5)

Method Params Mean Error StdDev Allocated
Set ACL 14.10 us 0.043 us 0.034 us -
SetEx ACL 20.34 us 0.063 us 0.052 us -
SetNx ACL 20.31 us 0.064 us 0.057 us -
SetXx ACL 23.62 us 0.029 us 0.024 us -
GetFound ACL 15.57 us 0.040 us 0.036 us -
GetNotFound ACL 10.79 us 0.047 us 0.039 us -
Increment ACL 21.36 us 0.042 us 0.037 us -
Decrement ACL 21.76 us 0.062 us 0.052 us -
IncrementBy ACL 26.17 us 0.099 us 0.083 us -
DecrementBy ACL 25.66 us 0.045 us 0.035 us -
Set AOF 21.20 us 0.062 us 0.058 us -
SetEx AOF 27.06 us 0.091 us 0.081 us -
SetNx AOF 28.04 us 0.119 us 0.106 us -
SetXx AOF 26.79 us 0.060 us 0.056 us -
GetFound AOF 15.46 us 0.053 us 0.047 us -
GetNotFound AOF 11.10 us 0.058 us 0.051 us -
Increment AOF 26.50 us 0.065 us 0.061 us -
Decrement AOF 26.89 us 0.072 us 0.060 us -
IncrementBy AOF 31.63 us 0.138 us 0.129 us -
DecrementBy AOF 32.17 us 0.136 us 0.127 us -
Set None 14.61 us 0.035 us 0.033 us -
SetEx None 19.76 us 0.053 us 0.044 us -
SetNx None 20.95 us 0.027 us 0.024 us -
SetXx None 22.19 us 0.064 us 0.060 us -
GetFound None 15.60 us 0.013 us 0.011 us -
GetNotFound None 12.22 us 0.040 us 0.036 us -
Increment None 22.16 us 0.051 us 0.043 us -
Decrement None 21.95 us 0.016 us 0.013 us -
IncrementBy None 26.43 us 0.060 us 0.050 us -
DecrementBy None 26.95 us 0.074 us 0.065 us -

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.

1 participant