http: use sync.Map for request-scoped vars#7595
Conversation
Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
There was a problem hiding this comment.
Thanks Mohammed. This is probably fine, however I worry that it's not really solving a deeper problem... I am suspicious of the concurrent use of a Request. I worry that it may enable/encourage behavior that is actually buggy in other ways. Like, this error could be a good canary for a bug / mishandling of values.
So, I will need to think on this. I'd like to know more about the upstream use case in the cache handler.
|
I think there are two separate concerns here. The immediate one is that this looks like only a partial migration from Separately, I share the concern that this may only be addressing one symptom. The cache-handler/Souin adapter appears to pass the original request into Souin then always forward that same original |
|
Yes, I tackled only 1 of the maps. This one is unexported, so it's easier to change. The others are exported directly as maps, i.e. marshalling directly onto them from JSON, and applying similar fix to them requires custom marshaller to avoid breaking existing config. I know stdlib copies the This is where Souin creates data race between upstream and cache: Maybe we should push the responsibility of ensuring thread-safety downstream? @darkweak, is it possible to re-architect this part of Souin so it relies on copies of |
I received a report of a
concurrent map read and map writefailure at this linecaddy/modules/caddyhttp/marshalers.go
Lines 43 to 45 in ffb6ab0
The only conceivable reason for it is due to how the cache handler creates data race between cache and upstream on the same
http.Requestobject. I cannot think of any other scenario. Whether it's truly the culprit or not, we can resolve it for all cases by usingsync.Map. I contemplated creating our own opaque map struct with a mutex, but the one of use cases listed insync.Mapdocumentation seems to apply to our scenario:Namely, the entry for a given key is written once and read many times. I searched the code base for
SetVarandGetVar. I don't see cases of overwrite, but there are a couple multipleGetVarfor the same key.Assistance Disclosure
No AI was used.