Skip to content

Commit a9471e0

Browse files
lsoldadoclaude
andcommitted
fix(format): don't overwrite freshly-refreshed cache on slow API resolve
Sourcery flagged a race in loadWorkspaceTimezone: if the user updated the timezone via Settings → refreshWorkspaceTimezone while the initial GET /settings/workspace was still in flight, the eventual resolution of that GET would overwrite cachedTz (and localStorage) with the stale server value, silently reverting the user's change until the next reload. Fix: in both the success and failure handlers, only write if cachedTz is still null. If anything else claimed the cache in the meantime, keep the fresher value. Reported-by: sourcery-ai[bot] on PR #59 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent d64ee29 commit a9471e0

1 file changed

Lines changed: 17 additions & 6 deletions

File tree

dashboard/frontend/src/lib/format.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,33 @@ export function getTimezoneSync(): string {
3838
return browserTz()
3939
}
4040

41-
/** Fetch from API and cache. Subsequent callers reuse the in-flight promise. */
41+
/** Fetch from API and cache. Subsequent callers reuse the in-flight promise.
42+
*
43+
* Race-safe with `refreshWorkspaceTimezone`: if the user updates the setting
44+
* (or any other code path populates the cache) while this fetch is in flight,
45+
* the resolved value is dropped — we never overwrite a fresher cache value
46+
* with the stale server response. */
4247
export async function loadWorkspaceTimezone(): Promise<string> {
4348
if (cachedTz) return cachedTz
4449
if (inflight) return inflight
4550
inflight = api
4651
.get('/settings/workspace')
4752
.then((data: any) => {
4853
const tz: string = data?.workspace?.timezone || browserTz()
49-
cachedTz = tz
50-
try { window.localStorage.setItem(STORAGE_KEY, tz) } catch { /* noop */ }
51-
return tz
54+
// Only write if nothing else claimed the cache in the meantime
55+
// (e.g. a concurrent refreshWorkspaceTimezone from Settings save).
56+
if (cachedTz == null) {
57+
cachedTz = tz
58+
try { window.localStorage.setItem(STORAGE_KEY, tz) } catch { /* noop */ }
59+
}
60+
return cachedTz!
5261
})
5362
.catch(() => {
5463
const fallback = browserTz()
55-
cachedTz = fallback
56-
return fallback
64+
if (cachedTz == null) {
65+
cachedTz = fallback
66+
}
67+
return cachedTz!
5768
})
5869
.finally(() => { inflight = null })
5970
return inflight

0 commit comments

Comments
 (0)