Comments (4)
Hi @poisa, and thanks for your interest in Carlos!
let's see if I can answer your questions:
1st requirement: I'm afraid we don't offer a time-based expiration of items yet. This is a big limitation of Carlos at the moment that should be addressed with #89. I already had some ideas in mind how to design the feature, but didn't have time unfortunately to work on it. So short answer, yes you would need to build something on top on DiskCacheLevel
(that you can reuse anyway), that keeps track of the time each item was fetched. Not a blocker, but some amount of work on your part.
I would do it like this:
- Instantiate a
NetworkFetcher
- Instantiate a
DiskCacheLevel
- Transform the disk cache with a condition. In the condition closure you can check for the type of the object through the key (for example the last part of the URL or some similar logic to differ between images and JSON), and once you determine the type of the object, you could even inspect the file on disk (by leveraging the knowledge of how
DiskCacheLevel
stores files based on the hash of the key) to check its last modified timestamp. You can apply your custom expiration rules here and returnfalse
if needed, so that the whole disk level will fail - Build a composition of this newly created disk level with the network fetcher created at step 1
This will behave as described, although you would need to create the transformer/condition at step 3 manually.
2nd requirement: As you said, you can condition the network fetcher with a check for reachability. The problem is that this, together with the solution for the 1st requirement, would cause a cache miss if the item is older than your expiration time and the user is offline. To avoid this, you could directly apply the reachability check to the condition mentioned above, so that you don't check for the expiration time of an item if the user is offline (since we already know we are not going to fetch from the network anyway).
Another more convoluted option would be to switch the cache created for the 1st requirement, and the original disk level created at step 2 of the solution for the 1st requirement, and choose between the two depending on the reachability status. This way, if you are offline you directly route the request to the disk level only; if you are online, you route the request to the composed cache obtained as the solution of the 1st requirement. This is "more complex" but slightly better IMHO because you separate the concerns of the reachability rule and the expiration rule.
This would look like this:
The code would look something like this:
let oneHour = 60*60
let oneMonth = 30*24*oneHour
let disk = DiskCacheLevel<NSURL, NSData>()
let network = NetworkFetcher()
let conditionedDisk = disk.conditioned { URL in
if isImage(URL) {
return Future(!isOlderThan(URL, oneMonth))
} else if isJSON(URL) {
return Future(!isOlderThan(URL, oneHour))
} else {
return Future(true)
}
}
let onlineCache = conditionedDisk >>> network
let onlineCheck = switchLevels(onlineCache, cacheB: disk, switchClosure: { URL in
if isOnline() {
return .CacheA
} else {
return .CacheB
}
})
I hope this answers your questions, and you will be able to make an informed decision about whether to use Carlos or not!
from carlos.
I updated the answer since I first wrote it with more information, a diagram, and some pseudo code.
from carlos.
Wow, thanks for the prompt and detailed answer! With the info you provided I think I will be able to use Carlos in my upcoming project.
In my ideal cache interface I would love to do something along the lines of:
cache.set("test String", forKey: "key", withTimeout: 60)
// or
cache.setTimeout(60)
In my case not all JSON files will have the same expiration timeout but I think for the time being I can come up with some class that given a URL will return the appropriate timeout.
For the second requirement I like the second option better (switching levels) since, like you hinted, each cache will do less and the intent will be clearer.
I'll be working with this in the next few weeks (don't be surprised it I pop up around here with another question!).
Thanks!
from carlos.
No problem if you come up with more questions! I'll be happy to answer them.
I'm glad the answer clarified some things a bit more.
Regarding the ideal interface, I thought about the global timeout (cache.setTimeout(60)
) but that's quite complex when you think that this should work with every level that we ship out of the box, plus every custom level the user might build, plus any composition of the above.
Maybe the first option could be easier (cache.set("test string", forKey: "key", withTimeout: 60)
). I still have to think about it some more time and when the "Eureka" will come, I'll write a draft for it :)
Have a nice weekend!
from carlos.
Related Issues (20)
- Can't build with Carthage HOT 5
- Reify batchGetAll into a CacheLevel HOT 1
- Reify batchGetSome into a CacheLevel HOT 3
- Add identity cache (always missing) HOT 1
- Migrate to Swift 2.3 HOT 2
- Migrate to Swift 3 HOT 8
- why it always occur like this " No such module PiedPiper ?" HOT 2
- setDataAsync assigns a negative value to an UInt causing runtime crash HOT 1
- Support for Gloss (Moya) HOT 5
- Problem running Carlos.playground
- Logger level capitalization
- Using Carlos to cache videos HOT 18
- Force to fetch from networking always HOT 4
- How can i implement fetch and refresh using cache
- Swift 4 Support HOT 2
- Minor Compiler Warnings for Swift 4.2 HOT 1
- App Distribution with Carlos dependency fails because of embedded PiedPiper
- Custom Fetcher with high memory usage HOT 7
- How to remove specific Keys from the Cache without clearing all of them HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from carlos.