Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix #290: Add moderators specific rate limiting settings #294

Merged
merged 6 commits into from
Oct 29, 2023

Conversation

DavidKarlas
Copy link
Contributor

@DavidKarlas DavidKarlas commented Oct 28, 2023

This change removes transfer size rate limiting for moderator role users aka. DWG members.

I tried to make change as small as possible and not refactor much code.

User roles were fetch before to check if user can see redactions or not...

This change removes transfer size rate limiting for moderator role users aka. DWG members.
@tomhughes
Copy link
Contributor

I envisaged an ability to set a separate, higher, limit for moderators not to remove it all together.

Also this will need changing on the rails side as well to be consistent.

@DavidKarlas
Copy link
Contributor Author

Ok, I will update PR, should we go with fixed value like 5x or 10x, or should I introduce --moderatormultiplier?
Looks like Ruby side doesn't have rate limiting at all, do you want me to add it?

@tomhughes
Copy link
Contributor

I would suggest just having a second set of limit and burst values for moderators.

…ions

As suggested on initial pull request, added two new options `--moderator-ratelimit` and `--moderator-maxdebt`
Anywhere where `MAXDEBT`/`RATELIMIT` was present, I expanded using same pattern for `MODERATOR_MAXDEBT`/`MODERATOR_RATELIMIT`
@DavidKarlas
Copy link
Contributor Author

DavidKarlas commented Oct 28, 2023

Pushed changes, added --moderator-maxdebt and --moderator-ratelimit. Open to suggestions for better names.

@DavidKarlas DavidKarlas changed the title Fix #290: Remove transfer size limit for moderator Fix #290: Add moderators specific rate limiting settings Oct 28, 2023
…sec`

Feels a bit better, still wondering what better name than `standard` would be...
@DavidKarlas
Copy link
Contributor Author

DavidKarlas commented Oct 28, 2023

While working on this, I realized we are walking near limit which is 2GB(New default for moderators is 1GB, which is 4x of previous default of 250MB). How do we avoid problems? I see three options:

  • Switch to long(~doubles size of memcached memory)
  • throw exception if option value is bigger than 1.5GB
  • Change to uint and throw exception if option value is bigger than 3.5GB

@mmd-osm
Copy link
Collaborator

mmd-osm commented Oct 28, 2023

Switch to long(~doubles size of memcached memory)

I see another issue here. Since we're storing values in binary format in memcached, any change to the length would either require to purge the cache, or we need the implementation to deal with the previous 32 bit length, and a new 64 bit length.
Also, I'm not exactly clear what Rails is doing with rate limiting.

Then the rate limiting code is a bit dated, and test coverage isn't exactly perfect. Maybe we should think about how we could add some test for the new code. I'm ok with doing that later, if there's an urgent need to move this code to production.

@tomhughes
Copy link
Contributor

I think I was wrong about rails actually... I don't think we actually implement the rate limiting there.

src/process_request.cpp Outdated Show resolved Hide resolved
Switched to using global_setting and evaluate `user_roles.count(osm_user_role_t::moderator) > 0` just once
src/options.cpp Outdated Show resolved Hide resolved
@DavidKarlas
Copy link
Contributor Author

I will attempt to mock now() to unit test rate limitting.

@DavidKarlas
Copy link
Contributor Author

I wonder if I should rename:

global_settings::get_bytes_per_sec(moderator);
into
global_settings::get_ratelimiter_ratelimit(moderator);

and

global_settings::get_max_bytes(moderator);
into
global_settings::get_ratelimiter_maxdebt(moderator);
?

@mmd-osm
Copy link
Collaborator

mmd-osm commented Oct 28, 2023

Yes, I think that's a good idea. I was also a bit unhappy with the naming, because it's difficult to see that both are related to rate limiting.

@mmd-osm mmd-osm added this to the v0.8.9 milestone Oct 28, 2023
@mmd-osm mmd-osm linked an issue Oct 28, 2023 that may be closed by this pull request
@Zaczero
Copy link

Zaczero commented Oct 29, 2023

BTW, do you accept donations, @DavidKarlas? I really appreciate it when someone goes out of their way to help others.

@DavidKarlas
Copy link
Contributor Author

BTW, do you accept donations, @DavidKarlas? I really appreciate it when someone goes out of their way to help others.

Go here 😉

I pushed now renamed global settings and actually do parsing of options...
I tested this, checked via debugger that options are correctly applied, observed via JOSM that limits are never reached for moderator user... I'm pretty confident this change is good...

Now question... If we want to add test for this, I need guidance on how to mock time(NULL)
As far as I can see there are 2 ways, would like to hear more...

  1. I introduce new class for getting time that similar to the way null_rate_limiter vs. memcached_rate_limiter, this means that in main.cpp this would be created and passed to process_request(req, limiter, generator, route, *factory, update_factory.get(), oauth_store.get())
  2. Add time parameter to rate_limiter.check and rate_limiter.update that is epoch seconds and only unit tests rate_limiter and not rest of process_request logic like passing in correct bytes_written value...
  3. Third option?

If you want test let me know how to mock, or if you think this can be merged without test please review.
Thank you!

@Zaczero
Copy link

Zaczero commented Oct 29, 2023

Go here 😉

2nd time in a week? Give me a break!

@DavidKarlas
Copy link
Contributor Author

I wonder what would be implications of using req.get_current_time() which is set here:

std::chrono::system_clock::time_point now(std::chrono::system_clock::now());
req.set_current_time(now);

This would allow for easy mocking/calling of process_request similar to
process_request(req, limiter, generator, route, factory, nullptr, store);

@mmd-osm
Copy link
Collaborator

mmd-osm commented Oct 29, 2023

If you want test let me know how to mock, or if you think this can be merged without test please review.

I think I would need some time for a good idea how to test this. As mentioned earlier, I would be ok to do this later as a separate PR in this case.

src/options.cpp Outdated Show resolved Hide resolved
@mmd-osm mmd-osm merged commit 79a09fb into zerebubuth:master Oct 29, 2023
@DavidKarlas DavidKarlas deleted the removeRateLimitForMods branch October 29, 2023 17:59
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Increase (or remove) the rate limit for administrators/moderators
4 participants