Skip to content

Commit 2572377

Browse files
Incorporate maxAge
1 parent edfcd83 commit 2572377

File tree

6 files changed

+38
-16
lines changed

6 files changed

+38
-16
lines changed

Sources/Cache/Cache.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ actor Cache {
113113

114114
let hydratedTree = ResultTree(
115115
data: hydratedResults,
116-
ttl: dehydratedTree.ttl,
117116
cachedAt: dehydratedTree.cachedAt,
118117
lastAccessed: dehydratedTree.lastAccessed,
119118
rootObject: rootObj
@@ -147,7 +146,6 @@ actor Cache {
147146
queryId: queryId,
148147
tree: .init(
149148
data: dehydratedResults,
150-
ttl: response.ttl,
151149
cachedAt: Date(),
152150
lastAccessed: Date(),
153151
rootObject: rootObj

Sources/Cache/CacheSettings.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
import Foundation
16+
1517
/// Specifies the cache configuration for a `DataConnect` instance.
1618
///
1719
/// You can configure the cache's storage policy and its maximum size.
@@ -33,13 +35,22 @@ public struct CacheSettings: Sendable {
3335
/// to trigger cleanup procedures. The default is 100MB (100,000,000 bytes).
3436
public let maxSizeBytes: UInt64
3537

38+
/// Max time interval before a queries cache is considered stale and refreshed from the server
39+
/// This interval does not imply that cached data is evicted and it can still be accessed using
40+
/// the `cacheOnly` fetch policy
41+
public let maxAge: TimeInterval
42+
3643
/// Creates a new cache settings configuration.
3744
///
3845
/// - Parameters:
3946
/// - storage: The storage mechanism to use. Defaults to `.persistent`.
4047
/// - maxSize: The maximum desired size of the cache in bytes. Defaults to 100MB.
41-
public init(storage: Storage = .persistent, maxSize: UInt64 = 100_000_000) {
48+
/// - maxAge: The max time interval before a queries cache is considered stale and refreshed
49+
/// from the server
50+
public init(storage: Storage = .persistent, maxSize: UInt64 = 100_000_000,
51+
maxAge: TimeInterval = 0) {
4252
self.storage = storage
4353
maxSizeBytes = maxSize
54+
self.maxAge = maxAge
4455
}
4556
}

Sources/Cache/ResultTree.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ struct ResultTree: Codable {
1919
// tree data - could be hydrated or dehydrated.
2020
let data: String
2121

22-
// interval during which query results are considered fresh
23-
let ttl: TimeInterval
24-
2522
// Local time when the entry was cached / updated
2623
let cachedAt: Date
2724

@@ -38,7 +35,6 @@ struct ResultTree: Codable {
3835
enum CodingKeys: String, CodingKey {
3936
case cachedAt = "ca" // cached at
4037
case lastAccessed = "la" // last accessed
41-
case ttl = "ri" // revalidation interval
4238
case data = "d" // data cached
4339
}
4440
}

Sources/Internal/GrpcClient.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@ actor GrpcClient: CustomStringConvertible {
159159
If we have Partial Errors, we follow the partial error route below.
160160
*/
161161
guard !errorInfoList.isEmpty else {
162-
// TODO: Extract ttl, server timestamp
163-
return ServerResponse(jsonResults: resultsString, ttl: 10.0)
162+
// TODO: Extract ttl, server timestamp when available
163+
return ServerResponse(jsonResults: resultsString, maxAge: nil)
164164
}
165165

166166
// We have partial errors returned

Sources/Internal/ServerResponse.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ import Foundation
1616

1717
struct ServerResponse {
1818
let jsonResults: String
19-
let ttl: TimeInterval
19+
let maxAge: TimeInterval?
2020
}

Sources/Queries/GenericQueryRef.swift

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,24 @@ actor GenericQueryRef<ResultData: Decodable & Sendable, Variable: OperationVaria
3030

3131
private let cache: Cache?
3232

33-
private var ttl: TimeInterval? = 10.0 //
33+
// maxAge received from server in query response
34+
private var serverMaxAge: TimeInterval? = nil
35+
36+
// maxAge computed based on server or cache settings
37+
// server is given priority over cache settings
38+
private var maxAge: TimeInterval {
39+
if let serverMaxAge {
40+
DataConnectLogger.debug("Using maxAge specified from server \(serverMaxAge)")
41+
return serverMaxAge
42+
}
43+
44+
if let ma = cache?.config.maxAge {
45+
DataConnectLogger.debug("Using maxAge specified from cache settings \(ma)")
46+
return ma
47+
}
48+
49+
return 0
50+
}
3451

3552
// Ideally we would like this to be part of the QueryRef protocol
3653
// Not adding for now since the protocol is Public
@@ -94,6 +111,7 @@ actor GenericQueryRef<ResultData: Decodable & Sendable, Variable: OperationVaria
94111

95112
do {
96113
if let cache {
114+
serverMaxAge = response.maxAge
97115
await cache.update(queryId: operationId, response: response, requestor: self)
98116
}
99117
}
@@ -112,15 +130,14 @@ actor GenericQueryRef<ResultData: Decodable & Sendable, Variable: OperationVaria
112130
}
113131

114132
private func fetchCachedResults(allowStale: Bool) async throws -> OperationResult<ResultData> {
115-
guard let cache,
116-
let ttl,
117-
ttl > 0 else {
118-
DataConnectLogger.info("No cache provider configured or ttl is not set \(ttl)")
133+
guard let cache
134+
else {
135+
DataConnectLogger.info("No cache provider configured")
119136
return OperationResult(data: nil, source: .cache)
120137
}
121138

122139
if let cacheEntry = await cache.resultTree(queryId: request.requestId),
123-
(cacheEntry.isStale(ttl) && allowStale) || !cacheEntry.isStale(ttl) {
140+
(cacheEntry.isStale(maxAge) && allowStale) || !cacheEntry.isStale(maxAge) {
124141
let decoder = JSONDecoder()
125142
let decodedData = try decoder.decode(
126143
ResultData.self,

0 commit comments

Comments
 (0)