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

refactor storage implementation #243

Closed

Conversation

zufardhiyaulhaq
Copy link
Contributor

refactor storage implementation to use design pattern. this is also a step to implement rolling window support in #193

currently there is no unit test, let me know if this is make sense and I can write the unit test.

Signed-off-by: zufardhiyaulhaq [email protected]

Signed-off-by: zufardhiyaulhaq <[email protected]>
@zufardhiyaulhaq
Copy link
Contributor Author

@mattklein123 @nezdolik needs your help to review. I move all implementation details related to storage to StorageStrategy.

@nezdolik
Copy link
Member

Thanks @zufardhiyaulhaq, i will review shortly.

Copy link
Member

@nezdolik nezdolik left a comment

Choose a reason for hiding this comment

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

@zufardhiyaulhaq i've done first pass, will need to do one more. Please add unit/integration tests for this change.

package strategy

type StorageStrategy interface {
GetValue(key string) (uint64, error)
Copy link
Member

Choose a reason for hiding this comment

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

nit: add docs to interface methods

Copy link
Member

Choose a reason for hiding this comment

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

ping on this

// Now fetch the pipeline.
responseDescriptorStatuses := make([]*pb.RateLimitResponse_DescriptorStatus,
len(request.Descriptors))
for i, cacheKey := range cacheKeys {

limitAfterIncrease := results[i]
limitBeforeIncrease := limitAfterIncrease - hitsAddend
limitBeforeIncrease := uint32(results[i])
Copy link
Member

Choose a reason for hiding this comment

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

is this change intended? eg limitBeforeIncrease used to be results[i] - hitsAddend and with this change it will be uint32(results[i])

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes this is intended. since we are not increasing in this function, so it's should be the result that we get from redis. We will increase the value in increaseAsync function below.

@github-actions
Copy link

This pull request has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@github-actions github-actions bot added the stale label May 21, 2021
@mattklein123 mattklein123 self-assigned this May 25, 2021
Copy link
Member

@nezdolik nezdolik left a comment

Choose a reason for hiding this comment

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

@zufardhiyaulhaq PR mostly looks good to me (apart from missing tests). It's a large PR to review, but big part of it just moving code around, so functionality should remain the same.

s.RedisPerSecondType, s.RedisPerSecondUrl, s.RedisPerSecondPoolSize, s.RedisPerSecondPipelineWindow, s.RedisPerSecondPipelineLimit)
}
var otherPool Client
otherPool = NewClientImpl(srv.Scope().Scope("redis_pool"), s.RedisTls, s.RedisAuth, s.RedisType, s.RedisUrl, s.RedisPoolSize,
var otherPool storage_strategy.StorageStrategy
Copy link
Member

Choose a reason for hiding this comment

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

nit: use inline initialisation here

"github.com/mediocregopher/radix/v3"
)

type RedisClientInterface interface {
Copy link
Member

Choose a reason for hiding this comment

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

nit: add docs to interface methods

Copy link
Member

Choose a reason for hiding this comment

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

same here, comment repeats type name

"github.com/bradfitz/gomemcache/memcache"
)

type MemcachedClientInterface interface {
Copy link
Member

Choose a reason for hiding this comment

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

nit: add docs to interface methods

Copy link
Member

Choose a reason for hiding this comment

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

nit: this comment looks rudimentary, as it repeats the name of type, either add more explanatory comment or remove it.

// simply by incrementing it but memcached cannot. In memcache new keys need to be explicitly
// added.
package memcached_test

Copy link
Member

Choose a reason for hiding this comment

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

please add tests for refactored code

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi sorry for very slow resp, will start creating unit test for the code

Signed-off-by: zufardhiyaulhaq <[email protected]>
Signed-off-by: zufardhiyaulhaq <[email protected]>
Signed-off-by: zufardhiyaulhaq <[email protected]>
@zufardhiyaulhaq
Copy link
Contributor Author

@nezdolik need your help to review, rebase from master and add the unit test.

@nezdolik
Copy link
Member

@zufardhiyaulhaq somehow i missed your comment, i will review by start of next week.

Comment on lines +110 to 131
if this.perSecondClient != nil && cacheKey.PerSecond {
err := this.perSecondClient.IncrementValue(cacheKey.Key, uint64(hitsAddend))
if err != nil {
logger.Error(err)
}

err = this.perSecondClient.SetExpire(cacheKey.Key, uint64(expirationSeconds))
if err != nil {
logger.Error(err)
}
} else {
err := this.client.IncrementValue(cacheKey.Key, uint64(hitsAddend))
if err != nil {
logger.Error(err)
}

err = this.client.SetExpire(cacheKey.Key, uint64(expirationSeconds))
if err != nil {
logger.Error(err)
}
}
}
Copy link
Member

