@@ -405,42 +405,53 @@ export class Client<TContext = string> extends IPCClient<TContext> {
405405/**
406406 * Will ensure no messages are lost if there are no event listeners.
407407 */
408- export function createBufferedEvent < T > ( source : Event < T > ) : Event < T > {
409- let emitter : Emitter < T > ;
410- let hasListeners = false ;
411- let isDeliveringMessages = false ;
412- let bufferedMessages : T [ ] = [ ] ;
413-
414- const deliverMessages = ( ) => {
415- if ( isDeliveringMessages ) {
408+ export class BufferedEmitter < T > {
409+ private _emitter : Emitter < T > ;
410+ public readonly event : Event < T > ;
411+
412+ private _hasListeners = false ;
413+ private _isDeliveringMessages = false ;
414+ private _bufferedMessages : T [ ] = [ ] ;
415+
416+ constructor ( ) {
417+ this . _emitter = new Emitter < T > ( {
418+ onFirstListenerAdd : ( ) => {
419+ this . _hasListeners = true ;
420+ // it is important to deliver these messages after this call, but before
421+ // other messages have a chance to be received (to guarantee in order delivery)
422+ // that's why we're using here nextTick and not other types of timeouts
423+ process . nextTick ( ( ) => this . _deliverMessages ) ;
424+ } ,
425+ onLastListenerRemove : ( ) => {
426+ this . _hasListeners = false ;
427+ }
428+ } ) ;
429+
430+ this . event = this . _emitter . event ;
431+ }
432+
433+ private _deliverMessages ( ) : void {
434+ if ( this . _isDeliveringMessages ) {
416435 return ;
417436 }
418- isDeliveringMessages = true ;
419- while ( hasListeners && bufferedMessages . length > 0 ) {
420- emitter . fire ( bufferedMessages . shift ( ) ! ) ;
437+ this . _isDeliveringMessages = true ;
438+ while ( this . _hasListeners && this . _bufferedMessages . length > 0 ) {
439+ this . _emitter . fire ( this . _bufferedMessages . shift ( ) ! ) ;
421440 }
422- isDeliveringMessages = false ;
423- } ;
441+ this . _isDeliveringMessages = false ;
442+ }
424443
425- source ( ( e : T ) => {
426- bufferedMessages . push ( e ) ;
427- deliverMessages ( ) ;
428- } ) ;
429-
430- emitter = new Emitter < T > ( {
431- onFirstListenerAdd : ( ) => {
432- hasListeners = true ;
433- // it is important to deliver these messages after this call, but before
434- // other messages have a chance to be received (to guarantee in order delivery)
435- // that's why we're using here nextTick and not other types of timeouts
436- process . nextTick ( deliverMessages ) ;
437- } ,
438- onLastListenerRemove : ( ) => {
439- hasListeners = false ;
440- }
441- } ) ;
442-
443- return emitter . event ;
444+ public fire ( event : T ) : void {
445+ if ( this . _hasListeners ) {
446+ this . _emitter . fire ( event ) ;
447+ } else {
448+ this . _bufferedMessages . push ( event ) ;
449+ }
450+ }
451+
452+ public flushBuffer ( ) : void {
453+ this . _bufferedMessages = [ ] ;
454+ }
444455}
445456
446457class QueueElement < T > {
@@ -530,20 +541,20 @@ export class PersistentProtocol implements IMessagePassingProtocol {
530541 private _socketReader : ProtocolReader ;
531542 private _socketDisposables : IDisposable [ ] ;
532543
533- private _onControlMessage = new Emitter < VSBuffer > ( ) ;
534- readonly onControlMessage : Event < VSBuffer > = createBufferedEvent ( this . _onControlMessage . event ) ;
544+ private readonly _onControlMessage = new BufferedEmitter < VSBuffer > ( ) ;
545+ readonly onControlMessage : Event < VSBuffer > = this . _onControlMessage . event ;
535546
536- private _onMessage = new Emitter < VSBuffer > ( ) ;
537- readonly onMessage : Event < VSBuffer > = createBufferedEvent ( this . _onMessage . event ) ;
547+ private readonly _onMessage = new BufferedEmitter < VSBuffer > ( ) ;
548+ readonly onMessage : Event < VSBuffer > = this . _onMessage . event ;
538549
539- private _onClose = new Emitter < void > ( ) ;
540- readonly onClose : Event < void > = createBufferedEvent ( this . _onClose . event ) ;
550+ private readonly _onClose = new BufferedEmitter < void > ( ) ;
551+ readonly onClose : Event < void > = this . _onClose . event ;
541552
542- private _onSocketClose = new Emitter < void > ( ) ;
543- readonly onSocketClose : Event < void > = createBufferedEvent ( this . _onSocketClose . event ) ;
553+ private readonly _onSocketClose = new BufferedEmitter < void > ( ) ;
554+ readonly onSocketClose : Event < void > = this . _onSocketClose . event ;
544555
545- private _onSocketTimeout = new Emitter < void > ( ) ;
546- readonly onSocketTimeout : Event < void > = createBufferedEvent ( this . _onSocketTimeout . event ) ;
556+ private readonly _onSocketTimeout = new BufferedEmitter < void > ( ) ;
557+ readonly onSocketTimeout : Event < void > = this . _onSocketTimeout . event ;
547558
548559 public get unacknowledgedCount ( ) : number {
549560 return this . _outgoingMsgId - this . _outgoingAckId ;
@@ -656,6 +667,10 @@ export class PersistentProtocol implements IMessagePassingProtocol {
656667 this . _isReconnecting = true ;
657668
658669 this . _socketDisposables = dispose ( this . _socketDisposables ) ;
670+ this . _onControlMessage . flushBuffer ( ) ;
671+ this . _onSocketClose . flushBuffer ( ) ;
672+ this . _onSocketTimeout . flushBuffer ( ) ;
673+ this . _socket . dispose ( ) ;
659674
660675 this . _socket = socket ;
661676 this . _socketWriter = new ProtocolWriter ( this . _socket ) ;
0 commit comments