fix(chat): apply loadMessages dedup to force=true callers as well
useWebSocket's ready handler calls loadMessages(channelId, true) from two adjacent code paths in the same handler invocation (remote-space refresh + per-origin cache clearing). Both fired in parallel because force=true bypassed dedup, producing the duplicate /messages requests visible in playwright network traces even after the parallel-mount dedup landed. Coalescing force=true with an in-flight call is safe: the requests hit the same endpoint with the same params and would return the same data, and the force caller still gets a fresh result via the shared Promise.
This commit is contained in:
@@ -179,12 +179,16 @@ export const useChatStore = create<ChatState>((set, get) => ({
|
|||||||
// The remote WS ready handler will call loadMessages once the map is populated.
|
// The remote WS ready handler will call loadMessages once the map is populated.
|
||||||
if (!isDm && !useSpaceStore.getState().channelOriginMap.has(channelId)) return;
|
if (!isDm && !useSpaceStore.getState().channelOriginMap.has(channelId)) return;
|
||||||
|
|
||||||
// Parallel-call dedup: if a non-forced load for this channel is already in
|
// Parallel-call dedup: if a load for this channel is already in flight,
|
||||||
// flight, return that Promise instead of starting a second fetch. `force`
|
// return that Promise instead of starting a second fetch. Applies to
|
||||||
// bypasses the dedup because callers using it (WS reconnect) explicitly
|
// force=true callers as well — `useWebSocket`'s ready handler invokes
|
||||||
// want a fresh fetch even if one is already pending. See `inFlightLoads`
|
// `loadMessages(currentChannelId, true)` from two adjacent code paths
|
||||||
// declaration for the full rationale.
|
// (one for remote-instance space refresh, one for cache clearing) on every
|
||||||
if (!force) {
|
// WS-ready event, and there's no value in two parallel fetches for the
|
||||||
|
// same channel: they hit the same endpoint with the same params and
|
||||||
|
// return the same data. Coalescing is safe; the force caller still gets a
|
||||||
|
// fresh result via the in-flight Promise.
|
||||||
|
{
|
||||||
const existing = inFlightLoads.get(channelId);
|
const existing = inFlightLoads.get(channelId);
|
||||||
if (existing) return existing;
|
if (existing) return existing;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user