16
16
17
17
import * as api from '../protos/firestore_proto_api' ;
18
18
import { CredentialsProvider , Token } from '../api/credentials' ;
19
- import { DatabaseInfo } from '../core/database_info' ;
20
19
import { SnapshotVersion } from '../core/snapshot_version' ;
21
20
import { ProtoByteString , TargetId } from '../core/types' ;
22
21
import { QueryData } from '../local/query_data' ;
@@ -31,6 +30,7 @@ import { Connection, Stream } from './connection';
31
30
import { JsonProtoSerializer } from './serializer' ;
32
31
import { WatchChange } from './watch_change' ;
33
32
import { isNullOrUndefined } from '../util/types' ;
33
+ import { CancelablePromise } from '../util/promise' ;
34
34
35
35
const LOG_TAG = 'PersistentStream' ;
36
36
@@ -154,7 +154,7 @@ export abstract class PersistentStream<
154
154
ListenerType extends PersistentStreamListener
155
155
> {
156
156
private state : PersistentStreamState ;
157
- private idle = false ;
157
+ private inactivityTimerPromise : CancelablePromise < void > | null = null ;
158
158
private stream : Stream < SendType , ReceiveType > | null = null ;
159
159
160
160
protected backoff : ExponentialBackoff ;
@@ -245,16 +245,25 @@ export abstract class PersistentStream<
245
245
}
246
246
247
247
/**
248
- * Initializes the idle timer. If no write takes place within one minute, the
249
- * WebChannel stream will be closed.
248
+ * Marks this stream as idle. If no further actions are performed on the
249
+ * stream for one minute, the stream will automatically close itself and
250
+ * notify the stream's onClose() handler with Status.OK. The stream will then
251
+ * be in a !isStarted() state, requiring the caller to start the stream again
252
+ * before further use.
253
+ *
254
+ * Only streams that are in state 'Open' can be marked idle, as all other
255
+ * states imply pending network operations.
250
256
*/
251
257
markIdle ( ) : void {
252
- this . idle = true ;
253
- this . queue
254
- . schedule ( ( ) => {
255
- return this . handleIdleCloseTimer ( ) ;
256
- } , IDLE_TIMEOUT_MS )
257
- . catch ( ( err : FirestoreError ) => {
258
+ // Starts the idle time if we are in state 'Open' and are not yet already
259
+ // running a timer (in which case the previous idle timeout still applies).
260
+ if ( this . isOpen ( ) && this . inactivityTimerPromise === null ) {
261
+ this . inactivityTimerPromise = this . queue . scheduleWithDelay (
262
+ ( ) => this . handleIdleCloseTimer ( ) ,
263
+ IDLE_TIMEOUT_MS
264
+ ) ;
265
+
266
+ this . inactivityTimerPromise . catch ( ( err : FirestoreError ) => {
258
267
// When the AsyncQueue gets drained during testing, pending Promises
259
268
// (including these idle checks) will get rejected. We special-case
260
269
// these cancelled idle checks to make sure that these specific Promise
@@ -266,6 +275,7 @@ export abstract class PersistentStream<
266
275
} `
267
276
) ;
268
277
} ) ;
278
+ }
269
279
}
270
280
271
281
/** Sends a message to the underlying stream. */
@@ -276,7 +286,7 @@ export abstract class PersistentStream<
276
286
277
287
/** Called by the idle timer when the stream should close due to inactivity. */
278
288
private handleIdleCloseTimer ( ) : Promise < void > {
279
- if ( this . isOpen ( ) && this . idle ) {
289
+ if ( this . isOpen ( ) ) {
280
290
// When timing out an idle stream there's no reason to force the stream into backoff when
281
291
// it restarts so set the stream state to Initial instead of Error.
282
292
return this . close ( PersistentStreamState . Initial ) ;
@@ -286,7 +296,10 @@ export abstract class PersistentStream<
286
296
287
297
/** Marks the stream as active again. */
288
298
private cancelIdleCheck ( ) {
289
- this . idle = false ;
299
+ if ( this . inactivityTimerPromise ) {
300
+ this . inactivityTimerPromise . cancel ( ) ;
301
+ this . inactivityTimerPromise = null ;
302
+ }
290
303
}
291
304
292
305
/**
@@ -520,7 +533,6 @@ export class PersistentListenStream extends PersistentStream<
520
533
WatchStreamListener
521
534
> {
522
535
constructor (
523
- private databaseInfo : DatabaseInfo ,
524
536
queue : AsyncQueue ,
525
537
connection : Connection ,
526
538
credentials : CredentialsProvider ,
@@ -624,7 +636,6 @@ export class PersistentWriteStream extends PersistentStream<
624
636
private handshakeComplete_ = false ;
625
637
626
638
constructor (
627
- private databaseInfo : DatabaseInfo ,
628
639
queue : AsyncQueue ,
629
640
connection : Connection ,
630
641
credentials : CredentialsProvider ,
0 commit comments