1414
1515class RedisClient (object ):
1616
17- def __init__ (self , socket_connect_timeout = 30 , socket_timeout = None ):
18- self ._host = '127.0.0.1'
19- self ._port = 6379
20- self ._password = None
21- self ._parse_config ()
17+ def __init__ (self , socket_connect_timeout = 30 , socket_timeout = None ,
18+ health_check_interval = None , retry_on_timeout = None ):
19+ self ._host = REDIS_HOST
20+ self ._port = REDIS_PORT
21+ self ._password = REDIS_PASSWORD
22+
23+ self ._connection_kwargs = {
24+ 'host' : self ._host ,
25+ 'port' : self ._port ,
26+ 'password' : self ._password ,
27+ 'socket_timeout' : socket_timeout ,
28+ 'socket_connect_timeout' : socket_connect_timeout ,
29+ 'decode_responses' : True ,
30+ }
31+ if health_check_interval is not None :
32+ self ._connection_kwargs ['health_check_interval' ] = health_check_interval
33+ if retry_on_timeout is not None :
34+ self ._connection_kwargs ['retry_on_timeout' ] = retry_on_timeout
2235
2336 """
2437 By default, each Redis instance created will in turn create its own connection pool.
2538 Every caller using redis client will has it's own pool with config caller passed.
2639 """
27- self .connection = redis .Redis (
28- host = self ._host , port = self ._port , password = self ._password ,
29- socket_timeout = socket_timeout , socket_connect_timeout = socket_connect_timeout ,
30- decode_responses = True
31- )
32-
33- def _parse_config (self ):
40+ self ._redis = redis .Redis (** self ._connection_kwargs )
3441
35- self ._host = REDIS_HOST
36- self ._port = REDIS_PORT
37- self ._password = REDIS_PASSWORD
42+ def reconnect (self ):
43+ try :
44+ self ._redis .connection_pool .disconnect ()
45+ except Exception :
46+ pass
47+ self ._redis = redis .Redis (** self ._connection_kwargs )
48+ return self ._redis
3849
3950 def get_subscriber (self , channel_name ):
4051 while True :
4152 try :
42- subscriber = self .connection .pubsub (ignore_subscribe_messages = True )
53+ subscriber = self ._redis .pubsub (ignore_subscribe_messages = True )
4354 subscriber .subscribe (channel_name )
55+ logger .info ('redis pubsub success, success subscribe %s' , channel_name )
4456 except redis .AuthenticationError as e :
4557 logger .critical ('connect to redis auth error: %s' , e )
4658 raise e
@@ -50,20 +62,42 @@ def get_subscriber(self, channel_name):
5062 else :
5163 return subscriber
5264
65+ def close_subscriber (self , subscriber ):
66+ if not subscriber :
67+ return
68+ try :
69+ subscriber .close ()
70+ except Exception as e :
71+ logger .debug ('close redis subscriber failed: %s' , e )
72+
73+ def refresh_subscriber (self , subscriber , pubsub_channel_name , reason = 'unknown' ):
74+ logger .info ('reconnect redis pubsub channel=%s reason=%s' , pubsub_channel_name , reason )
75+ self .close_subscriber (subscriber )
76+ try :
77+ self .reconnect ()
78+ except Exception as e :
79+ logger .error ('redis reconnect failed channel=%s error=%s' , pubsub_channel_name , e )
80+ return self .get_subscriber (pubsub_channel_name )
81+
5382 def get (self , key ):
54- return self .connection .get (key )
83+ return self ._redis .get (key )
5584
5685 def set (self , key , value , timeout = None ):
5786 if not timeout :
58- return self .connection .set (key , value )
87+ return self ._redis .set (key , value )
5988 else :
60- return self .connection .setex (key , timeout , value )
89+ return self ._redis .setex (key , timeout , value )
6190
6291 def delete (self , key ):
63- return self .connection .delete (key )
92+ return self ._redis .delete (key )
6493
6594 def publish (self , channel_name , message ):
66- return self .connection .publish (channel_name , message )
95+ try :
96+ return self ._redis .publish (channel_name , message )
97+ except Exception as e :
98+ logger .warning ('redis publish failed on %s: %s' , channel_name , e )
99+ self .reconnect ()
100+ return self ._redis .publish (channel_name , message )
67101
68102
69103class RedisCache (object ):
0 commit comments