Support ignore_class and queue to noparallel decorator
This commit is contained in:
parent
cfb2276ecd
commit
233d5f31f2
2 changed files with 49 additions and 3 deletions
|
@ -14,6 +14,13 @@ class ExampleClass(object):
|
||||||
self.counted += 1
|
self.counted += 1
|
||||||
return "counted:%s" % i
|
return "counted:%s" % i
|
||||||
|
|
||||||
|
@util.Noparallel(queue=True, ignore_class=True)
|
||||||
|
def countQueue(self, num=5):
|
||||||
|
for i in range(1, num+1):
|
||||||
|
time.sleep(0.01)
|
||||||
|
self.counted += 1
|
||||||
|
return "counted:%s" % i
|
||||||
|
|
||||||
@util.Noparallel(blocking=False)
|
@util.Noparallel(blocking=False)
|
||||||
def countNoblocking(self, num=5):
|
def countNoblocking(self, num=5):
|
||||||
for i in range(1, num+1):
|
for i in range(1, num+1):
|
||||||
|
@ -57,3 +64,34 @@ class TestNoparallel:
|
||||||
|
|
||||||
obj1.countNoblocking().join() # Allow again and wait until finishes
|
obj1.countNoblocking().join() # Allow again and wait until finishes
|
||||||
assert obj1.counted == 10
|
assert obj1.counted == 10
|
||||||
|
|
||||||
|
def testQueue(self):
|
||||||
|
obj1 = ExampleClass()
|
||||||
|
|
||||||
|
threads = [
|
||||||
|
gevent.spawn(obj1.countQueue),
|
||||||
|
gevent.spawn(obj1.countQueue),
|
||||||
|
gevent.spawn(obj1.countQueue)
|
||||||
|
]
|
||||||
|
gevent.joinall(threads)
|
||||||
|
|
||||||
|
assert obj1.counted == 15 # Calls should be executed sequentially
|
||||||
|
|
||||||
|
def testIngoreClass(self):
|
||||||
|
obj1 = ExampleClass()
|
||||||
|
obj2 = ExampleClass()
|
||||||
|
|
||||||
|
threads = [
|
||||||
|
gevent.spawn(obj1.countQueue),
|
||||||
|
gevent.spawn(obj1.countQueue),
|
||||||
|
gevent.spawn(obj1.countQueue),
|
||||||
|
gevent.spawn(obj2.countQueue),
|
||||||
|
gevent.spawn(obj2.countQueue)
|
||||||
|
]
|
||||||
|
s = time.time()
|
||||||
|
gevent.joinall(threads)
|
||||||
|
assert obj1.counted == 15
|
||||||
|
assert obj2.counted == 10
|
||||||
|
|
||||||
|
taken = time.time() - s
|
||||||
|
assert taken >= 0.25 # Every count takes 0.05sec
|
||||||
|
|
|
@ -4,14 +4,18 @@ import time
|
||||||
|
|
||||||
class Noparallel(object): # Only allow function running once in same time
|
class Noparallel(object): # Only allow function running once in same time
|
||||||
|
|
||||||
def __init__(self, blocking=True, ignore_args=False):
|
def __init__(self, blocking=True, ignore_args=False, ignore_class=False, queue=False):
|
||||||
self.threads = {}
|
self.threads = {}
|
||||||
self.blocking = blocking # Blocking: Acts like normal function else thread returned
|
self.blocking = blocking # Blocking: Acts like normal function else thread returned
|
||||||
|
self.queue = queue
|
||||||
self.ignore_args = ignore_args
|
self.ignore_args = ignore_args
|
||||||
|
self.ignore_class = ignore_class
|
||||||
|
|
||||||
def __call__(self, func):
|
def __call__(self, func):
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
if self.ignore_args:
|
if self.ignore_class:
|
||||||
|
key = func # Unique key only by function and class object
|
||||||
|
elif self.ignore_args:
|
||||||
key = (func, args[0]) # Unique key only by function and class object
|
key = (func, args[0]) # Unique key only by function and class object
|
||||||
else:
|
else:
|
||||||
key = (func, tuple(args), str(kwargs)) # Unique key for function including parameters
|
key = (func, tuple(args), str(kwargs)) # Unique key for function including parameters
|
||||||
|
@ -19,7 +23,11 @@ class Noparallel(object): # Only allow function running once in same time
|
||||||
thread = self.threads[key]
|
thread = self.threads[key]
|
||||||
if self.blocking:
|
if self.blocking:
|
||||||
thread.join() # Blocking until its finished
|
thread.join() # Blocking until its finished
|
||||||
|
if self.queue:
|
||||||
|
return wrapper(*args, **kwargs) # Run again
|
||||||
|
else:
|
||||||
return thread.value # Return the value
|
return thread.value # Return the value
|
||||||
|
|
||||||
else: # No blocking
|
else: # No blocking
|
||||||
if thread.ready(): # Its finished, create a new
|
if thread.ready(): # Its finished, create a new
|
||||||
thread = gevent.spawn(func, *args, **kwargs)
|
thread = gevent.spawn(func, *args, **kwargs)
|
||||||
|
|
Loading…
Reference in a new issue