From 8235aff75f7790754db6cba967d1c51527965455 Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Mon, 1 Apr 2024 18:07:52 -0400 Subject: [PATCH] Digital PCT265 story MVAPCT-48 - Added cache timing hacks --- .../MVMCoreLoadRequestOperation.m | 4 +++ .../MainProtocols/MVMCoreGlobalLoadProtocol.h | 3 ++ .../MVMCoreCache+Extension.swift | 31 +++++++------------ MVMCore/MVMCore/OtherHandlers/MVMCoreCache.h | 6 ++++ MVMCore/MVMCore/OtherHandlers/MVMCoreCache.m | 22 ++++++++++--- 5 files changed, 42 insertions(+), 24 deletions(-) diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m index 4d05abe..78108f9 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m @@ -443,6 +443,10 @@ NSDictionary *systemParameters = [jsonDictionary dict:KeySystemParameters]; loadObject.systemParametersJSON = systemParameters.count > 0 ? systemParameters : nil; + if ([[MVMCoreObject sharedInstance].globalLoadDelegate respondsToSelector:@selector(willProcessLoadObject:)]) { + [[MVMCoreObject sharedInstance].globalLoadDelegate willProcessLoadObject:loadObject]; + } + // module items are cached. MVMCoreErrorObject *moduleCachingError = nil; BOOL shouldContinue = [MVMCoreLoadRequestOperation cacheModules:modules loadObject:loadObject error:&moduleCachingError]; diff --git a/MVMCore/MVMCore/MainProtocols/MVMCoreGlobalLoadProtocol.h b/MVMCore/MVMCore/MainProtocols/MVMCoreGlobalLoadProtocol.h index 76fede6..93f1b23 100644 --- a/MVMCore/MVMCore/MainProtocols/MVMCoreGlobalLoadProtocol.h +++ b/MVMCore/MVMCore/MainProtocols/MVMCoreGlobalLoadProtocol.h @@ -41,6 +41,9 @@ /// Checks to see if the operation has content to show. - (BOOL)hasContentToShow:(nonnull MVMCoreLoadObject *)loadObject error:(nullable MVMCoreErrorObject *)error; +/// Notifies the delegate we are about to process the load object. +- (void)willProcessLoadObject:(nonnull MVMCoreLoadObject *)loadObject; + #if ENABLE_HARD_CODED_RESPONSE - (nullable NSDictionary *)getJSONForRequestParameters:(nonnull MVMCoreRequestParameters *)requestParameters; - (nonnull NSDictionary *)modifyJSON:(nonnull NSDictionary *)json; diff --git a/MVMCore/MVMCore/OtherHandlers/MVMCoreCache+Extension.swift b/MVMCore/MVMCore/OtherHandlers/MVMCoreCache+Extension.swift index fdbff0b..7210021 100644 --- a/MVMCore/MVMCore/OtherHandlers/MVMCoreCache+Extension.swift +++ b/MVMCore/MVMCore/OtherHandlers/MVMCoreCache+Extension.swift @@ -49,17 +49,17 @@ public class CachedData: Codable { @objc public class PersistentCacheManager: NSObject { @objc public static let shared = PersistentCacheManager() private let fileManager = FileManager.default - private lazy var cacheDirectory = { fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first!.appendingPathComponent("Atomic")}() + @objc public lazy var cacheDirectory = { fileManager.urls(for: .cachesDirectory, in: .userDomainMask).first!.appendingPathComponent("Atomic")}() private override init() {} - @objc public func save(data: [String: AnyHashable], forKey key: String, expirationDate: Date) throws { + @objc public func save(data: [String: AnyHashable], forKey key: String, path: URL, expirationDate: Date) throws { let cachedData = CachedData(data: data, expirationDate: expirationDate) - let filePath = self.filePath(forKey: key) do { - try FileManager.default.createDirectory(atPath: self.cacheDirectory.relativePath, withIntermediateDirectories: true, attributes: [.protectionKey: FileProtectionType.complete]) + try FileManager.default.createDirectory(atPath: path.deletingLastPathComponent().relativePath, withIntermediateDirectories: true, attributes: [.protectionKey: FileProtectionType.complete]) let dataToSave = try JSONEncoder().encode(cachedData) - try dataToSave.write(to: filePath, options: [.atomic, .completeFileProtection]) + try dataToSave.write(to: path, options: [.atomic, .completeFileProtection]) + MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: SAVED TO PERSISTENT CACHE, key:\(key), path:\(path)") } catch is EncodingError { throw CacheError.serializationFailed } catch { @@ -67,21 +67,20 @@ public class CachedData: Codable { } } - @objc public func load(forKey key: String) throws -> [String: AnyHashable] { - let filePath = self.filePath(forKey: key) + @objc public func load(forKey key: String, path: URL) throws -> [String: AnyHashable] { do { - let data = try Data(contentsOf: filePath) + let data = try Data(contentsOf: path) let decodedCachedData = try JSONDecoder().decode(CachedData.self, from: data) if Date() < decodedCachedData.expirationDate { - MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: LOADED FROM PERSISTENT CACHE, key:\(key)") + MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: LOADED FROM PERSISTENT CACHE, key:\(key), path:\(path)") return decodedCachedData.data } else { - MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: EXPIRED, key:\(key)") + MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: EXPIRED, key:\(key), path:\(path)") throw CacheError.dataExpired } } catch { // Remove item from the cache on any failure. - try fileManager.removeItem(at: filePath) + try fileManager.removeItem(at: path) switch error { case is DecodingError: @@ -98,15 +97,7 @@ public class CachedData: Codable { } @objc public func removeAll() throws { - let fileURLs = try fileManager.contentsOfDirectory( - at: cacheDirectory, - includingPropertiesForKeys: nil, - options: .skipsHiddenFiles - ) - - for fileURL in fileURLs where fileURL.pathExtension == "json" { - try FileManager.default.removeItem(at: fileURL) - } + try FileManager.default.removeItem(at: cacheDirectory) } private func filePath(forKey key: String) -> URL { diff --git a/MVMCore/MVMCore/OtherHandlers/MVMCoreCache.h b/MVMCore/MVMCore/OtherHandlers/MVMCoreCache.h index 07ec07c..6319fa5 100644 --- a/MVMCore/MVMCore/OtherHandlers/MVMCoreCache.h +++ b/MVMCore/MVMCore/OtherHandlers/MVMCoreCache.h @@ -48,6 +48,12 @@ typedef void(^MVMCoreGetImageBlock)(UIImage * _Nullable, NSData * _Nullable, BOO /// Checks if the module is to be persistently cached. - (BOOL)shouldPersistentlyCacheModule:(nonnull NSDictionary *)jsonDictionary module:(nonnull NSString *)module; +/// Can override the path for the page to be cached. Currently Cache/Atomic/Pages/pageType +- (nullable NSURL *)getPathForPersistentCachePage:(nonnull NSString *)pageType; + +/// Can override the path for the page to be cached. Currently Cache/Atomic/Modules/moduleName +- (nullable NSURL *)getPathForPersistentCacheModule:(nonnull NSString *)moduleName; + // For pages external to the mobile first framework to be added to the list to not cache - (void)addPageTypesToNotCache:(nullable NSArray *)array; diff --git a/MVMCore/MVMCore/OtherHandlers/MVMCoreCache.m b/MVMCore/MVMCore/OtherHandlers/MVMCoreCache.m index 1a4aa98..3f1fa92 100644 --- a/MVMCore/MVMCore/OtherHandlers/MVMCoreCache.m +++ b/MVMCore/MVMCore/OtherHandlers/MVMCoreCache.m @@ -134,6 +134,14 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt"; return [self shouldPersistentlyCacheJSON:jsonDictionary]; } +- (nullable NSURL *)getPathForPersistentCachePage:(nonnull NSString *)pageType { + return [[[[PersistentCacheManager shared].cacheDirectory URLByAppendingPathComponent:@"Pages"] URLByAppendingPathComponent:pageType] URLByAppendingPathExtension:@"json"]; +} + +- (nullable NSURL *)getPathForPersistentCacheModule:(nonnull NSString *)moduleName { + return [[[[PersistentCacheManager shared].cacheDirectory URLByAppendingPathComponent:@"Modules"] URLByAppendingPathComponent:moduleName]URLByAppendingPathExtension:@"json"]; +} + - (void)addPageTypesToNotCache:(nullable NSArray *)array { if (array) { [self.pageTypesToNotCache addObjectsFromArray:array]; @@ -162,12 +170,12 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt"; - (NSDictionary * _Nullable)fetchPageFromPersistentCache:(nonnull NSString *)pageType { NSError *error = nil; - return [[PersistentCacheManager shared] loadForKey:pageType error:&error]; + return [[PersistentCacheManager shared] loadForKey:pageType path:[self getPathForPersistentCachePage:pageType] error:&error]; } - (NSDictionary * _Nullable)fetchModuleFromPersistentCache:(nonnull NSString *)moduleName { NSError *error = nil; - return [[PersistentCacheManager shared] loadForKey:moduleName error:&error]; + return [[PersistentCacheManager shared] loadForKey:moduleName path:[self getPathForPersistentCacheModule:moduleName] error:&error]; } #pragma mark - Advanced Fetch @@ -261,12 +269,18 @@ static NSString * const STATIC_CACHE_COMPONENT = @"StaticCache.txt"; - (void)addPageToPersistentCache:(nonnull NSDictionary *)jsonDictionary pageType:(nonnull NSString *)pageType expirationDate:(nonnull NSDate *)expirationDate { NSError *error = nil; - [[PersistentCacheManager shared] saveWithData:jsonDictionary forKey:pageType expirationDate:expirationDate error:&error]; + [[PersistentCacheManager shared] saveWithData:jsonDictionary forKey:pageType path:[self getPathForPersistentCachePage:pageType] expirationDate:expirationDate error:&error]; + if (error) { + [[MVMCoreLoggingHandler sharedLoggingHandler] addErrorToLog:[MVMCoreErrorObject createErrorObjectForNSError:error location:[NSString stringWithFormat:@"%s_%@",__PRETTY_FUNCTION__,pageType]]]; + } } - (void)addModuleToPersistentCache:(nonnull NSDictionary *)jsonDictionary moduleName:(nonnull NSString *)moduleName expirationDate:(nonnull NSDate *)expirationDate { NSError *error = nil; - [[PersistentCacheManager shared] saveWithData:jsonDictionary forKey:moduleName expirationDate:expirationDate error:&error]; + [[PersistentCacheManager shared] saveWithData:jsonDictionary forKey:moduleName path:[self getPathForPersistentCacheModule:moduleName] expirationDate:expirationDate error:&error]; + if (error) { + [[MVMCoreLoggingHandler sharedLoggingHandler] addErrorToLog:[MVMCoreErrorObject createErrorObjectForNSError:error location:[NSString stringWithFormat:@"%s_%@",__PRETTY_FUNCTION__,moduleName]]]; + } } #pragma mark - Advanced Insertion