Skip to content

Commit d79a2a6

Browse files
committed
fix(ui): propagate group catalog changes to open clients
sessions.groups.put/rename/delete now always broadcast a groups-change event, and the session capability reloads the gateway-owned catalog when one arrives, so another browser's group create/reorder/rename/delete no longer leaves this client on a stale snapshot for the rest of the connection. Part of #103431
1 parent d454495 commit d79a2a6

2 files changed

Lines changed: 13 additions & 7 deletions

File tree

src/gateway/server-methods/sessions.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2612,13 +2612,15 @@ export const sessionsHandlers: GatewayRequestHandlers = {
26122612
}
26132613
respond(true, { groups: listSessionGroups() }, undefined);
26142614
},
2615-
"sessions.groups.put": async ({ params, respond }) => {
2615+
"sessions.groups.put": async ({ params, respond, context }) => {
26162616
if (
26172617
!assertValidParams(params, validateSessionsGroupsPutParams, "sessions.groups.put", respond)
26182618
) {
26192619
return;
26202620
}
26212621
respond(true, { ok: true, groups: putSessionGroups(params.names) }, undefined);
2622+
// Catalog-only changes still need to reach other open clients.
2623+
emitSessionsChanged(context, { reason: "groups" });
26222624
},
26232625
"sessions.groups.rename": async ({ params, respond, context }) => {
26242626
if (
@@ -2638,9 +2640,7 @@ export const sessionsHandlers: GatewayRequestHandlers = {
26382640
to: params.to,
26392641
});
26402642
respond(true, { ok: true, ...result }, undefined);
2641-
if (result.updatedSessions > 0) {
2642-
emitSessionsChanged(context, { reason: "groups" });
2643-
}
2643+
emitSessionsChanged(context, { reason: "groups" });
26442644
} catch (error) {
26452645
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, formatErrorMessage(error)));
26462646
}
@@ -2662,9 +2662,7 @@ export const sessionsHandlers: GatewayRequestHandlers = {
26622662
name: params.name,
26632663
});
26642664
respond(true, { ok: true, ...result }, undefined);
2665-
if (result.updatedSessions > 0) {
2666-
emitSessionsChanged(context, { reason: "groups" });
2667-
}
2665+
emitSessionsChanged(context, { reason: "groups" });
26682666
} catch (error) {
26692667
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, formatErrorMessage(error)));
26702668
}

ui/src/lib/sessions/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,6 +1279,14 @@ export function createSessionCapability(gateway: SessionGateway): SessionCapabil
12791279
showArchived: lastListOptions.showArchived,
12801280
});
12811281
const eventInfo = readSessionChangedEvent(event.payload);
1282+
// Catalog mutations from other clients invalidate the per-connection
1283+
// groups snapshot. Groups events carry no session key, so read the
1284+
// reason straight off the payload instead of the parsed row info.
1285+
const eventReason = (event.payload as { reason?: unknown } | null)?.reason;
1286+
if (eventReason === "groups") {
1287+
groupsLoadedEpoch = -1;
1288+
void groupsLoad();
1289+
}
12821290
const hasActiveRun = reconciled.hasActiveRun ?? eventInfo?.hasActiveRun;
12831291
const status = reconciled.status ?? eventInfo?.status;
12841292
const runEnded =

0 commit comments

Comments
 (0)