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

feat [sc 106247]: Add a caching layer to prevent SDK from sending the same payloads too frequently upstream #193

Conversation

FourSigma
Copy link
Contributor

@FourSigma FourSigma commented Jun 26, 2024

What this PR does / why we need it:

Caching middleware helps rate limits intentional or unintentional spamming of endpoints.

  • Add caching middleware to endpoints
  • Prevents identical payloads from being send repeatedly upstream to replicated-app while preserving the client side UX

Which issue(s) this PR fixes:

Fixes #

Special notes for your reviewer:

Steps to reproduce

Does this PR introduce a user-facing change?


Does this PR require documentation?

@FourSigma FourSigma force-pushed the siva/sc-106247/sdk-sending-identical-events-too-frequently-cache-layer branch from e10bca8 to 33576b3 Compare June 26, 2024 15:36
@FourSigma FourSigma changed the title feat [sc 106247]: Add a caching layer to prevent SDK sending the same metrics too frequently feat [sc 106247]: Add a caching layer to prevent SDK from sending the same metrics too frequently Jun 26, 2024
@FourSigma FourSigma force-pushed the siva/sc-106247/sdk-sending-identical-events-too-frequently-cache-layer branch 7 times, most recently from 755dcac to 5aeba44 Compare June 26, 2024 18:25
@FourSigma FourSigma force-pushed the siva/sc-106247/sdk-sending-identical-events-too-frequently-cache-layer branch from 5aeba44 to 6073f9e Compare June 26, 2024 18:34
pkg/apiserver/server.go Outdated Show resolved Hide resolved
@marccampbell
Copy link
Member

Is there a reason we don't apply this to other methods in the API? If we do, this should be a middleware in the same implementation that gin middlewares work.

It's weird to me that we are returning "Served From Cache" when we rate limit in this method. I do like that we are including a custom header to indicate that the request was rate limited, but the served from cache is intended to mean that the API was disconnected. Will reusing this same header create a more difficult to debug scenario where the user can't tell if the API was down or they are sending too frequently? Continuing to make this return the same status code is great, don't 429 and push the issue to the developer.

@FourSigma FourSigma force-pushed the siva/sc-106247/sdk-sending-identical-events-too-frequently-cache-layer branch 2 times, most recently from 8a7cd44 to 1d0a0cd Compare June 27, 2024 00:49
@FourSigma FourSigma force-pushed the siva/sc-106247/sdk-sending-identical-events-too-frequently-cache-layer branch from 1d0a0cd to 246780e Compare June 27, 2024 00:52
pkg/handlers/middleware.go Outdated Show resolved Hide resolved
pkg/apiserver/server.go Outdated Show resolved Hide resolved
@FourSigma
Copy link
Contributor Author

FourSigma commented Jun 27, 2024

Is there a reason we don't apply this to other methods in the API? If we do, this should be a middleware in the same implementation that gin middlewares work.

It's weird to me that we are returning "Served From Cache" when we rate limit in this method. I do like that we are including a custom header to indicate that the request was rate limited, but the served from cache is intended to mean that the API was disconnected. Will reusing this same header create a more difficult to debug scenario where the user can't tell if the API was down or they are sending too frequently? Continuing to make this return the same status code is great, don't 429 and push the issue to the developer.

Good thought process @marccampbell . My initial reading of the issue was that we had a few delinquent endpoints (e.g custom-metrics) that needed to be "rate-limited" via a caching mechanism. The current closure implementation of the middleware allows each endpoint to have its own independent cache. Typing it out makes me thing that this might be unnecessary.

I can definitely change the cache header to be more unique. Do you some meaningful name suggestions already in mind? Fundamentally, we are serving cached data so I re-used the header. There is stdout logging to indicate that is being "rate limited", if that helps?

@FourSigma FourSigma force-pushed the siva/sc-106247/sdk-sending-identical-events-too-frequently-cache-layer branch 2 times, most recently from de3bf1a to ce88810 Compare June 27, 2024 14:48
@FourSigma FourSigma force-pushed the siva/sc-106247/sdk-sending-identical-events-too-frequently-cache-layer branch from ce88810 to ee11442 Compare June 27, 2024 14:55
@FourSigma FourSigma force-pushed the siva/sc-106247/sdk-sending-identical-events-too-frequently-cache-layer branch from 137c8e5 to 690b6b5 Compare June 27, 2024 15:15
@FourSigma FourSigma force-pushed the siva/sc-106247/sdk-sending-identical-events-too-frequently-cache-layer branch from 690b6b5 to 28bc4e7 Compare June 27, 2024 15:19
@FourSigma FourSigma changed the title feat [sc 106247]: Add a caching layer to prevent SDK from sending the same metrics too frequently feat [sc 106247]: Add a caching layer to prevent SDK from sending the same payloads too frequently Jun 27, 2024
@FourSigma FourSigma changed the title feat [sc 106247]: Add a caching layer to prevent SDK from sending the same payloads too frequently feat [sc 106247]: Add a caching layer to prevent SDK from sending the same payloads too frequently upstream Jun 27, 2024

cache.Set(key, CacheEntry{
StatusCode: recorder.StatusCode,
RequestBody: body,
Copy link
Member

Choose a reason for hiding this comment

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

we should consider making this a digest too because even without historical record this map can get big

divolgin
divolgin previously approved these changes Jun 27, 2024
@FourSigma
Copy link
Contributor Author

@divolgin (CC: @marccampbell ) I made a cached sub-router and added a X-Replicated-Rate-Limited header. Let me know what you all think.

@FourSigma FourSigma force-pushed the siva/sc-106247/sdk-sending-identical-events-too-frequently-cache-layer branch from 42d9e4c to 639acd8 Compare June 28, 2024 04:01
@FourSigma FourSigma force-pushed the siva/sc-106247/sdk-sending-identical-events-too-frequently-cache-layer branch from 639acd8 to a632f58 Compare June 28, 2024 04:03
@FourSigma FourSigma requested a review from divolgin June 28, 2024 13:37
@FourSigma FourSigma requested a review from sgalsaleh June 28, 2024 18:10
}
}

func IsSamePayload(a, b []byte) bool {
Copy link
Member

Choose a reason for hiding this comment

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

why not just use bytes.Equal?

Copy link
Contributor Author

@FourSigma FourSigma Jun 28, 2024

Choose a reason for hiding this comment

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

@sgalsaleh JSON key ordering differences when you marshal from map[string]interface{} results in different byte slices for the same payload. Also raw JSON payloads might have different white space with same underlying content.

@FourSigma FourSigma merged commit b536d1b into main Jul 1, 2024
11 checks passed
@FourSigma FourSigma deleted the siva/sc-106247/sdk-sending-identical-events-too-frequently-cache-layer branch July 1, 2024 20:46
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.

4 participants