From 31730fabf28f97f91f83ee16a6a6a851defa910f Mon Sep 17 00:00:00 2001 From: Anirban Banerjee Date: Tue, 28 Jan 2025 13:08:21 +0530 Subject: [PATCH] Added polling and disabled SSR --- angular.json | 6 +- src/app/home/home.component.ts | 68 ++++++++++++++----- .../status-card/status-card.component.scss | 4 ++ src/config.ts | 2 + 4 files changed, 60 insertions(+), 20 deletions(-) diff --git a/angular.json b/angular.json index e3c11f6..b46883b 100644 --- a/angular.json +++ b/angular.json @@ -36,10 +36,8 @@ ], "scripts": [], "server": "src/main.server.ts", - "outputMode": "server", - "ssr": { - "entry": "src/server.ts" - } + "ssr": false, + "prerender": false }, "configurations": { "production": { diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts index dda5b3a..033bd51 100644 --- a/src/app/home/home.component.ts +++ b/src/app/home/home.component.ts @@ -1,12 +1,17 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, OnDestroy } from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { forkJoin } from 'rxjs'; +import { Region, StatusResponse } from '../../types'; +import { + regions, + regionStatusApiPath, + statusPollingIntervalInMs, +} from '../../config'; import { HeaderComponent } from '../header/header.component'; import { FooterComponent } from '../footer/footer.component'; import { StatusCardComponent } from '../status-card/status-card.component'; import { HeaderBannerComponent } from '../header-banner/header-banner.component'; -import { regions, regionStatusApiPath } from '../../config'; -import { Region, StatusResponse } from '../../types'; +import { Subscription, forkJoin, interval, of } from 'rxjs'; +import { startWith, switchMap, catchError } from 'rxjs/operators'; @Component({ selector: 'app-home', @@ -20,34 +25,65 @@ import { Region, StatusResponse } from '../../types'; templateUrl: './home.component.html', styleUrl: './home.component.scss', }) -export class HomeComponent implements OnInit { +export class HomeComponent implements OnInit, OnDestroy { regions: Region[] = regions; + private pollingSubscription?: Subscription; constructor(private http: HttpClient) {} ngOnInit() { - this.fetchRegionStatuses(); + this.startPolling(); + } + + ngOnDestroy() { + if (this.pollingSubscription) { + this.pollingSubscription.unsubscribe(); + } } - fetchRegionStatuses() { - const statusRequests = this.regions.map((region) => - this.http.get(`${region.url}${regionStatusApiPath}`) + private startPolling() { + this.pollingSubscription = interval(statusPollingIntervalInMs) + .pipe( + startWith(0), + switchMap(() => { + return this.fetchStatuses(); + }) + ) + .subscribe(); + } + + private fetchStatuses() { + const requests = this.regions.map((region) => + this.http.get(`${region.url}${regionStatusApiPath}`).pipe( + catchError(() => { + return of(null); + }) + ) ); - forkJoin(statusRequests).subscribe({ - next: (responses) => { + return forkJoin(requests).pipe( + switchMap((responses) => { responses.forEach((response, index) => { - this.regions[index].status = response.status; + if (response) { + this.regions[index].status = response.status; + } else { + this.regions[index].status = { + description: 'Unknown', + indicator: 'unknown', + }; + } }); - }, - error: () => { + return of([]); + }), + catchError(() => { this.regions.forEach((region) => { region.status = { description: 'Unknown', indicator: 'unknown', }; }); - }, - }); + return of([]); + }) + ); } } diff --git a/src/app/status-card/status-card.component.scss b/src/app/status-card/status-card.component.scss index 04fa246..2639ffb 100644 --- a/src/app/status-card/status-card.component.scss +++ b/src/app/status-card/status-card.component.scss @@ -63,4 +63,8 @@ &-critical { background-color: #cf222e; } + + &-maintenance { + background-color: #3D78B1; + } } diff --git a/src/config.ts b/src/config.ts index 50490ea..870ae91 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,5 +1,7 @@ import { Region } from './types'; +export const statusPollingIntervalInMs = 30000; + export const labels = { bannerTitle: 'Welcome to the Swimlane Status Page', bannerSubtitle: