diff options
| author | Christian Cleberg <[email protected]> | 2026-05-06 20:41:49 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-05-06 20:41:49 -0500 |
| commit | 205cf2687ce48f3d004792ff223422a86cc6bdbc (patch) | |
| tree | 7edb78cede354e79aa8abd764ed9c5047e0ee168 /Hutch/Networking/ProjectService.swift | |
| parent | 57e4f34b4613c09beb0cb757ac2ba2b43cc04daf (diff) | |
| download | hutch-205cf2687ce48f3d004792ff223422a86cc6bdbc.tar.gz hutch-205cf2687ce48f3d004792ff223422a86cc6bdbc.tar.bz2 hutch-205cf2687ce48f3d004792ff223422a86cc6bdbc.zip | |
feat(cache): persist read-only API responsesv3.3.1
Add a bounded stale-while-revalidate cache at the Sourcehut API boundary with
stable keys, centralized TTLs, request coalescing, payload hashing, and LRU disk
pruning.
Cache high-value read-only repo, build, ticket, project, profile, paste, and
Home/Work Queue data while keeping mutations network-only and invalidating
related prefixes after successful writes.
Add focused cache tests and implementation notes.
Diffstat (limited to 'Hutch/Networking/ProjectService.swift')
| -rw-r--r-- | Hutch/Networking/ProjectService.swift | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/Hutch/Networking/ProjectService.swift b/Hutch/Networking/ProjectService.swift index 5e0e061..44320ca 100644 --- a/Hutch/Networking/ProjectService.swift +++ b/Hutch/Networking/ProjectService.swift @@ -287,12 +287,17 @@ struct ProjectService: Sendable { variables["cursor"] = cursor } - let response = try await client.execute( + let cached = try await client.executeCached( service: .hub, query: Self.projectsQuery, variables: variables.isEmpty ? nil : variables, - responseType: ProjectPageResponse.self + responseType: ProjectPageResponse.self, + cacheKey: APICacheKeys.projects(cursor: cursor), + resourceType: .userProfile, + ttl: APICacheTTLs.projectList, + policy: .cacheFirstThenRefresh ) + let response = cached.value results.append(contentsOf: response.me.projects.results) guard let nextCursor = response.me.projects.cursor else { @@ -324,12 +329,22 @@ struct ProjectService: Sendable { variables["trackersCursor"] = trackersCursor } - let response = try await client.execute( + let cached = try await client.executeCached( service: .hub, query: Self.projectDetailQuery, variables: variables, - responseType: ProjectDetailResponse.self + responseType: ProjectDetailResponse.self, + cacheKey: APICacheKeys.projectDetail( + rid: rid, + mailingListsCursor: mailingListsCursor, + sourcesCursor: sourcesCursor, + trackersCursor: trackersCursor + ), + resourceType: .userProfile, + ttl: APICacheTTLs.projectDetail, + policy: .cacheFirstThenRefresh ) + let response = cached.value guard let project = response.project else { throw SRHTError.decodingError( |
