@@ -106,6 +106,7 @@ class Redis extends Commander implements DataHandledable {
106106 private connectionEpoch = 0 ;
107107 private retryAttempts = 0 ;
108108 private manuallyClosing = false ;
109+ private socketTimeoutTimer : NodeJS . Timeout | undefined ;
109110
110111 // Prepare autopipelines structures
111112 private _autoPipelines = new Map ( ) ;
@@ -523,6 +524,10 @@ class Redis extends Commander implements DataHandledable {
523524 if ( Command . checkFlag ( "WILL_DISCONNECT" , command . name ) ) {
524525 this . manuallyClosing = true ;
525526 }
527+
528+ if ( this . options . socketTimeout !== undefined && this . socketTimeoutTimer === undefined ) {
529+ this . setSocketTimeout ( ) ;
530+ }
526531 }
527532
528533 if ( command . name === "select" && isInt ( command . args [ 0 ] ) ) {
@@ -537,6 +542,23 @@ class Redis extends Commander implements DataHandledable {
537542 return command . promise ;
538543 }
539544
545+ private setSocketTimeout ( ) {
546+ this . socketTimeoutTimer = setTimeout ( ( ) => {
547+ this . stream . destroy ( new Error ( `Socket timeout. Expecting data, but didn't receive any in ${ this . options . socketTimeout } ms.` ) ) ;
548+ this . socketTimeoutTimer = undefined ;
549+ } , this . options . socketTimeout ) ;
550+
551+ // this handler must run after the "data" handler in "DataHandler"
552+ // so that `this.commandQueue.length` will be updated
553+ this . stream . once ( "data" , ( ) => {
554+ console . log ( 'GOT DATA, CLEARING TIMER' ) ;
555+ clearTimeout ( this . socketTimeoutTimer ) ;
556+ this . socketTimeoutTimer = undefined ;
557+ if ( this . commandQueue . length === 0 ) return ;
558+ this . setSocketTimeout ( ) ;
559+ } ) ;
560+ }
561+
540562 scanStream ( options ?: ScanStreamOptions ) {
541563 return this . createScanStream ( "scan" , { options } ) ;
542564 }
0 commit comments