@@ -80,7 +80,7 @@ const _localReconnectStrategy = () =>
8080 * @returns {RedisClient|RedisCluster }
8181 * @private
8282 */
83- const _createClientBase = ( ) => {
83+ const _createClientBase = ( clientName ) => {
8484 if ( cfEnv . isOnCf ) {
8585 try {
8686 // NOTE: settings the user explicitly to empty resolves auth problems, see
@@ -100,29 +100,42 @@ const _createClientBase = () => {
100100 }
101101 return redis . createClient ( { url } ) ;
102102 } catch ( err ) {
103- throw new VError ( { name : VERROR_CLUSTER_NAME , cause : err } , "error during create client with redis service" ) ;
103+ throw new VError (
104+ { name : VERROR_CLUSTER_NAME , cause : err , info : { clientName } } ,
105+ "error during create client with redis service"
106+ ) ;
104107 }
105108 } else {
106109 // NOTE: documentation is buried here https://github.com/redis/node-redis/blob/master/docs/client-configuration.md
107- // NOTE: we make the host explicit here to avoid ipv4/ipv6 ambivalence problems that got introduced with node v18
108- return redis . createClient ( { socket : { host : "127.0.0.1" , reconnectStrategy : _localReconnectStrategy } } ) ;
110+ // NOTE: redis behaves a bit odd if you don't make the socket family, aka. ip stack version explicit here. For the
111+ // default family value 0, it will be ipv4 in node v16, ipv6 in node v18 and ipv4+ipv6 in node v20...
112+ return redis . createClient ( {
113+ url : "redis://localhost:6379" ,
114+ socket : { family : 4 , reconnectStrategy : _localReconnectStrategy } ,
115+ } ) ;
109116 }
110117} ;
111118
112- const _createClientAndConnect = async ( errorHandler ) => {
119+ const _createClientAndConnect = async ( clientName ) => {
113120 let client = null ;
114121 try {
115- client = _createClientBase ( ) ;
122+ client = _createClientBase ( clientName ) ;
116123 } catch ( err ) {
117- throw new VError ( { name : VERROR_CLUSTER_NAME , cause : err } , "error during create client" ) ;
124+ throw new VError ( { name : VERROR_CLUSTER_NAME , cause : err , info : { clientName } } , "error during create client" ) ;
118125 }
119126
120- client . on ( "error" , errorHandler ) ;
127+ // NOTE: documentation about events is here https://github.com/redis/node-redis?tab=readme-ov-file#events
128+ client . on ( "error" , ( err ) => {
129+ _logErrorOnEvent ( new VError ( { name : VERROR_CLUSTER_NAME , cause : err , info : { clientName } } , "caught error event" ) ) ;
130+ } ) ;
131+ client . on ( "reconnecting" , ( ) => {
132+ logger . warning ( "client '%s' is reconnecting" , clientName ) ;
133+ } ) ;
121134
122135 try {
123136 await client . connect ( ) ;
124137 } catch ( err ) {
125- throw new VError ( { name : VERROR_CLUSTER_NAME , cause : err } , "error during initial connect" ) ;
138+ throw new VError ( { name : VERROR_CLUSTER_NAME , cause : err , info : { clientName } } , "error during initial connect" ) ;
126139 }
127140 return client ;
128141} ;
@@ -133,17 +146,6 @@ const _closeClientBase = async (client) => {
133146 }
134147} ;
135148
136- const _clientErrorHandlerBase = async ( client , err , clientName ) => {
137- _logErrorOnEvent ( new VError ( { name : VERROR_CLUSTER_NAME , cause : err , info : { clientName } } , "caught error event" ) ) ;
138- try {
139- await _closeClientBase ( client ) ;
140- } catch ( closeError ) {
141- _logErrorOnEvent (
142- new VError ( { name : VERROR_CLUSTER_NAME , cause : closeError , info : { clientName } } , "error during client close" )
143- ) ;
144- }
145- } ;
146-
147149/**
148150 * Lazily create a regular client to be used
149151 * - for getting/setting values
@@ -156,10 +158,7 @@ const _clientErrorHandlerBase = async (client, err, clientName) => {
156158 */
157159const getMainClient = async ( ) => {
158160 if ( ! mainClient ) {
159- mainClient = await _createClientAndConnect ( async function ( err ) {
160- mainClient = null ;
161- await _clientErrorHandlerBase ( this , err , "main" ) ;
162- } ) ;
161+ mainClient = await _createClientAndConnect ( "main" ) ;
163162 }
164163 return mainClient ;
165164} ;
@@ -169,7 +168,10 @@ const getMainClient = async () => {
169168 *
170169 * @private
171170 */
172- const closeMainClient = async ( ) => await _closeClientBase ( mainClient ) ;
171+ const closeMainClient = async ( ) => {
172+ await _closeClientBase ( mainClient ) ;
173+ mainClient = null ;
174+ } ;
173175
174176/**
175177 * Lazily create a client to be used as a subscriber. Subscriber clients are in a special state and cannot be used for
@@ -182,10 +184,7 @@ const closeMainClient = async () => await _closeClientBase(mainClient);
182184 */
183185const getSubscriberClient = async ( ) => {
184186 if ( ! subscriberClient ) {
185- subscriberClient = await _createClientAndConnect ( async function ( err ) {
186- subscriberClient = null ;
187- await _clientErrorHandlerBase ( this , err , "subscriber" ) ;
188- } ) ;
187+ subscriberClient = await _createClientAndConnect ( "subscriber" ) ;
189188 }
190189 return subscriberClient ;
191190} ;
@@ -195,7 +194,10 @@ const getSubscriberClient = async () => {
195194 *
196195 * @private
197196 */
198- const closeSubscriberClient = async ( ) => await _closeClientBase ( subscriberClient ) ;
197+ const closeSubscriberClient = async ( ) => {
198+ await _closeClientBase ( subscriberClient ) ;
199+ subscriberClient = null ;
200+ } ;
199201
200202const _clientExec = async ( functionName , argsObject ) => {
201203 if ( ! mainClient ) {
0 commit comments