Reputation: 141
Inside a function I'm using a retry mechanism like that (always in a try/except block):
def load(self):
[........]
# Retry mechanism for locking database
for i in range(1, max_connection_retries+1):
try:
cu.lock()
break
except LockError as l_error:
if i < max_connection_retries:
sleep(20)
continue
else:
raise ContinuableError (logger.console(datetime.now().time().strftime ("%b %d %H:%M:%S") + ' ERROR:Impossible to lock the database after %i retries' % max_connection_retries))
[.......]
I'm using this mechanism several times in others part of the same function and in other functions. It would be possible to apply a decorator to only this part of the code ? something like that:
def load(self):
[.......]
@retry(max=5,message='blablabla')
try:
cu.lock()
break
except LockError as l_error:
[.......]
@retry(max=5)
try:
cu.unlock()
break
except LockError as l_error:
If so, could you help me showing me an example of a decorator for doing such task ?
Upvotes: 6
Views: 8703
Reputation: 39536
As said decorator can be applied only to function, but can move "retry" logic to separate function and pass cu.lock
/cu.unlock
(and other stuff like max
, messge
) to that function as params:
def retry(func, tries, message):
for i in range(1, tries+1):
try:
func() # <- call passed function
break
except LockError as l_error:
if i < tries:
sleep(20)
continue
else:
raise ContinuableError('...')
def load(self):
retry(cu.lock, tries=5, message='blablabla') # pass cu.lock to be called
retry(cu.unlock, tries=5, message='blablabla') # pass cu.unlock to be called
Upvotes: 2
Reputation: 530970
The decorator syntax is just syntactic sugar for
# f could be a class as well
def f():
...
f = retry(f)
It cannot be applied to arbitrary anonymous blocks of code. The main purpose of a decorator is to rebind a name, and an anonymous block, by definition, has no name.
What you would need to do is refactor the code you want to retry into a function that gets decorated. For example,
@retry(max=5, message='blablabla')
def get_lock():
try:
cu.lock()
except LockError as l_error:
# Some action dependent on the implementation of retry
def load(self):
get_lock()
Upvotes: 5