This is an automated email from the ASF dual-hosted git repository.
lizhimins pushed a commit to branch rocketmq-studio
in repository https://gitbox.apache.org/repos/asf/rocketmq-dashboard.git
The following commit(s) were added to refs/heads/rocketmq-studio by this push:
new d9534aa1 fix: clear stale client connections after instance load
failure (#1479)
d9534aa1 is described below
commit d9534aa1b8f27852c7aaf9e34cd60d5f5f2e4457
Author: aias00 <[email protected]>
AuthorDate: Tue Aug 11 15:34:15 2026 +0800
fix: clear stale client connections after instance load failure (#1479)
---
.../pages/cluster/__tests__/ClientsPage.test.tsx | 42 ++++++++++++++++++++++
web/src/pages/cluster/clients.tsx | 14 +++++++-
2 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/web/src/pages/cluster/__tests__/ClientsPage.test.tsx
b/web/src/pages/cluster/__tests__/ClientsPage.test.tsx
index 88c486de..6972f021 100644
--- a/web/src/pages/cluster/__tests__/ClientsPage.test.tsx
+++ b/web/src/pages/cluster/__tests__/ClientsPage.test.tsx
@@ -222,6 +222,48 @@ describe('Clients page', () => {
expect(within(screen.getByTestId('connection-total')).getByText('0')).toBeInTheDocument();
});
+ it('clears the previous instance data when the next instance connection
request fails', async () => {
+ vi.mocked(instanceService.listInstances).mockResolvedValue([
+ {
+ id: 'instance-1',
+ name: 'Instance 1',
+ endpoint: 'namesrv-1:9876',
+ type: 'DIRECT',
+ remark: '',
+ topicCount: 0,
+ consumerGroupCount: 0,
+ createdAt: '',
+ updatedAt: '',
+ },
+ {
+ id: 'instance-2',
+ name: 'Instance 2',
+ endpoint: 'namesrv-2:9876',
+ type: 'DIRECT',
+ remark: '',
+ topicCount: 0,
+ consumerGroupCount: 0,
+ createdAt: '',
+ updatedAt: '',
+ },
+ ]);
+ vi.mocked(connectionsService.listConnections).mockImplementation((query) =>
+ query?.instanceId === 'instance-1'
+ ? Promise.resolve([connection])
+ : Promise.reject(new Error('Instance 2 is unavailable')),
+ );
+ const user = userEvent.setup();
+ renderWithProviders(<ClientsPage />);
+
+ await screen.findByText('[email protected]:49152');
+ await user.click(screen.getByRole('combobox', { name: 'Instance' }));
+ await user.click(await screen.findByText('Instance 2', { selector:
'.ant-select-item-option-content' }));
+
+ expect(await screen.findByText('Instance 2 is
unavailable')).toBeInTheDocument();
+
expect(screen.queryByText('[email protected]:49152')).not.toBeInTheDocument();
+
expect(within(screen.getByTestId('connection-total')).getByText('0')).toBeInTheDocument();
+ });
+
it('surfaces instance discovery failures and allows retrying', async () => {
vi.mocked(instanceService.listInstances)
.mockRejectedValueOnce(new Error('Unable to load managed instances'))
diff --git a/web/src/pages/cluster/clients.tsx
b/web/src/pages/cluster/clients.tsx
index 16c97bbb..72cd0950 100644
--- a/web/src/pages/cluster/clients.tsx
+++ b/web/src/pages/cluster/clients.tsx
@@ -116,6 +116,15 @@ const ClientsPage = () => {
const [loadError, setLoadError] = useState<string | null>(null);
const [instanceLoadKey, setInstanceLoadKey] = useState(0);
+ const handleInstanceChange = (instanceId: string) => {
+ setSelectedInstanceId(instanceId);
+ setConnections([]);
+ setClusterFilter('ALL');
+ setSelectedConnection(null);
+ setLoadError(null);
+ setLoading(true);
+ };
+
useEffect(() => {
let cancelled = false;
@@ -159,6 +168,9 @@ const ClientsPage = () => {
})
.catch((error) => {
if (!cancelled) {
+ setConnections([]);
+ setClusterFilter('ALL');
+ setSelectedConnection(null);
setLoadError(getLoadErrorMessage(error));
}
})
@@ -403,7 +415,7 @@ const ClientsPage = () => {
<Select
aria-label="Instance"
value={selectedInstanceId || undefined}
- onChange={setSelectedInstanceId}
+ onChange={handleInstanceChange}
placeholder="Select instance"
style={{ width: 180 }}
options={instances.map((instance) => ({ value: instance.id, label:
instance.name }))}