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 memcached #33

Merged
merged 12 commits into from
Feb 27, 2024
Merged

Add memcached #33

merged 12 commits into from
Feb 27, 2024

Conversation

leeym
Copy link
Collaborator

@leeym leeym commented Feb 23, 2024

This PR is to add support for memcached, including:

  • LockMemcached
  • ConcurrentBufferMemcached
  • TokenBucketMemcached
  • LeakyBucketMemcached
  • FixedWindowCached
  • SlidingWindowMemcached

Copy link

codecov bot commented Feb 23, 2024

Codecov Report

Attention: Patch coverage is 85.61404% with 41 lines in your changes are missing coverage. Please review.

Project coverage is 83.51%. Comparing base (bc191d0) to head (b3c4bf1).

Files Patch % Lines
leakybucket.go 78.57% 9 Missing and 3 partials ⚠️
concurrent_buffer.go 89.15% 7 Missing and 2 partials ⚠️
tokenbucket.go 83.92% 7 Missing and 2 partials ⚠️
slidingwindow.go 84.44% 5 Missing and 2 partials ⚠️
locks.go 82.35% 3 Missing ⚠️
fixedwindow.go 96.42% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #33      +/-   ##
==========================================
+ Coverage   83.00%   83.51%   +0.50%     
==========================================
  Files          10       10              
  Lines        1183     1468     +285     
==========================================
+ Hits          982     1226     +244     
- Misses        137      169      +32     
- Partials       64       73       +9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@leeym leeym force-pushed the add-memcached branch 3 times, most recently from 273c9b4 to b2ed121 Compare February 23, 2024 05:21
@leeym leeym marked this pull request as ready for review February 23, 2024 06:55
@leeym leeym mentioned this pull request Feb 23, 2024
concurrent_buffer.go Outdated Show resolved Hide resolved
concurrent_buffer.go Outdated Show resolved Hide resolved
Copy link
Owner

@mennanov mennanov left a comment

Choose a reason for hiding this comment

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

This is a great contribution! I left a few comments to address.
Thanks!

concurrent_buffer.go Outdated Show resolved Hide resolved
fixedwindow.go Outdated Show resolved Hide resolved
locks.go Outdated Show resolved Hide resolved
case <-done:
if err != nil {
if errors.Is(err, memcache.ErrNotStored) {
return s.Increment(ctx, prev, curr, ttl)
Copy link
Owner

Choose a reason for hiding this comment

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

It seems like we should return an error in this case and let the client decide how to handle it: otherwise we may end up in a loop

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The recursive Increment is trying to solve a race condition.

If two callers both Increment (line 195) at the same time while the counter doesn't exist, they both fail with ErrCacheMiss and Add (line 202) to initiate counter with value 1. Only one of them will succeed and the other will fail with ErrNotStored. The failing one can recursively call itself and do Increment (line 195) again, and the second time it should work as the counter is created already.

If you feel strongly against this implementation I can return error instead, otherwise I prefer to keep it as is.

Copy link
Owner

Choose a reason for hiding this comment

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

Could you please provide more details about this:

Only one of them will succeed and the other will fail with ErrNotStored.

How is it guaranteed that at most 1 client will be able to add the key to memcached?

Copy link
Collaborator Author

@leeym leeym Feb 26, 2024

Choose a reason for hiding this comment

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

Because we do not use Set to overwrite any existing data. Instead we use Add which stores only if it does not already exist.

case <-done:
if err != nil {
if errors.Is(err, memcache.ErrNotStored) {
return s.Increment(ctx, prev, curr, ttl)
Copy link
Owner

Choose a reason for hiding this comment

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

Could you please provide more details about this:

Only one of them will succeed and the other will fail with ErrNotStored.

How is it guaranteed that at most 1 client will be able to add the key to memcached?

locks.go Show resolved Hide resolved
@leeym leeym requested a review from mennanov February 26, 2024 03:22
locks.go Outdated Show resolved Hide resolved
@leeym leeym requested a review from mennanov February 26, 2024 17:29
Copy link
Owner

@mennanov mennanov left a comment

Choose a reason for hiding this comment

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

Very nice!
Thanks a lot for your work!

@mennanov mennanov merged commit 50bb6c3 into mennanov:master Feb 27, 2024
7 checks passed
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.

2 participants