tressi
Version:
Deterministic load testing for API performance validation.
2 lines (1 loc) • 3.27 kB
JavaScript
import{a as v}from"./chunk-UR67FGQG.js";import{a as p}from"./chunk-2IBU6HRE.js";import{x as u}from"./chunk-BEQIQLT5.js";import{Bc as a,Gc as h,R as l,W as r,fc as s,ka as c}from"./chunk-W6IDPYNF.js";import{a as i,b as o}from"./chunk-I4MTPUBM.js";var _=class n{_log=r(h);_appRouter=r(u);_eventService=r(v);_rpc=r(p);_heartbeatTimeout=5e3;_retryInterval=3e3;_state=c({error:null,isHealthy:!0,lastCheck:null});isHealthy=s(()=>this._state().isHealthy);lastCheck=s(()=>this._state().lastCheck);_heartbeatTimeoutId=null;_retryIntervalId=null;_subscription=null;_errorSubscription=null;constructor(){this._subscribeToConnectedEvents()}async init(){await this.check()}async check(){try{let e=await this._rpc.client.health.$get();if(!e.ok)throw new Error("Health check failed");let t=await e.json();return this._state.update(m=>o(i({},m),{error:null,isHealthy:!0,lastCheck:new Date(t.timestamp)})),this._handleRecovery(),!0}catch(e){return this._handleConnectionLoss(e instanceof Error?e:new Error("Unknown error")),!1}}_subscribeToConnectedEvents(){this._subscription=this._eventService.getConnectedStream().subscribe({error:e=>{this._log.error("Health monitoring subscription error",e),this._handleConnectionLoss()},next:e=>{this._state.update(t=>o(i({},t),{error:null,isHealthy:!0,lastCheck:new Date(e.timestamp)})),this._handleRecovery()}}),this._errorSubscription=this._eventService.getErrorStream().subscribe({next:()=>{this._handleConnectionLoss(new Error("Event stream connection lost"))}})}_handleRecovery(){this.isHealthy()&&(this._stopRetryTimer(),this._resetHeartbeatTimeout(),globalThis.location.href.includes(a.SERVER_UNAVAILABLE)&&(this._log.info("Server recovered, resuming last session"),this._appRouter.toLastRoute()))}_resetHeartbeatTimeout(){this._heartbeatTimeoutId&&clearTimeout(this._heartbeatTimeoutId),this._heartbeatTimeoutId=setTimeout(()=>{this._handleConnectionLoss()},this._heartbeatTimeout)}_handleConnectionLoss(e){this._state.update(t=>o(i({},t),{error:e||new Error("Server connection lost"),isHealthy:!1})),this._appRouter.getCurrentUrl().includes(a.SERVER_UNAVAILABLE)||(this._log.error("Server unavailable, redirecting to error page"),this._appRouter.toServerUnavailable()),this._startRetryTimer()}_startRetryTimer(){this._retryIntervalId||(this._log.info("Starting reconnection retry timer"),this._retryIntervalId=setInterval(async()=>{this._log.info("Attempting to reconnect to event stream..."),this._eventService.connectToEventStream(),await this.check()},this._retryInterval))}_stopRetryTimer(){this._retryIntervalId&&(this._log.info("Stopping reconnection retry timer"),clearInterval(this._retryIntervalId),this._retryIntervalId=null)}getFormattedLastCheckTime(){let e=this.lastCheck();return e?e.toLocaleTimeString():"Never"}getRetryMessage(){return this.isHealthy()?"Connecting...":"Reconnecting..."}ngOnDestroy(){this._subscription&&(this._subscription.unsubscribe(),this._subscription=null),this._errorSubscription&&(this._errorSubscription.unsubscribe(),this._errorSubscription=null),this._heartbeatTimeoutId&&(clearTimeout(this._heartbeatTimeoutId),this._heartbeatTimeoutId=null),this._stopRetryTimer()}static \u0275fac=function(t){return new(t||n)};static \u0275prov=l({token:n,factory:n.\u0275fac,providedIn:"root"})};export{_ as a};