@@ -2,13 +2,13 @@ import {Inject, Injectable, OnDestroy} from '@angular/core';
2
2
import { Store } from '@ngxs/store' ;
3
3
import { DOCUMENT } from '@angular/common' ;
4
4
import * as dayjs from 'dayjs' ;
5
- import { BehaviorSubject , Observable , of , Subject , throwError } from 'rxjs' ;
5
+ import { BehaviorSubject , Observable , of , Subject , throwError , timer } from 'rxjs' ;
6
6
import { HttpClient } from '@angular/common/http' ;
7
- import { catchError , takeUntil , tap } from 'rxjs/operators' ;
7
+ import { catchError , delay , finalize , take , takeUntil , tap } from 'rxjs/operators' ;
8
8
9
9
import { environment } from '../../../../environments/environment' ;
10
10
import fromEventSource , { EventSourceMessage } from '../rxjs/fromEventSource' ;
11
- import retryWithConsecutiveBreak from '../rxjs/retryWithConsecutiveBreak' ;
11
+ import retryWithConsecutiveBreak , { RetryAttempt } from '../rxjs/retryWithConsecutiveBreak' ;
12
12
import { CheckCredentialsAction } from '../auth/state/auth.actions' ;
13
13
14
14
@Injectable ( {
@@ -71,6 +71,28 @@ export class BootProgressService implements OnDestroy {
71
71
}
72
72
}
73
73
74
+ private propagateRetryMessage ( attempt : RetryAttempt ) {
75
+ // set boot state to retry
76
+ this . state$ . next ( BootState . RETRY ) ;
77
+
78
+ let retryInSeconds = Math . round ( attempt . delay / 1000 ) - 1 ;
79
+
80
+ timer ( 0 , 1000 )
81
+ . pipe (
82
+ take ( retryInSeconds ) ,
83
+ finalize ( ( ) => {
84
+ of ( null )
85
+ . pipe ( delay ( 850 ) , takeUntil ( this . destroy$ ) )
86
+ . subscribe ( ( ) => this . message$ . next ( 'Connecting...' ) ) ;
87
+ } ) ,
88
+ takeUntil ( this . destroy$ )
89
+ )
90
+ . subscribe ( ( number ) => {
91
+ const remainingTime = retryInSeconds - number ;
92
+ this . message$ . next ( `Backend is down - retrying in ${ remainingTime } s` ) ;
93
+ } ) ;
94
+ }
95
+
74
96
private connect ( ) {
75
97
if ( this . stream$ === null ) {
76
98
this . state$ . next ( BootState . BOOTING ) ;
@@ -79,9 +101,6 @@ export class BootProgressService implements OnDestroy {
79
101
[ 'booting' , 'booted' , 'ready' ] ,
80
102
{ withCredentials : false }
81
103
) . pipe (
82
- // kill switch.
83
- takeUntil ( this . destroy$ ) ,
84
-
85
104
tap ( ( e : EventSourceMessage ) => {
86
105
if ( e . type === 'ready' ) {
87
106
this . handleReady ( e ) ;
@@ -96,17 +115,19 @@ export class BootProgressService implements OnDestroy {
96
115
maxRetries : - 1 ,
97
116
exponentialDelay : true ,
98
117
incrementFraction : 1.45 ,
99
- maxDelay : 15000 ,
118
+ maxDelay : 16000 ,
100
119
destroy$ : this . destroy$ ,
101
120
logAttempt : true ,
102
121
onRetry : attempt => {
103
122
if ( this . state$ . getValue ( ) !== BootState . BOOTED ) {
104
- this . state$ . next ( BootState . RETRY ) ;
105
- this . message$ . next ( `Backend is down - retrying in ${ Math . round ( attempt . delay / 1000 ) } s` ) ;
123
+ this . propagateRetryMessage ( attempt ) ;
106
124
}
107
125
}
108
126
} ) ,
109
127
128
+ // kill switch.
129
+ takeUntil ( this . destroy$ ) ,
130
+
110
131
catchError ( ( err ) => {
111
132
this . state$ . next ( BootState . FATAL ) ;
112
133
this . message$ . next ( 'Something unexpected happened - open dev console.' ) ;
0 commit comments