Skip to content

Commit

Permalink
The @synchronized and @synchronized_priority decorators now correctly…
Browse files Browse the repository at this point in the history
… handle exceptions to avoid dead locks.

Version updated to 1.1.0
  • Loading branch information
fernandoenzo committed Sep 7, 2020
1 parent a565205 commit cdb9888
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 9 deletions.
16 changes: 14 additions & 2 deletions parallel_utils/process/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,15 @@ def synchronized(max_threads: int = 1):
def locked(func):
@wraps(func)
def locked_func(*args, **kw_args):
exceptions = []
s.acquire()
res = func(*args, **kw_args)
try:
res = func(*args, **kw_args)
except Exception as e:
exceptions.append(e)
s.release()
if len(exceptions):
raise exceptions[0]
return res

return locked_func
Expand All @@ -45,9 +51,15 @@ def synchronized_priority(uid: Union[str, int], order: int = 1, total: int = Non
def locked(func):
@wraps(func)
def locked_func(*args, **kw_args):
exceptions = []
m.lock_priority_code(uid=uid, order=order, total=total)
res = func(*args, **kw_args)
try:
res = func(*args, **kw_args)
except Exception as e:
exceptions.append(e)
m.unlock_code(uid=uid)
if len(exceptions):
raise exceptions[0]
return res

return locked_func
Expand Down
24 changes: 18 additions & 6 deletions parallel_utils/thread/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,25 @@


def synchronized(max_threads: int = 1):
'''
"""
This decorator will allow only up to max_threads threads to run this function simultaneously.
:param max_threads: Maximum number of threads.
'''
"""

s = Semaphore(max_threads)

def locked(func):
@wraps(func)
def locked_func(*args, **kw_args):
exceptions = []
s.acquire()
res = func(*args, **kw_args)
try:
res = func(*args, **kw_args)
except Exception as e:
exceptions.append(e)
s.release()
if len(exceptions):
raise exceptions[0]
return res

return locked_func
Expand All @@ -34,20 +40,26 @@ def synchronized_priority(*args, **kwargs):
m = Monitor()

def synchronized_priority(uid: Union[str, int], order: int = 1, total: int = None):
'''
"""
This decorator will synchronize different threads to execute some functions
in a specific order to avoid race conditions.
:param uid: Unique identifier for the set of code snippets.
:param order: The priority of the function protected with this function's uid.
:param total: The total number of functions to synchronize using this function's uid.
'''
"""

def locked(func):
@wraps(func)
def locked_func(*args, **kw_args):
exceptions = []
m.lock_priority_code(uid=uid, order=order, total=total)
res = func(*args, **kw_args)
try:
res = func(*args, **kw_args)
except Exception as e:
exceptions.append(e)
m.unlock_code(uid=uid)
if len(exceptions):
raise exceptions[0]
return res

return locked_func
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
name = 'parallel-utils'

# https://www.python.org/dev/peps/pep-0440/#version-scheme
version = '1.0.0'
version = '1.1.0'

description = 'This library implements a class Monitor, as defined by Per Brinch Hansen and C.A.R. Hoare, ' \
'for synchronization and concurrent management of threads and processes in Python. It also provides other ' \
Expand Down

0 comments on commit cdb9888

Please sign in to comment.