diff --git a/spring-boot-admin-server-ui/src/main/frontend/mixins/subscribing.ts b/spring-boot-admin-server-ui/src/main/frontend/mixins/subscribing.ts index 024a54fcfff..fa9e488c35c 100644 --- a/spring-boot-admin-server-ui/src/main/frontend/mixins/subscribing.ts +++ b/spring-boot-admin-server-ui/src/main/frontend/mixins/subscribing.ts @@ -13,12 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { Subject } from 'rxjs'; export default { + data() { + return { + destroy$: new Subject(), + }; + }, created() { this.subscribe(); }, beforeUnmount() { + // Emit to signal all subscriptions to complete + this.destroy$.next(); + this.destroy$.complete(); this.unsubscribe(); }, methods: { diff --git a/spring-boot-admin-server-ui/src/main/frontend/services/instance.ts b/spring-boot-admin-server-ui/src/main/frontend/services/instance.ts index c67dada41ee..9bb551c5824 100644 --- a/spring-boot-admin-server-ui/src/main/frontend/services/instance.ts +++ b/spring-boot-admin-server-ui/src/main/frontend/services/instance.ts @@ -40,6 +40,7 @@ class Instance { public availableMetrics: string[] = []; public tags: { [key: string]: string }[]; public statusTimestamp: string; + public version?: number; public buildVersion: string; public statusInfo: StatusInfo; @@ -534,6 +535,7 @@ type StatusInfo = { type InstanceData = { id: string; + version?: number; registration: Registration; endpoints?: Endpoint[]; availableMetrics?: string[]; diff --git a/spring-boot-admin-server-ui/src/main/frontend/views/instances/details/details-cache.spec.ts b/spring-boot-admin-server-ui/src/main/frontend/views/instances/details/details-cache.spec.ts index 43c64902cc9..36683f7e41b 100644 --- a/spring-boot-admin-server-ui/src/main/frontend/views/instances/details/details-cache.spec.ts +++ b/spring-boot-admin-server-ui/src/main/frontend/views/instances/details/details-cache.spec.ts @@ -229,4 +229,39 @@ describe('DetailsCache', () => { expect(queryByText(`${HITS[0]}`)).not.toBeInTheDocument(); }); }); + + it('should reinitialize metrics when instance version changes (SSE update)', async () => { + const application = new Application(applications[0]); + const instance1 = application.instances[0]; + + const { getByText, rerender, queryByText } = await render(DetailsCache, { + props: { + instance: instance1, + cacheName: CACHE_NAME, + index: 0, + }, + }); + + // wait until initial fetch rendered a numeric value + await waitFor(() => { + expect(getByText(`${HITS[0]}`)).toBeTruthy(); + }); + + const instance2 = new Application({ + ...application, + instances: [ + { + ...instance1, + id: instance1.id, + version: (instance1.version ?? 0) + 1, + }, + ], + }).instances[0]; + + await rerender({ instance: instance2, cacheName: CACHE_NAME, index: 0 }); + + await waitFor(() => { + expect(queryByText(`${HITS[0]}`)).not.toBeInTheDocument(); + }); + }); }); diff --git a/spring-boot-admin-server-ui/src/main/frontend/views/instances/details/details-cache.vue b/spring-boot-admin-server-ui/src/main/frontend/views/instances/details/details-cache.vue index 5c49b26ccba..0a7a41ca5a6 100644 --- a/spring-boot-admin-server-ui/src/main/frontend/views/instances/details/details-cache.vue +++ b/spring-boot-admin-server-ui/src/main/frontend/views/instances/details/details-cache.vue @@ -79,7 +79,8 @@