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

isMenuItemsStale stalenessLevel issue #16

Open
bkai opened this issue May 20, 2013 · 0 comments
Open

isMenuItemsStale stalenessLevel issue #16

bkai opened this issue May 20, 2013 · 0 comments
Assignees

Comments

@bkai
Copy link

bkai commented May 20, 2013

Talking about ch24/iHotelApp/iHotelApp/ directory.

AppCache.m:

+(BOOL) isMenuItemsStale
{
...
NSString *archivePath = [[AppCache cacheDirectory] stringByAppendingPathComponent:@"MenuItems.archive"];    
NSTimeInterval stalenessLevel = [[[[NSFileManager defaultManager] attributesOfItemAtPath:archivePath error:nil] fileModificationDate] timeIntervalSinceNow];
...
}

stalenessLevel is computed from the time of the last modification of the corresponding data file. Thus, in order to have the correct time value, we need that every new data are written to local file as soon as we receive it from the remote engine in iHotelAppMenuViewController viewWillAppear method. But this is not done sooner than in viewWillDisappear method.

This "post-write" strategy is taken also in AppCache cacheData:toFile: method, where (see [leastRecentlyUsedCacheData writeToFile:archivePath atomically:YES];) the data gets written to disk only after it can't remain in memory any more.

When combined with "pre-write" stalenessLevel concept, some stale data are declared as not stale.

Fix is rather simple provided one caching strategy will be chosen as preferred.

Code excerpts follow.

iHotelAppMenuViewController:

-(void) viewWillAppear:(BOOL)animated {

  self.menuItems = [AppCache getCachedMenuItems];  
  [self.tableView reloadData];

  if([AppCache isMenuItemsStale] || !self.menuItems) {

    [AppDelegate.engine fetchMenuItemsOnSucceeded:^(NSMutableArray *listOfModelBaseObjects) {

      self.menuItems = listOfModelBaseObjects;
      [self.tableView reloadData];
    } onError:^(NSError *engineError) {
      [UIAlertView showWithError:engineError];
    }];
  }

  [super viewWillAppear:animated];
}

-(void) viewWillDisappear:(BOOL)animated {

  [AppCache cacheMenuItems:self.menuItems];
  [super viewWillDisappear:animated];
}

AppCache.m:

+(void) cacheData:(NSData*) data toFile:(NSString*) fileName
{
  [memoryCache setObject:data forKey:fileName];
  if([recentlyAccessedKeys containsObject:fileName])
  {
    [recentlyAccessedKeys removeObject:fileName];
  }

  [recentlyAccessedKeys insertObject:fileName atIndex:0];

  if([recentlyAccessedKeys count] > kCacheMemoryLimit)
  {
    NSString *leastRecentlyUsedDataFilename = [recentlyAccessedKeys lastObject];
    NSData *leastRecentlyUsedCacheData = [memoryCache objectForKey:leastRecentlyUsedDataFilename];
    NSString *archivePath = [[AppCache cacheDirectory] stringByAppendingPathComponent:fileName];  
    [leastRecentlyUsedCacheData writeToFile:archivePath atomically:YES];

    [recentlyAccessedKeys removeLastObject];
    [memoryCache removeObjectForKey:leastRecentlyUsedDataFilename];
  }
}

+(BOOL) isMenuItemsStale
{
  // if it is in memory cache, it is not stale
  if([recentlyAccessedKeys containsObject:@"MenuItems.archive"])
    return NO;

    NSString *archivePath = [[AppCache cacheDirectory] stringByAppendingPathComponent:@"MenuItems.archive"];  

  NSTimeInterval stalenessLevel = [[[[NSFileManager defaultManager] attributesOfItemAtPath:archivePath error:nil] fileModificationDate] timeIntervalSinceNow];

  return stalenessLevel > kMenuStaleSeconds;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants