Initial caching decorator for HttpRequestExecutors.#27
Conversation
|
I've created an initial FTR, the basic idea is to write the relevant request data and the cached response data in a simple format to a stream and de-serialize it when necessary. Everything below To use the decorator you would do something like this: |
|
Also, I'm not 100% sure if it's a good idea to make this a separate module. Would you say it's better if this goes to the decorators module? |
|
Wow, you just wrote a whole module :) I looked into it, here are the things I noted, any of them can easily be wrong of course, but I hope there is something useful among them: I think it's good as a separate module because it's big as you mentioned, so client doesn't need to bundle it if they only use Following for example. If it is stripped down by outsourcing some parts later, I guess it can still be moved to decorators that time if you see fit. Regarding the cache versioning, I think it could be a subdirectory instead of a file header (I think I saw this practice somewhere). And the version number could be handled by the I think it would be good if the file format was internal to a component that handles both reads and writes, so the format definition belongs to it, other implementations could use different ones. (Currently they are in Most of the existing code would go under it with a little refactor. In particular there may not be a need for Btw, I didn't understand how these conditions could be true if the cache entry was for that request, so I didn't included them above: I don't know if there is a need for clearing an entry, but a method could be added to
I am not sure I understand the question - do you mean that response parser used by let's say smoothsync api client, which would also be a general one, so it could be used at other places, too, could be used to parse the stored cached response as well? If yes, I guess it would make sense. |
I am not sure if you meant the serialization implementations or design, sorry that I only commented about the design. If that proposal makes sense I would start from that and after refactor, and I would expect serialization and deseralization coming under same class and then easier to see if there is anything to improve, reuse, change there. |
|
One more small note: |
|
I like the idea of adding an Also I prefer to keep the Keeping different versions of the cached files in different directories sounds nice, but is difficult do do. Mostly because the cache implementation doesn't know anything about the actual storage. The tests make sure that the cached request matches the sent request. The cache key is derived from a hash algorithm and while it's very unlikely that two different requests have the same key, it's still possible. The cache must always work correctly and should never return the wrong response for a request. These additional tests are cheap, so there is no reason not to perform them. Later on we may have to perform additional checks. Regarding Here is another design consideration: In certain scenarios the |
|
Ok, thanks for the further explanations and background. I see your points on keeping current About using the version for directory, it is a bit forced, but how about this: And the factory for Let me know if you would like me to check anything else. |
|
I think something like this should work for now: Not sure if that works but we could use the |
|
I probably don't know enough about the topic, but I am thinking about this use case to protect entries from eviction while request for them is ongoing.. I suppose they would happen very rarely in practice, right? But to make it correct, it affects design considerations now, so let's say 0.001% of calls affects the design (and general implementation) now, so I am thinking if it could be handled differently, like with retrying? So for ETAGs, when the cached response got evicted during the call, we would retry without the ETAG header to get a new response. It would make the logic for ETAG handling (an executor decorator?) a bit more complex, but it would be contained there, it wouldn't need to affect other components, design. I am also not sure how eviction is usually implemented, do you maybe have any plans for it? Something scheduled, or run after each call async, or at initialization? I like the separate |
|
About |
|
I don't have any specific plans for an eviction mechanism. But it surely depends on the algorithm if we need to worry about concurrent eviction. You're right about the URI parameter in the first method. We probably don't need it for the last one, because the response should already have it. |
385b7c9 to
16e709b
Compare
|
@dmfs I've reassigned this to you as I am not sure about the status of this. |
Implements #16