Giter Club home page Giter Club logo

Comments (4)

vittoriom avatar vittoriom commented on June 10, 2024

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 return false 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:

alt

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.

vittoriom avatar vittoriom commented on June 10, 2024

I updated the answer since I first wrote it with more information, a diagram, and some pseudo code.

from carlos.

poisa avatar poisa commented on June 10, 2024

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.

vittoriom avatar vittoriom commented on June 10, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.