@@ -23,21 +23,22 @@ import { CancelablePromise } from '../util/promise';
23
23
const LOG_TAG = 'OnlineStateTracker' ;
24
24
25
25
// To deal with transient failures, we allow multiple stream attempts before
26
- // giving up and transitioning to Offline.
26
+ // giving up and transitioning from OnlineState.Unknown to Offline.
27
27
const MAX_WATCH_STREAM_FAILURES = 2 ;
28
28
29
29
// To deal with stream attempts that don't succeed or fail in a timely manner,
30
- // we have a maximum timeout we'll wait for the stream to either succeed or fail
31
- // MAX_WATCH_STREAM_FAILURES times, else we revert to OnlineState.Offline.
32
- const MAX_WATCH_STREAM_TIMEOUT_MS = 10 * 1000 ;
30
+ // we have a timeout for OnlineState to reach Online or Offline.
31
+ // If the timeout is reached, we transition to Offline rather than waiting
32
+ // indefinitely.
33
+ const ONLINE_STATE_TIMEOUT_MS = 10 * 1000 ;
33
34
34
35
/**
35
36
* A component used by the RemoteStore to track the OnlineState (that is,
36
37
* whether or not the client as a whole should be considered to be online or
37
38
* offline), implementing the appropriate heuristics.
38
39
*
39
40
* In particular, when the client is trying to connect to the backend, we
40
- * allow up to MAX_WATCH_STREAM_FAILURES within MAX_WATCH_STREAM_TIMEOUT_MS for
41
+ * allow up to MAX_WATCH_STREAM_FAILURES within ONLINE_STATE_TIMEOUT_MS for
41
42
* a connection to succeed. If we have too many failures or the timeout elapses,
42
43
* then we set the OnlineState to Offline, and the client will behave as if
43
44
* it is offline (get()s will return cached data, etc.).
@@ -54,11 +55,11 @@ export class OnlineStateTracker {
54
55
private watchStreamFailures = 0 ;
55
56
56
57
/**
57
- * A timer that elapses after MAX_WATCH_STREAM_TIMEOUT_MS , at which point we
58
- * revert to OnlineState.Offline without waiting for the stream to actually
59
- * fail (MAX_WATCH_STREAM_FAILURES times).
58
+ * A timer that elapses after ONLINE_STATE_TIMEOUT_MS , at which point we
59
+ * transition from OnlineState.Unknown to OnlineState.Offline without waiting
60
+ * for the stream to actually fail (MAX_WATCH_STREAM_FAILURES times).
60
61
*/
61
- private watchStreamTimerPromise : CancelablePromise < void > | null = null ;
62
+ private onlineStateTimer : CancelablePromise < void > | null = null ;
62
63
63
64
/**
64
65
* Whether the client should log a warning message if it fails to connect to
@@ -75,29 +76,34 @@ export class OnlineStateTracker {
75
76
/**
76
77
* Called by RemoteStore when a watch stream is started.
77
78
*
78
- * It sets the OnlineState to Unknown and starts a MAX_WATCH_STREAM_TIMEOUT_MS
79
- * timer if necessary.
79
+ * It sets the OnlineState to Unknown and starts the onlineStateTimer
80
+ * if necessary.
80
81
*/
81
82
handleWatchStreamStart ( ) : void {
82
83
this . setAndBroadcast ( OnlineState . Unknown ) ;
83
84
84
- if ( this . watchStreamTimerPromise === null ) {
85
- this . watchStreamTimerPromise = this . asyncQueue . enqueueAfterDelay (
85
+ if ( this . onlineStateTimer === null ) {
86
+ this . onlineStateTimer = this . asyncQueue . enqueueAfterDelay (
86
87
TimerId . OnlineStateTimeout ,
87
- MAX_WATCH_STREAM_TIMEOUT_MS ,
88
+ ONLINE_STATE_TIMEOUT_MS ,
88
89
( ) => {
89
- this . watchStreamTimerPromise = null ;
90
+ this . onlineStateTimer = null ;
90
91
assert (
91
92
this . state === OnlineState . Unknown ,
92
93
'Timer should be canceled if we transitioned to a different state.'
93
94
) ;
94
95
log . debug (
95
96
LOG_TAG ,
96
97
`Watch stream didn't reach online or offline within ` +
97
- `${ MAX_WATCH_STREAM_TIMEOUT_MS } ms. Considering client offline.`
98
+ `${ ONLINE_STATE_TIMEOUT_MS } ms. Considering client offline.`
98
99
) ;
99
100
this . logClientOfflineWarningIfNecessary ( ) ;
100
101
this . setAndBroadcast ( OnlineState . Offline ) ;
102
+
103
+ // NOTE: handleWatchStreamFailure() will continue to increment
104
+ // watchStreamFailures even though we are already marked Offline,
105
+ // but this is non-harmful.
106
+
101
107
return Promise . resolve ( ) ;
102
108
}
103
109
) ;
@@ -116,7 +122,7 @@ export class OnlineStateTracker {
116
122
} else {
117
123
this . watchStreamFailures ++ ;
118
124
if ( this . watchStreamFailures >= MAX_WATCH_STREAM_FAILURES ) {
119
- this . clearWatchStreamTimer ( ) ;
125
+ this . clearOnlineStateTimer ( ) ;
120
126
this . logClientOfflineWarningIfNecessary ( ) ;
121
127
this . setAndBroadcast ( OnlineState . Offline ) ;
122
128
}
@@ -131,7 +137,7 @@ export class OnlineStateTracker {
131
137
* handleWatchStreamStart() and handleWatchStreamFailure().
132
138
*/
133
139
set ( newState : OnlineState ) : void {
134
- this . clearWatchStreamTimer ( ) ;
140
+ this . clearOnlineStateTimer ( ) ;
135
141
this . watchStreamFailures = 0 ;
136
142
137
143
if ( newState === OnlineState . Online ) {
@@ -157,10 +163,10 @@ export class OnlineStateTracker {
157
163
}
158
164
}
159
165
160
- private clearWatchStreamTimer ( ) : void {
161
- if ( this . watchStreamTimerPromise !== null ) {
162
- this . watchStreamTimerPromise . cancel ( ) ;
163
- this . watchStreamTimerPromise = null ;
166
+ private clearOnlineStateTimer ( ) : void {
167
+ if ( this . onlineStateTimer !== null ) {
168
+ this . onlineStateTimer . cancel ( ) ;
169
+ this . onlineStateTimer = null ;
164
170
}
165
171
}
166
172
}
0 commit comments