Choose a reason for hiding this comment

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

this section looks like duplicated code

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah but it's not, it's using different client to execute

Copy link
Member

@nezdolik nezdolik Jul 2, 2021

Choose a reason for hiding this comment

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

perhaps you could extract it to a function that accepts a client as argument?

client: client,
perSecondClient: perSecondClient,
jitterRand: jitterRand,
expirationJitterMaxSeconds: expirationJitterMaxSeconds,
Copy link
Member

Choose a reason for hiding this comment

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

so here we pass jitter settings both in base rate limiter and in fixedRateLimitCacheImpl, should stick to one class instead

if srv != "" {
client = newMemcachedClientFromSrv(scope, srv, srvRefresh, maxIdleConnection)
} else {

Copy link
Member

Choose a reason for hiding this comment

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

either remove empty block or put client initialization with hosts here

defer t.Stop()
for {
select {
case <-t.C:
Copy link
Member

Choose a reason for hiding this comment

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

not related to PR itself: i know this is Go convention, but is hard to read (if one is not familiar with Tickers in Go)

"github.com/bradfitz/gomemcache/memcache"
)

type MemcachedClientInterface interface {
Copy link
Member

Choose a reason for hiding this comment

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

nit: this comment looks rudimentary, as it repeats the name of type, either add more explanatory comment or remove it.

Copy link
Member

@nezdolik nezdolik 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 great refactoring, thank you. Added comments for bunch of nits, but overall makes sense to me. Would the next step be plugging different algorithms into storage strategy?

"github.com/mediocregopher/radix/v3"
)

type RedisClientInterface interface {
Copy link
Member

Choose a reason for hiding this comment

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

same here, comment repeats type name

"github.com/envoyproxy/ratelimit/src/storage/service"
)

type MemcachedStrategy struct {
Copy link
Member

Choose a reason for hiding this comment

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

nit: use compile time check if given type implements interface, example here: https://github.com/envoyproxy/ratelimit/blob/main/src/memcached/cache_impl.go#L55

"github.com/mediocregopher/radix/v3"
)

type RedisStrategy struct {
Copy link
Member

Choose a reason for hiding this comment

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

nit: use compile time check if given type implements interface, example here: https://github.com/envoyproxy/ratelimit/blob/main/src/memcached/cache_impl.go#L55

package strategy

type StorageStrategy interface {
GetValue(key string) (uint64, error)
Copy link
Member

Choose a reason for hiding this comment

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

ping on this

package strategy

// Interface to abstract underlying storage like memcached and redis
// Implement bussiness level where we don't care how underlying storage doing it.\
Copy link
Member

Choose a reason for hiding this comment

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

extra slash in the end?

@github-actions
Copy link

github-actions bot commented Aug 1, 2021

This pull request has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@github-actions github-actions bot added the stale label Aug 1, 2021
@github-actions
Copy link

github-actions bot commented Aug 8, 2021

This pull request has been automatically closed because it has not had activity in the last 37 days. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions!

@github-actions github-actions bot closed this Aug 8, 2021
@ysawa0 ysawa0 mentioned this pull request Dec 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants