Skip to content

Commit 81a723a

Browse files
committed
fix: resolve Storybook metadata setup bug
1 parent ca8e94f commit 81a723a

File tree

1 file changed

+34
-9
lines changed

1 file changed

+34
-9
lines changed

site/src/modules/resources/AgentMetadata.tsx

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,37 +45,55 @@ interface AgentMetadataProps {
4545
storybookMetadata?: WorkspaceAgentMetadata[];
4646
}
4747

48+
const maxSocketErrorRetryCount = 3;
49+
4850
export const AgentMetadata: FC<AgentMetadataProps> = ({
4951
agent,
5052
storybookMetadata,
5153
}) => {
52-
const [metadata, setMetadata] = useState<WorkspaceAgentMetadata[]>();
54+
const [activeMetadata, setActiveMetadata] = useState(storybookMetadata);
5355
useEffect(() => {
5456
if (storybookMetadata !== undefined) {
5557
return;
5658
}
5759

5860
let timeoutId: number | undefined = undefined;
5961
let latestSocket: OneWayWebSocket | undefined = undefined;
62+
let retries = 0;
6063

6164
const createNewConnection = () => {
6265
const socket = watchAgentMetadata(agent.id);
6366
latestSocket = socket;
6467

6568
socket.addEventListener("error", () => {
66-
displayError("Socket closed unexpectedly. Creating new connection...");
67-
setMetadata(undefined);
69+
setActiveMetadata(undefined);
6870
window.clearTimeout(timeoutId);
69-
timeoutId = window.setTimeout(() => {
70-
createNewConnection();
71-
}, 3_000);
71+
72+
retries++;
73+
if (retries < maxSocketErrorRetryCount) {
74+
displayError(
75+
"Unexpected disconnect while watching Metadata changes. Creating new connection...",
76+
);
77+
timeoutId = window.setTimeout(() => {
78+
createNewConnection();
79+
}, 3_000);
80+
return;
81+
}
82+
83+
displayError(
84+
"Unexpected disconnect while watching Metadata changes. Cannot connect to server",
85+
);
86+
// The socket should already be closed by this point, but doing
87+
// this just to be thorough
88+
socket.close();
89+
latestSocket = undefined;
7290
});
7391

7492
socket.addEventListener("message", (e) => {
7593
try {
7694
const payload = JSON.parse(e.data) as ServerSentEvent;
7795
if (payload.type === "data") {
78-
setMetadata(payload.data as WorkspaceAgentMetadata[]);
96+
setActiveMetadata(payload.data as WorkspaceAgentMetadata[]);
7997
}
8098
} catch {
8199
displayError(
@@ -90,17 +108,24 @@ export const AgentMetadata: FC<AgentMetadataProps> = ({
90108
window.clearTimeout(timeoutId);
91109
latestSocket?.close();
92110
};
111+
112+
// This is an unfortunate pitfall with this component's testing setup,
113+
// but even though we use the value of storybookMetadata as the initial
114+
// value of the activeMetadata, we cannot put activeMetadata itself into
115+
// the dependency array. If we did, we would destroy and rebuild each
116+
// connection every single time a new message comes in from the socket,
117+
// because the socket has to be wired up to the state setter
93118
}, [agent.id, storybookMetadata]);
94119

95-
if (metadata === undefined) {
120+
if (activeMetadata === undefined) {
96121
return (
97122
<section css={styles.root}>
98123
<AgentMetadataSkeleton />
99124
</section>
100125
);
101126
}
102127

103-
return <AgentMetadataView metadata={metadata} />;
128+
return <AgentMetadataView metadata={activeMetadata} />;
104129
};
105130

106131
export const AgentMetadataSkeleton: FC = () => {

0 commit comments

Comments
 (0)