Skip to content

stalePeriod clarification #283

Open
Open

Description

@nt4f04uNd

i used to think that maxAgeCacheObject, which was i guess replaced with stalePeriod worked like so:
we download file -> mark some expiry date for it -> when it's expired we redownload it

with current docs it seems that's not the case

/// Files are removed when they haven't been used for longer than [stalePeriod]
/// or when this cache has grown too big. When the cache is larger than [maxNrOfCacheObjects]

so if i have stalePeriod that equals to 1 day and user opens my app each 12 hours, for instance, and the file is being reused, my cache will never be invalidated? if that's true, how do i change this?

Activity

  1. renefloor commented on Feb 23, 2021

    @renefloor
    Contributor

    Yes, that's exactly why there was a rename with a better documentation. You can only control how long you want to have the file on disk. The server controls how long the image is valid using the cache-control max-age header. If you set the stalePeriod on 1 day, but the max-age is 2 hours the file can be served from cache after 4 hours, but the library will check at the server if there is a newer version of the file.

  2. nt4f04uNd commented on Feb 23, 2021

    @nt4f04uNd
    Author

    does flutter_cache_manager_firebase handle that? if i replace the file in storage it doesn't seem to refetch the new version of file

    (i use it for videos)

  3. renefloor commented on Feb 23, 2021

    @renefloor
    Contributor

    I don't know what kind of cache headers are set by firebase. You could check that using postman or something similar.

  4. nt4f04uNd commented on Feb 23, 2021

    @nt4f04uNd
    Author

    it sets max-age=0 by default. does it mean that file will be automatically replaced on update? (i'm currently migrating to newer version from maxAgeCacheObject)

  5. renefloor commented on Feb 23, 2021

    @renefloor
    Contributor

    Although the name changed the behaviour shouldn't have changed.

    When the max-age is 0 it uses a default period of 7 days, because most people will still want to have some cache.
    When setting the header to 'no-cache' it is really set to 0 seconds. You can see that code here: https://github.com/Baseflow/flutter_cache_manager/blob/develop/flutter_cache_manager/lib/src/web/file_service.dart#L87

  6. nt4f04uNd commented on Feb 23, 2021

    @nt4f04uNd
    Author

    i just tried setting the stalePeriod to 0, it doesn't work at all and never invalidates the cache

  7. renefloor commented on Feb 23, 2021

    @renefloor
    Contributor

    How did you test this?
    And it shouldn't invalidate the cache, just remove the files.

  8. nt4f04uNd commented on Feb 23, 2021

    @nt4f04uNd
    Author

    And it shouldn't invalidate the cache, just remove the files.

    yep, that's what i meant actually

    How did you test this?

    i have an app tied up with the firebase storage. i opened the file once in my app, then changed it in storage, then opened the file again and saw the same cached file, it was not refetched. i tried it multiple times and waited for a few minutes - cached files still weren't deleted, even after app restart

  9. nt4f04uNd commented on Feb 23, 2021

    @nt4f04uNd
    Author

    hmm, actually wait a bit, i will test it again

  10. renefloor commented on Feb 23, 2021

    @renefloor
    Contributor

    @nt4f04uNd I just did the following test:

    void main() {
      runApp(MyApp());
      checkCache();
    }
    
    Future<void> checkCache() async {
      var i = 0;
      while (i < 50) {
        CustomCacheManager.instance
            .getFileStream('https://via.placeholder.com/${(i % 5) + 1}',
                withProgress: false)
            .where((e) => e is FileInfo)
            .forEach((element) {
          var fileInfo = element as FileInfo;
          print("${fileInfo.originalUrl} from: ${fileInfo.source}");
        });
    
        await Future.delayed(Duration(seconds: secondsBetweenPulls));
        i++;
      }
    }
    
    class CustomCacheManager {
      static const key = 'customCacheObject';
      static CacheManager instance = CacheManager(Config(key,
          stalePeriod: Duration(seconds: stalePeriodInSeconds), maxNrOfCacheObjects: 1000));
    }
    

    Having the following settings it keeps the file in the cache:

    var secondsBetweenPulls = 1;
    var stalePeriodInSeconds = 30;
    
    I/flutter (30423): https://via.placeholder.com/1 from: FileSource.Cache
    I/flutter (30423): https://via.placeholder.com/2 from: FileSource.Cache
    I/flutter (30423): https://via.placeholder.com/3 from: FileSource.Cache
    I/flutter (30423): https://via.placeholder.com/4 from: FileSource.Cache
    I/flutter (30423): https://via.placeholder.com/5 from: FileSource.Cache
    I/flutter (30423): https://via.placeholder.com/1 from: FileSource.Cache
    I/flutter (30423): https://via.placeholder.com/2 from: FileSource.Cache
    I/flutter (30423): https://via.placeholder.com/3 from: FileSource.Cache
    I/flutter (30423): https://via.placeholder.com/4 from: FileSource.Cache
    I/flutter (30423): https://via.placeholder.com/5 from: FileSource.Cache
    

    The following settings doesn't keep the file in the cache:

    var secondsBetweenPulls = 10;
    var stalePeriodInSeconds = 10;
    
    I/flutter (30423): https://via.placeholder.com/1 from: FileSource.Cache
    I/flutter (30423): https://via.placeholder.com/2 from: FileSource.Cache
    I/flutter (30423): https://via.placeholder.com/3 from: FileSource.Online
    I/flutter (30423): https://via.placeholder.com/4 from: FileSource.Online
    I/flutter (30423): https://via.placeholder.com/5 from: FileSource.Online
    I/flutter (30423): https://via.placeholder.com/1 from: FileSource.Online
    
  11. nt4f04uNd commented on Feb 23, 2021

    @nt4f04uNd
    Author

    thanks for a great test, i can confirm it works for values you provided, but it doesn't work for me with these

    var secondsBetweenPulls = 120;
    var stalePeriodInSeconds = 120;

    i didn't really try to tweak them to some other values, but in my app when i set stalePeriod to two minutes or so, it simply doesn't work

    here's reproducible that uses your test https://github.com/nt4f04unds-archive/issues/tree/flutter_cache_manager_283

    use this command to clone it as it has a lot of branches

    git clone -b flutter_cache_manager_283 --single-branch git@github.com:nt4f04unds-archive/issues.git
    
    logs
    I/flutter (12918): https://via.placeholder.com/3 from: FileSource.Online
    I/flutter (12918): https://via.placeholder.com/3 from: FileSource.Cache
    I/flutter (12918): https://via.placeholder.com/3 from: FileSource.Cache
    I/flutter (12918): https://via.placeholder.com/3 from: FileSource.Cache
    I/flutter (12918): https://via.placeholder.com/3 from: FileSource.Cache
    I/flutter (12918): https://via.placeholder.com/3 from: FileSource.Cache
    
  12. renefloor commented on Feb 24, 2021

    @renefloor
    Contributor

    You changed the example from downloading 5 different images to only 'https://via.placeholder.com/3'. The library isn't continuously checking the cache, but only 10 seconds after something happened. So every time after you request this file it checks if it is recently used and it will never be stale (because you just requested it). If you change that file to 'https://via.placeholder.com/${(i % 5) + 1}' I expect it to work.

  13. nt4f04uNd commented on Mar 10, 2021

    @nt4f04uNd
    Author

    ok thanks for detailed explanations
    could you put those in documentation? this would be really helpful

  14. billyonggoorigaming commented on Mar 22, 2021

    @billyonggoorigaming

    The current documention says:

    When are the cached files updated?
    A valid url response should contain a Cache-Control header. More info on the header can be found here, but in summary it says for how long the image can be expected to be up to date. It also contains an 'eTag' which can be used to check (after that time) whether the file did change or if it is actually still valid.

    Following the provided link about Cache-Control header, we can see this:

    no-cache and max-age=0, must-revalidate indicates same meaning.
    Clients can cache a resource but must revalidate each time before using it. This means HTTP request occurs each time though, it can skip downloading HTTP body if the content is valid

    But for flutter_cache_manager it is:

    When the max-age is 0 it uses a default period of 7 days, because most people will still want to have some cache.
    When setting the header to 'no-cache' it is really set to 0 seconds.

    @renefloor
    Wouldn't it be better for max-age=0 to behave like what's written in the Mozilla's documentation, which has the same meaning to no-cache?

    If not, adding the default to 7 days to the documentation would be really helpful.

  15. renefloor commented on Mar 22, 2021

    @renefloor
    Contributor

    I agree that it should be better documented.
    I think max-age=0 is often set because devs just miss setting it. However, we got many complaints about the library not caching when we adhered to the 'max-age'. The Cache-Control: no-cache header is often added more deliberately in my experience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions