summaryrefslogtreecommitdiff
path: root/Hutch/Networking/ProjectService.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-05-06 20:41:49 -0500
committerChristian Cleberg <[email protected]>2026-05-06 20:41:49 -0500
commit205cf2687ce48f3d004792ff223422a86cc6bdbc (patch)
tree7edb78cede354e79aa8abd764ed9c5047e0ee168 /Hutch/Networking/ProjectService.swift
parent57e4f34b4613c09beb0cb757ac2ba2b43cc04daf (diff)
downloadhutch-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.swift23
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(