@@ -63,20 +63,21 @@ class Redis extends Commander {
6363
6464 options : RedisOptions ;
6565 status : RedisStatus = "wait" ;
66- commandQueue : Deque < CommandItem > ;
67- offlineQueue : Deque ;
68- connectionEpoch = 0 ;
69- connector : AbstractConnector ;
70- condition : {
66+ stream : NetStream ;
67+ isCluster = false ;
68+
69+ private connector : AbstractConnector ;
70+ private reconnectTimeout : ReturnType < typeof setTimeout > | null = null ;
71+ private condition : {
7172 select : number ;
7273 auth ?: string | [ string , string ] ;
7374 subscriber : boolean ;
7475 } ;
75- stream : NetStream ;
76- manuallyClosing = false ;
77- retryAttempts = 0 ;
78- reconnectTimeout : ReturnType < typeof setTimeout > | null = null ;
79- isCluster = false ;
76+ private commandQueue : Deque < CommandItem > ;
77+ private offlineQueue : Deque ;
78+ private connectionEpoch = 0 ;
79+ private retryAttempts = 0 ;
80+ private manuallyClosing = false ;
8081
8182 // Prepare autopipelines structures
8283 private _autoPipelines = new Map ( ) ;
@@ -129,51 +130,6 @@ class Redis extends Commander {
129130 return queued ;
130131 }
131132
132- parseOptions ( ...args : unknown [ ] ) {
133- const options : Record < string , unknown > = { } ;
134- let isTls = false ;
135- for ( let i = 0 ; i < args . length ; ++ i ) {
136- const arg = args [ i ] ;
137- if ( arg === null || typeof arg === "undefined" ) {
138- continue ;
139- }
140- if ( typeof arg === "object" ) {
141- defaults ( options , arg ) ;
142- } else if ( typeof arg === "string" ) {
143- defaults ( options , parseURL ( arg ) ) ;
144- if ( arg . startsWith ( "rediss://" ) ) {
145- isTls = true ;
146- }
147- } else if ( typeof arg === "number" ) {
148- options . port = arg ;
149- } else {
150- throw new Error ( "Invalid argument " + arg ) ;
151- }
152- }
153- if ( isTls ) {
154- defaults ( options , { tls : true } ) ;
155- }
156- defaults ( options , Redis . defaultOptions ) ;
157-
158- if ( typeof options . port === "string" ) {
159- options . port = parseInt ( options . port , 10 ) ;
160- }
161- if ( typeof options . db === "string" ) {
162- options . db = parseInt ( options . db , 10 ) ;
163- }
164-
165- // @ts -expect-error
166- this . options = resolveTLSProfile ( options ) ;
167- }
168-
169- resetCommandQueue ( ) {
170- this . commandQueue = new Deque ( ) ;
171- }
172-
173- resetOfflineQueue ( ) {
174- this . offlineQueue = new Deque ( ) ;
175- }
176-
177133 /**
178134 * Create a connection to Redis.
179135 * This method will be invoked automatically when creating a new Redis instance
@@ -347,80 +303,6 @@ class Redis extends Commander {
347303 return new Redis ( { ...this . options , ...override } ) ;
348304 }
349305
350- recoverFromFatalError ( commandError , err : Error | null , options ) {
351- this . flushQueue ( err , options ) ;
352- this . silentEmit ( "error" , err ) ;
353- this . disconnect ( true ) ;
354- }
355-
356- handleReconnection ( err : Error , item : CommandItem ) {
357- let needReconnect : ReturnType < ReconnectOnError > = false ;
358- if ( this . options . reconnectOnError ) {
359- needReconnect = this . options . reconnectOnError ( err ) ;
360- }
361-
362- switch ( needReconnect ) {
363- case 1 :
364- case true :
365- if ( this . status !== "reconnecting" ) {
366- this . disconnect ( true ) ;
367- }
368- item . command . reject ( err ) ;
369- break ;
370- case 2 :
371- if ( this . status !== "reconnecting" ) {
372- this . disconnect ( true ) ;
373- }
374- if (
375- this . condition . select !== item . select &&
376- item . command . name !== "select"
377- ) {
378- this . select ( item . select ) ;
379- }
380- // TODO
381- // @ts -expect-error
382- this . sendCommand ( item . command ) ;
383- break ;
384- default :
385- item . command . reject ( err ) ;
386- }
387- }
388-
389- /**
390- * Emit only when there's at least one listener.
391- */
392- silentEmit ( eventName : string , arg ?: unknown ) : boolean {
393- let error : unknown ;
394- if ( eventName === "error" ) {
395- error = arg ;
396-
397- if ( this . status === "end" ) {
398- return ;
399- }
400-
401- if ( this . manuallyClosing ) {
402- // ignore connection related errors when manually disconnecting
403- if (
404- error instanceof Error &&
405- ( error . message === CONNECTION_CLOSED_ERROR_MSG ||
406- // @ts -expect-error
407- error . syscall === "connect" ||
408- // @ts -expect-error
409- error . syscall === "read" )
410- ) {
411- return ;
412- }
413- }
414- }
415- if ( this . listeners ( eventName ) . length > 0 ) {
416- return this . emit . apply ( this , arguments ) ;
417- }
418- if ( error && error instanceof Error ) {
419- console . error ( "[ioredis] Unhandled error event:" , error . stack ) ;
420- }
421- return false ;
422- }
423-
424306 /**
425307 * Listen for all requests received by the server in real time.
426308 *
@@ -642,6 +524,41 @@ class Redis extends Commander {
642524 return this . createScanStream ( "zscanBuffer" , { key, options } ) ;
643525 }
644526
527+ /**
528+ * Emit only when there's at least one listener.
529+ */
530+ silentEmit ( eventName : string , arg ?: unknown ) : boolean {
531+ let error : unknown ;
532+ if ( eventName === "error" ) {
533+ error = arg ;
534+
535+ if ( this . status === "end" ) {
536+ return ;
537+ }
538+
539+ if ( this . manuallyClosing ) {
540+ // ignore connection related errors when manually disconnecting
541+ if (
542+ error instanceof Error &&
543+ ( error . message === CONNECTION_CLOSED_ERROR_MSG ||
544+ // @ts -expect-error
545+ error . syscall === "connect" ||
546+ // @ts -expect-error
547+ error . syscall === "read" )
548+ ) {
549+ return ;
550+ }
551+ }
552+ }
553+ if ( this . listeners ( eventName ) . length > 0 ) {
554+ return this . emit . apply ( this , arguments ) ;
555+ }
556+ if ( error && error instanceof Error ) {
557+ console . error ( "[ioredis] Unhandled error event:" , error . stack ) ;
558+ }
559+ return false ;
560+ }
561+
645562 /**
646563 * Get description of the connection. Used for debugging.
647564 */
@@ -667,6 +584,90 @@ class Redis extends Commander {
667584 return description ;
668585 }
669586
587+ private resetCommandQueue ( ) {
588+ this . commandQueue = new Deque ( ) ;
589+ }
590+
591+ private resetOfflineQueue ( ) {
592+ this . offlineQueue = new Deque ( ) ;
593+ }
594+
595+ private recoverFromFatalError ( commandError , err : Error | null , options ) {
596+ this . flushQueue ( err , options ) ;
597+ this . silentEmit ( "error" , err ) ;
598+ this . disconnect ( true ) ;
599+ }
600+
601+ private handleReconnection ( err : Error , item : CommandItem ) {
602+ let needReconnect : ReturnType < ReconnectOnError > = false ;
603+ if ( this . options . reconnectOnError ) {
604+ needReconnect = this . options . reconnectOnError ( err ) ;
605+ }
606+
607+ switch ( needReconnect ) {
608+ case 1 :
609+ case true :
610+ if ( this . status !== "reconnecting" ) {
611+ this . disconnect ( true ) ;
612+ }
613+ item . command . reject ( err ) ;
614+ break ;
615+ case 2 :
616+ if ( this . status !== "reconnecting" ) {
617+ this . disconnect ( true ) ;
618+ }
619+ if (
620+ this . condition . select !== item . select &&
621+ item . command . name !== "select"
622+ ) {
623+ this . select ( item . select ) ;
624+ }
625+ // TODO
626+ // @ts -expect-error
627+ this . sendCommand ( item . command ) ;
628+ break ;
629+ default :
630+ item . command . reject ( err ) ;
631+ }
632+ }
633+
634+ private parseOptions ( ...args : unknown [ ] ) {
635+ const options : Record < string , unknown > = { } ;
636+ let isTls = false ;
637+ for ( let i = 0 ; i < args . length ; ++ i ) {
638+ const arg = args [ i ] ;
639+ if ( arg === null || typeof arg === "undefined" ) {
640+ continue ;
641+ }
642+ if ( typeof arg === "object" ) {
643+ defaults ( options , arg ) ;
644+ } else if ( typeof arg === "string" ) {
645+ defaults ( options , parseURL ( arg ) ) ;
646+ if ( arg . startsWith ( "rediss://" ) ) {
647+ isTls = true ;
648+ }
649+ } else if ( typeof arg === "number" ) {
650+ options . port = arg ;
651+ } else {
652+ throw new Error ( "Invalid argument " + arg ) ;
653+ }
654+ }
655+ if ( isTls ) {
656+ defaults ( options , { tls : true } ) ;
657+ }
658+ defaults ( options , Redis . defaultOptions ) ;
659+
660+ if ( typeof options . port === "string" ) {
661+ options . port = parseInt ( options . port , 10 ) ;
662+ }
663+ if ( typeof options . db === "string" ) {
664+ options . db = parseInt ( options . db , 10 ) ;
665+ }
666+
667+ // @ts -expect-error
668+ this . options = resolveTLSProfile ( options ) ;
669+ }
670+
670671 /**
671672 * Change instance's status
672673 */
0 commit comments