⚡ Bolt: [Deduplicate concurrent album fetches] (#50)
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit is contained in:
@@ -2,3 +2,8 @@
|
||||
|
||||
**Learning:** `useMemo` can significantly boost the performance of long list or grid components (like `PhotoGrid` component) that otherwise gets re-rendered on simple interactions like navigating the image lightbox. Running standard formatting `pnpm format` applies huge changes across entire directories, so it's generally best to format and clean up ONLY modified files to avoid huge diff pollution in code review.
|
||||
**Action:** Be extremely cautious of running format/lint commands at the root codebase; specify only modified directories or files, or avoid formatting if it cascades globally. Focus on targeted memoization where state changes dictate expensive array mapping operations.
|
||||
|
||||
## 2024-05-28 - [Deduplicate concurrent API requests via Promise caching]
|
||||
|
||||
**Learning:** When using `Promise.all` to fetch dependent data in parallel (e.g., getting multiple subpages and standalone albums that internally call a shared `getAlbums` function), the internal cache might not be populated in time. This leads to redundant concurrent network requests to the upstream server.
|
||||
**Action:** Implement Promise deduplication (request coalescing) by caching the pending Promise itself (e.g., in a `this.pendingPromise` class field) rather than just the final result. Return the pending Promise to subsequent callers until it resolves, ensuring only one network request is made.
|
||||
|
||||
@@ -72,6 +72,7 @@ export interface SubpageSummary {
|
||||
|
||||
class ImmichClient {
|
||||
private hasLoggedAlbums = false;
|
||||
private pendingAlbumsPromise: Promise<ImmichAlbum[]> | null = null;
|
||||
|
||||
private get config() {
|
||||
return getConfig();
|
||||
@@ -152,6 +153,12 @@ class ImmichClient {
|
||||
const cached = cache.get<ImmichAlbum[]>(cacheKey);
|
||||
if (cached) return cached;
|
||||
|
||||
if (this.pendingAlbumsPromise) {
|
||||
return this.pendingAlbumsPromise;
|
||||
}
|
||||
|
||||
this.pendingAlbumsPromise = (async () => {
|
||||
try {
|
||||
const all = await this.request<ImmichAlbum[]>('/albums?shared=true');
|
||||
if (!all) return [];
|
||||
|
||||
@@ -203,6 +210,12 @@ class ImmichClient {
|
||||
|
||||
cache.set(cacheKey, filtered, this.config.cacheTtl);
|
||||
return filtered;
|
||||
} finally {
|
||||
this.pendingAlbumsPromise = null;
|
||||
}
|
||||
})();
|
||||
|
||||
return this.pendingAlbumsPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user