22Backend for django cache
33"""
44import socket
5+ from functools import wraps
56from django .core .cache import InvalidCacheBackendError
67from django .core .cache .backends .memcached import PyLibMCCache
7- from django .utils .functional import cached_property
88from .cluster_utils import get_cluster_info
99
1010
11+ def invalidate_cache_after_error (f ):
12+ """
13+ catch any exception and invalidate internal cache with list of nodes
14+ """
15+ @wraps (f )
16+ def wrapper (self , * args , ** kwds ):
17+ try :
18+ return f (self , * args , ** kwds )
19+ except Exception :
20+ self .clear_cluster_nodes_cache ()
21+ raise
22+ return wrapper
23+
24+
1125class ElastiCache (PyLibMCCache ):
1226 """
1327 backend for Amazon ElastiCache (memcached) with auto discovery mode
@@ -40,18 +54,25 @@ def update_params(self, params):
4054 'ketama' : True
4155 }
4256
43- @cached_property
57+ def clear_cluster_nodes_cache (self ):
58+ """clear internal cache with list of nodes in cluster"""
59+ if hasattr (self , '_cluster_nodes_cache' ):
60+ del self ._cluster_nodes_cache
61+
4462 def get_cluster_nodes (self ):
4563 """
4664 return list with all nodes in cluster
4765 """
48- server , port = self ._servers [0 ].split (':' )
49- try :
50- return get_cluster_info (server , port )['nodes' ]
51- except (socket .gaierror , socket .timeout ) as err :
52- raise Exception ('Cannot connect to cluster {} ({})' .format (
53- self ._servers [0 ], err
54- ))
66+ if not hasattr (self , '_cluster_nodes_cache' ):
67+ server , port = self ._servers [0 ].split (':' )
68+ try :
69+ self ._cluster_nodes_cache = (
70+ get_cluster_info (server , port )['nodes' ])
71+ except (socket .gaierror , socket .timeout ) as err :
72+ raise Exception ('Cannot connect to cluster {} ({})' .format (
73+ self ._servers [0 ], err
74+ ))
75+ return self ._cluster_nodes_cache
5576
5677 @property
5778 def _cache (self ):
@@ -67,10 +88,30 @@ def _cache(self):
6788 if client :
6889 return client
6990
70- client = self ._lib .Client (self .get_cluster_nodes )
91+ client = self ._lib .Client (self .get_cluster_nodes () )
7192 if self ._options :
7293 client .behaviors = self ._options
7394
7495 container ._client = client
7596
7697 return client
98+
99+ @invalidate_cache_after_error
100+ def get (self , * args , ** kwargs ):
101+ return super (ElastiCache , self ).get (* args , ** kwargs )
102+
103+ @invalidate_cache_after_error
104+ def get_many (self , * args , ** kwargs ):
105+ return super (ElastiCache , self ).get_many (* args , ** kwargs )
106+
107+ @invalidate_cache_after_error
108+ def set (self , * args , ** kwargs ):
109+ return super (ElastiCache , self ).set (* args , ** kwargs )
110+
111+ @invalidate_cache_after_error
112+ def set_many (self , * args , ** kwargs ):
113+ return super (ElastiCache , self ).set_many (* args , ** kwargs )
114+
115+ @invalidate_cache_after_error
116+ def delete (self , * args , ** kwargs ):
117+ return super (ElastiCache , self ).delete (* args , ** kwargs )
0 commit comments