-
Notifications
You must be signed in to change notification settings - Fork 259
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
chore: Handle too big CH payloads for caching #191
Conversation
Your Render PR Server URL is https://chproxy-pr-191.onrender.com. Follow its progress at https://dashboard.render.com/static/srv-cbba2pb0tnuvdk1hnv20. |
d4fb3c0
to
75de0c6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Guram,
I haven't reviewed your PR yet but you should add a description of this feature in the documentation otherwise it won't be used by chproxy users
Your Render PR Server URL is https://chproxy-pr-191.onrender.com. Follow its progress at https://dashboard.render.com/static/srv-cbbak6givq07b7e6n7d0. |
c6ec7c6
to
98be969
Compare
config/config.go
Outdated
@@ -32,6 +32,8 @@ var ( | |||
} | |||
|
|||
defaultExecutionTime = Duration(30 * time.Second) | |||
|
|||
defaultMaxPayloadSize = ByteSize(100000000) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't forget in the doc to talk about the default max value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nb: given what @Garnek20 saw in production (for the chatamart cluster), this default size is still to small. IHMO, if we want to have a transparent release (meaning a user that was not using this feature don't understand why some queries are not cached anymore), we should put a very high and unrealistic value like 1<<50.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sigua-cs Can you add a comment explaining why this value is set so high?
cache/async_cache.go
Outdated
@@ -20,6 +20,8 @@ type AsyncCache struct { | |||
TransactionRegistry | |||
|
|||
graceTime time.Duration | |||
|
|||
MaxPayloadSize int64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since the size must be positive, why not using a uint64 instead of an int64. I'm not sure but I think the ByteSize type is an alias of the uint64 type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, ByteSize is a custom type based on uint64. In the Cache struct maxPayloadSize is a ByteSize, also in the config defaultMaxPayloadSize is a ByteSize. The reason why in the AsyncCache struct it's int64 because we need compare it with the contentLength/bufferedRespWriter which is int64. There is a function which checks if the contentLength not greater than maxPayloadSize, and if the MaxPayloadSize is ByteSize we will need to convert it to int64 every time we check the contentLength
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still, I agree with @mga-chka we should not allow building a cache with negative value
utils.go
Outdated
|
||
func isToCache(length int64, s *scope) bool { | ||
maxPayloadSize := s.user.cache.MaxPayloadSize | ||
return length <= maxPayloadSize |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
open question: should we had some metrics in order to know the number of queries not cached because they're too big
I need to update the proxy.go according the latest fix version |
279785d
to
509048e
Compare
baaeb05
to
867d697
Compare
b719487
to
2e43b23
Compare
2e43b23
to
c1329fc
Compare
c1329fc
to
de46161
Compare
} | ||
} else { | ||
// Do not cache responses greater than max payload size. | ||
if contentLength > int64(s.user.cache.MaxPayloadSize) { | ||
cacheSkipped.With(labels).Inc() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add a test that will check that the maxpayloadSize works for a payload bigger and doesn't work for a payload smaller. One way to check it in the test would be to look at the cacheSkipped counter
main_test.go
Outdated
@@ -339,6 +374,39 @@ func TestServe(t *testing.T) { | |||
}, | |||
startHTTP, | |||
}, | |||
{ | |||
"http cache max payload size", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a good test but you should also add the test that will asses if when the maxPayloadSize is activated if a payload a smaller than the limit will be cached
3b196e8
to
c2a7319
Compare
1829ae8
to
3afaba7
Compare
main_test.go
Outdated
cachedData, err := cc.Get(key) | ||
|
||
if cachedData != nil || err == nil { | ||
t.Fatal("skipped response from cache is expected") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
t.Fatal("skipped response from cache is expected") | |
t.Fatal("response bigger than maxPayloadSize should not be cached") |
main_test.go
Outdated
path := fmt.Sprintf("%s/cache/%s", testDir, key.String()) | ||
if _, err := os.Stat(path); err != nil { | ||
t.Fatalf("err while getting file %q info: %s", path, err) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why should we do this check here? IMO it's irrelevant given we're retrieving from cache just after
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
proxy.go
Outdated
// Do not cache responses greater than max payload size. | ||
if contentLength > int64(s.user.cache.MaxPayloadSize) { | ||
cacheSkipped.With(labels).Inc() | ||
log.Debugf("%s: Request will not be cached. Content length (%d) is greater than max payload size (%d)", s, contentLength, s.user.cache.MaxPayloadSize) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's worth to place it as info log
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
} | ||
} else { | ||
// Do not cache responses greater than max payload size. | ||
if contentLength > int64(s.user.cache.MaxPayloadSize) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should complete ongoing transaction even if cache is being skipped
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
I also don't think distinguishing http vs https is necessary in tests. It's enough to test one given we're interested in checking for if max payload size is exceeded or not @sigua-cs |
3afaba7
to
33755b4
Compare
Removed HTTP tests. Only HTTPS will be used |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks @sigua-cs 🎉
Implements #143