@@ -212,6 +212,11 @@ export abstract class PersistentStream<
212
212
this . backoff = new ExponentialBackoff ( queue , connectionTimerId ) ;
213
213
}
214
214
215
+ /**
216
+ * Count of response messages received.
217
+ */
218
+ protected responseCount : number = 0 ;
219
+
215
220
/**
216
221
* Returns true if start() has been called and no error has occurred. True
217
222
* indicates the stream is open or in the process of opening (which
@@ -246,6 +251,7 @@ export abstract class PersistentStream<
246
251
* When start returns, isStarted() will return true.
247
252
*/
248
253
start ( ) : void {
254
+ this . responseCount = 0 ;
249
255
if ( this . state === PersistentStreamState . Error ) {
250
256
this . performBackoff ( ) ;
251
257
return ;
@@ -429,11 +435,18 @@ export abstract class PersistentStream<
429
435
) : Stream < SendType , ReceiveType > ;
430
436
431
437
/**
432
- * Called after the stream has received a message. The function will be
433
- * called on the right queue and must return a Promise.
438
+ * Called when the stream receives first message.
439
+ * The function will be called on the right queue and must return a Promise.
440
+ * @param message - The message received from the stream.
441
+ */
442
+ protected abstract onFirst ( message : ReceiveType ) : Promise < void > ;
443
+
444
+ /**
445
+ * Called on subsequent messages after the stream has received first message.
446
+ * The function will be called on the right queue and must return a Promise.
434
447
* @param message - The message received from the stream.
435
448
*/
436
- protected abstract onMessage ( message : ReceiveType ) : Promise < void > ;
449
+ protected abstract onNext ( message : ReceiveType ) : Promise < void > ;
437
450
438
451
private auth ( ) : void {
439
452
debugAssert (
@@ -522,7 +535,7 @@ export abstract class PersistentStream<
522
535
} ) ;
523
536
this . stream . onMessage ( ( msg : ReceiveType ) => {
524
537
dispatchIfNotClosed ( ( ) => {
525
- return this . onMessage ( msg ) ;
538
+ return ++ this . responseCount === 1 ? this . onFirst ( msg ) : this . onNext ( msg ) ;
526
539
} ) ;
527
540
} ) ;
528
541
}
@@ -643,7 +656,11 @@ export class PersistentListenStream extends PersistentStream<
643
656
) ;
644
657
}
645
658
646
- protected onMessage ( watchChangeProto : ProtoListenResponse ) : Promise < void > {
659
+ protected onFirst ( watchChangeProto : ProtoListenResponse ) : Promise < void > {
660
+ return this . onNext ( watchChangeProto ) ;
661
+ }
662
+
663
+ protected onNext ( watchChangeProto : ProtoListenResponse ) : Promise < void > {
647
664
// A successful response means the stream is healthy
648
665
this . backoff . reset ( ) ;
649
666
@@ -723,8 +740,6 @@ export class PersistentWriteStream extends PersistentStream<
723
740
ProtoWriteResponse ,
724
741
WriteStreamListener
725
742
> {
726
- private handshakeComplete_ = false ;
727
-
728
743
constructor (
729
744
queue : AsyncQueue ,
730
745
connection : Connection ,
@@ -760,18 +775,17 @@ export class PersistentWriteStream extends PersistentStream<
760
775
* the stream is ready to accept mutations.
761
776
*/
762
777
get handshakeComplete ( ) : boolean {
763
- return this . handshakeComplete_ ;
778
+ return this . responseCount > 0 ;
764
779
}
765
780
766
781
// Override of PersistentStream.start
767
782
start ( ) : void {
768
- this . handshakeComplete_ = false ;
769
783
this . lastStreamToken = undefined ;
770
784
super . start ( ) ;
771
785
}
772
786
773
787
protected tearDown ( ) : void {
774
- if ( this . handshakeComplete_ ) {
788
+ if ( this . handshakeComplete ) {
775
789
this . writeMutations ( [ ] ) ;
776
790
}
777
791
}
@@ -787,35 +801,41 @@ export class PersistentWriteStream extends PersistentStream<
787
801
) ;
788
802
}
789
803
790
- protected onMessage ( responseProto : ProtoWriteResponse ) : Promise < void > {
804
+ protected onFirst ( responseProto : ProtoWriteResponse ) : Promise < void > {
805
+ // Always capture the last stream token.
806
+ hardAssert (
807
+ ! ! responseProto . streamToken ,
808
+ 'Got a write handshake response without a stream token'
809
+ ) ;
810
+ this . lastStreamToken = responseProto . streamToken ;
811
+
812
+ // The first response is always the handshake response
813
+ hardAssert (
814
+ ! responseProto . writeResults || responseProto . writeResults . length === 0 ,
815
+ 'Got mutation results for handshake'
816
+ ) ;
817
+ return this . listener ! . onHandshakeComplete ( ) ;
818
+ }
819
+
820
+ protected onNext ( responseProto : ProtoWriteResponse ) : Promise < void > {
791
821
// Always capture the last stream token.
792
822
hardAssert (
793
823
! ! responseProto . streamToken ,
794
824
'Got a write response without a stream token'
795
825
) ;
796
826
this . lastStreamToken = responseProto . streamToken ;
797
827
798
- if ( ! this . handshakeComplete_ ) {
799
- // The first response is always the handshake response
800
- hardAssert (
801
- ! responseProto . writeResults || responseProto . writeResults . length === 0 ,
802
- 'Got mutation results for handshake'
803
- ) ;
804
- this . handshakeComplete_ = true ;
805
- return this . listener ! . onHandshakeComplete ( ) ;
806
- } else {
807
- // A successful first write response means the stream is healthy,
808
- // Note, that we could consider a successful handshake healthy, however,
809
- // the write itself might be causing an error we want to back off from.
810
- this . backoff . reset ( ) ;
828
+ // A successful first write response means the stream is healthy,
829
+ // Note, that we could consider a successful handshake healthy, however,
830
+ // the write itself might be causing an error we want to back off from.
831
+ this . backoff . reset ( ) ;
811
832
812
- const results = fromWriteResults (
813
- responseProto . writeResults ,
814
- responseProto . commitTime
815
- ) ;
816
- const commitVersion = fromVersion ( responseProto . commitTime ! ) ;
817
- return this . listener ! . onMutationResult ( commitVersion , results ) ;
818
- }
833
+ const results = fromWriteResults (
834
+ responseProto . writeResults ,
835
+ responseProto . commitTime
836
+ ) ;
837
+ const commitVersion = fromVersion ( responseProto . commitTime ! ) ;
838
+ return this . listener ! . onMutationResult ( commitVersion , results ) ;
819
839
}
820
840
821
841
/**
@@ -825,7 +845,7 @@ export class PersistentWriteStream extends PersistentStream<
825
845
*/
826
846
writeHandshake ( ) : void {
827
847
debugAssert ( this . isOpen ( ) , 'Writing handshake requires an opened stream' ) ;
828
- debugAssert ( ! this . handshakeComplete_ , 'Handshake already completed' ) ;
848
+ debugAssert ( ! this . handshakeComplete , 'Handshake already completed' ) ;
829
849
debugAssert (
830
850
! this . lastStreamToken ,
831
851
'Stream token should be empty during handshake'
@@ -841,7 +861,7 @@ export class PersistentWriteStream extends PersistentStream<
841
861
writeMutations ( mutations : Mutation [ ] ) : void {
842
862
debugAssert ( this . isOpen ( ) , 'Writing mutations requires an opened stream' ) ;
843
863
debugAssert (
844
- this . handshakeComplete_ ,
864
+ this . handshakeComplete ,
845
865
'Handshake must be complete before writing mutations'
846
866
) ;
847
867
debugAssert (
0 commit comments