xfbs / diff.rs

Web application to render a diff between Rust crate versions. Implemented in Yew, runs fully in the browser as WebAssembly.
https://diff.rs
MIT License
86 stars 6 forks source link

Possible alternate caching solution #5

Closed 06chaynes closed 4 months ago

06chaynes commented 1 year ago

Really great project!

Thought I would suggest an alternate way to handle the HTTP request caching. I had started this branch here https://github.com/06chaynes/diff.rs/blob/add-caching/src/data.rs that sets up the reqwest client to use http-cache (full disclosure I'm the maintainer of this one) via reqwest-middleware. Other than testing, the component.rs file would need to be modified to call the fetch each time and allow the cache logic to be handled at the client level.

If you're interested I'd be happy to answer any questions, otherwise feel free to close this out!

xfbs commented 1 year ago

Hey, thanks so much!

This is really awesome. I figured there would be something more ergonomic than my makeshift little cache. I'll take this for a spin and see if I can get it merged in.

I do have a couple of questions about it!

06chaynes commented 1 year ago

Sounds good!

By default the cache will reside on the disk (in a directory called http-cacache in the working directory but that's customizable) so it can persist between reqwest clients, that's with the cacache CacheManager. If a disk based cache isn't an option you can use the Moka manager but that cache would require some more tweaks to implement as it is an in memory solution. I haven't really looked to deep at the code here yet, so I did operate under a few assumptions as to how this works and could easily be missing something.

I have barely scratched the surface on the WebAssembly stuff so I wouldn't be of much help there, does sound interesting though!. If either surf or reqwest can be used then I suppose it's possible this middleware could be as well, though it may require some modifications.

Edit: on the question of size management I think something custom would need to be written for the disk based cache. For Moka I think you can limit the total number of objects in the cache but there may be other options as well.

xfbs commented 1 year ago

Hey!

So... I went on a little bit of a deep-dive on this to try to figure out how to make things work. It's a bit more complex than things seem, but super interesting.

So, the code that powers diff.rs all runs fully inside the browser (via WebAssembly). Out-of-the-box, http_cache will not compile, because it depends on some crates that don't compile under WebAssembly.

The first crate that is problematic is reqwest-middleware, this one will not build within WebAssembly. The main reason why it will not build is that it expects some futures to be Send and Sync which they are not under WebAssembly (because it it single-threaded). So I went ahead and created a pull request which fixes that: https://github.com/TrueLayer/reqwest-middleware/pull/81.

I think http_cache itself can be similarly fixed by removing the Send and Sync bounds on the CacheManager trait and using async_trait(?Send) (both of these only when the target architecture is wasm32).

I think with this patch, it will be possible to get http_cache working in WASM, and it will even be possible to get IndexedDB working as a cache. That would make http_cache quite useful for other WebAssembly-based projects. I might look into this more tomorrow and see if I can come up with a prototype.

06chaynes commented 1 year ago

Going to do a bit of research on my end but that sounds good to me. I also saw the crate https://github.com/devashishdxt/idb and seems like that should work for the manager backend from what I can tell.

xfbs commented 4 months ago

Closing this due to inactivity, might revisit this at some point in the future!