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

File cache #306

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open

File cache #306

wants to merge 25 commits into from

Conversation

pcantrell
Copy link
Member

@pcantrell pcantrell commented Apr 6, 2020

This PR adds a file-based cache implementation to Siesta. This will give most projects offline access & fast launch for almost free.

A word on why this is so compelling for Siesta: traditional HTTP caches (such as URLSession’s cache) exist to prevent requests for data that is still fresh (enough). This makes them good for reducing network traffic, but bad for offline access: it’s a strict choice between getting the cached data or the fresh network data. Worse yet, the API gets to make that choice for you based on (usually ill-behaved) HTTP headers!

Siesta’s architecture, however, makes it possible for a Resource to simultaneously have data and be in the midst of requesting data. This makes it possible for your app to launch with the last data it last had — no matter how old, you decide whether you want to show it — and show that stored data even as it is requesting fresh data, even if that request fails.

This all happens fairly transparently for Siesta apps. Called loadIfNeeded and you’ll get a newData(cache) event when the cached data arrives, then a newData(network) event if the load request succeeds. All you have to do is build your UI so that loading and network errors don’t completely obscure the UI, and bingo! offline access.

There is still documentation work and cleanup to do here, but the code on this branch should be ready to use in your project! I encourage Siesta users to try it and report back. Please give it a whirl! 🙏

To try it out:

service.configure {
    $0.pipeline[.rawData].cacheUsing {
        try FileCache<Data>(
            poolName: “some locally unique name for your API",
            dataIsolation: .perUser(identifiedBy: someUserSpecificValue))
    }
}

…or if you are using public data that can be shared across users of the app:

            dataIsolation: .sharedByAllUsers

This PR also fixes numerous subtle problems with the existing cache infrastructure. It’s long been possible roll your own persistent caching for Siesta, but it always involved a bit of per-project finagling. Improvements here should make custom caches both easier to write and easier to work with — most notably, caches now only apply to GET requests and do not apply to cross-resource requests with load(using:). These two gotchas were a common source of trouble with custom cache implementations.

Fixes #289. Fixes #291.

@pcantrell pcantrell added this to In progress in 1.6 Apr 8, 2020
@mgrider
Copy link

mgrider commented Aug 4, 2020

Is it possible to configure "heavy" resources (ie, RemoteImageView) to only try the network if there is nothing in cache?

@pcantrell
Copy link
Member Author

pcantrell commented Nov 1, 2020

Is it possible to configure "heavy" resources (ie, RemoteImageView) to only try the network if there is nothing in cache?

Yes, configuring expirationTime to a large value should give you the behavior you’re looking for:

RemoteImageView.defaultImageService.configure {
    $0.expirationTime = .infinity
}

…or:

myService.configure("**.png") {  // or whatever
    $0.expirationTime = .infinity
}

However, I don’t recommend that, because it prevents your server from ever being able to push a corrected image unless either something in your code does an explicit reload or the user deletes and reinstalls the app.

A better solution is to make sure your asset serve handles etags correctly and emits 304s when appropriate, because Siesta handles both of those things automatically (both the in-memory and file caches). So if your server does that, all images become lightweight zero-content-length responses unless they’ve changed.

@pcantrell pcantrell force-pushed the file-cache branch 2 times, most recently from 13076ff to 2751763 Compare October 24, 2021 02:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
1.6
  
In progress
Development

Successfully merging this pull request may close these issues.

Cached Resource timestamp refresh after loading File-based caching for Siesta
2 participants