Rev427, Ignore repr from coverage, Add RateLimit call penalty to, Event test, Noparallel test, RateLimit test, Remove falling Pypy test
This commit is contained in:
parent
8f7df0f7fb
commit
47dbdc0850
9 changed files with 342 additions and 133 deletions
|
@ -2,10 +2,6 @@ language: python
|
||||||
cache: pip
|
cache: pip
|
||||||
python:
|
python:
|
||||||
- 2.7
|
- 2.7
|
||||||
- pypy
|
|
||||||
matrix:
|
|
||||||
allow_failures:
|
|
||||||
- pypy
|
|
||||||
install:
|
install:
|
||||||
- pip install -r requirements.txt
|
- pip install -r requirements.txt
|
||||||
before_script:
|
before_script:
|
||||||
|
|
|
@ -8,7 +8,7 @@ class Config(object):
|
||||||
|
|
||||||
def __init__(self, argv):
|
def __init__(self, argv):
|
||||||
self.version = "0.3.2"
|
self.version = "0.3.2"
|
||||||
self.rev = 426
|
self.rev = 427
|
||||||
self.argv = argv
|
self.argv = argv
|
||||||
self.action = None
|
self.action = None
|
||||||
self.createParser()
|
self.createParser()
|
||||||
|
|
65
src/Test/TestEvent.py
Normal file
65
src/Test/TestEvent.py
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
import util
|
||||||
|
|
||||||
|
|
||||||
|
class TestClass(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.called = []
|
||||||
|
self.onChanged = util.Event()
|
||||||
|
|
||||||
|
def increment(self, title):
|
||||||
|
self.called.append(title)
|
||||||
|
|
||||||
|
|
||||||
|
class TestEvent:
|
||||||
|
def testEvent(self):
|
||||||
|
test_obj = TestClass()
|
||||||
|
test_obj.onChanged.append(lambda: test_obj.increment("Called #1"))
|
||||||
|
test_obj.onChanged.append(lambda: test_obj.increment("Called #2"))
|
||||||
|
test_obj.onChanged.once(lambda: test_obj.increment("Once"))
|
||||||
|
|
||||||
|
assert test_obj.called == []
|
||||||
|
test_obj.onChanged()
|
||||||
|
assert test_obj.called == ["Called #1", "Called #2", "Once"]
|
||||||
|
test_obj.onChanged()
|
||||||
|
test_obj.onChanged()
|
||||||
|
assert test_obj.called == ["Called #1", "Called #2", "Once", "Called #1", "Called #2", "Called #1", "Called #2"]
|
||||||
|
|
||||||
|
def testOnce(self):
|
||||||
|
test_obj = TestClass()
|
||||||
|
test_obj.onChanged.once(lambda: test_obj.increment("Once test #1"))
|
||||||
|
|
||||||
|
# It should be called only once
|
||||||
|
assert test_obj.called == []
|
||||||
|
test_obj.onChanged()
|
||||||
|
assert test_obj.called == ["Once test #1"]
|
||||||
|
test_obj.onChanged()
|
||||||
|
test_obj.onChanged()
|
||||||
|
assert test_obj.called == ["Once test #1"]
|
||||||
|
|
||||||
|
def testOnceMultiple(self):
|
||||||
|
test_obj = TestClass()
|
||||||
|
# Allow queue more than once
|
||||||
|
test_obj.onChanged.once(lambda: test_obj.increment("Once test #1"))
|
||||||
|
test_obj.onChanged.once(lambda: test_obj.increment("Once test #2"))
|
||||||
|
test_obj.onChanged.once(lambda: test_obj.increment("Once test #3"))
|
||||||
|
|
||||||
|
assert test_obj.called == []
|
||||||
|
test_obj.onChanged()
|
||||||
|
assert test_obj.called == ["Once test #1", "Once test #2", "Once test #3"]
|
||||||
|
test_obj.onChanged()
|
||||||
|
test_obj.onChanged()
|
||||||
|
assert test_obj.called == ["Once test #1", "Once test #2", "Once test #3"]
|
||||||
|
|
||||||
|
def testOnceNamed(self):
|
||||||
|
test_obj = TestClass()
|
||||||
|
# Dont store more that one from same type
|
||||||
|
test_obj.onChanged.once(lambda: test_obj.increment("Once test #1/1"), "type 1")
|
||||||
|
test_obj.onChanged.once(lambda: test_obj.increment("Once test #1/2"), "type 1")
|
||||||
|
test_obj.onChanged.once(lambda: test_obj.increment("Once test #2"), "type 2")
|
||||||
|
|
||||||
|
assert test_obj.called == []
|
||||||
|
test_obj.onChanged()
|
||||||
|
assert test_obj.called == ["Once test #1/1", "Once test #2"]
|
||||||
|
test_obj.onChanged()
|
||||||
|
test_obj.onChanged()
|
||||||
|
assert test_obj.called == ["Once test #1/1", "Once test #2"]
|
62
src/Test/TestNoparallel.py
Normal file
62
src/Test/TestNoparallel.py
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
import time
|
||||||
|
|
||||||
|
import gevent
|
||||||
|
from gevent import monkey
|
||||||
|
monkey.patch_all()
|
||||||
|
|
||||||
|
import util
|
||||||
|
|
||||||
|
class TestClass(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.counted = 0
|
||||||
|
|
||||||
|
@util.Noparallel()
|
||||||
|
def countBlocking(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)
|
||||||
|
def countNoblocking(self, num=5):
|
||||||
|
for i in range(1, num+1):
|
||||||
|
time.sleep(0.01)
|
||||||
|
self.counted += 1
|
||||||
|
return "counted:%s" % i
|
||||||
|
|
||||||
|
|
||||||
|
class TestNoparallel:
|
||||||
|
def testBlocking(self):
|
||||||
|
obj1 = TestClass()
|
||||||
|
obj2 = TestClass()
|
||||||
|
|
||||||
|
# Dont allow to call again until its running and wait until its running
|
||||||
|
threads = [
|
||||||
|
gevent.spawn(obj1.countBlocking),
|
||||||
|
gevent.spawn(obj1.countBlocking),
|
||||||
|
gevent.spawn(obj1.countBlocking),
|
||||||
|
gevent.spawn(obj2.countBlocking)
|
||||||
|
]
|
||||||
|
assert obj2.countBlocking() == "counted:5" # The call is ignored as obj2.countBlocking already counting, but block until its finishes
|
||||||
|
gevent.joinall(threads)
|
||||||
|
assert [thread.value for thread in threads] == ["counted:5","counted:5","counted:5","counted:5"] # Check the return value for every call
|
||||||
|
obj2.countBlocking() # Allow to call again as obj2.countBlocking finished
|
||||||
|
|
||||||
|
assert obj1.counted == 5
|
||||||
|
assert obj2.counted == 10
|
||||||
|
|
||||||
|
def testNoblocking(self):
|
||||||
|
obj1 = TestClass()
|
||||||
|
obj2 = TestClass()
|
||||||
|
|
||||||
|
thread1 = obj1.countNoblocking()
|
||||||
|
thread2 = obj1.countNoblocking() # Ignored
|
||||||
|
|
||||||
|
assert obj1.counted == 0
|
||||||
|
time.sleep(0.1)
|
||||||
|
assert thread1.value == "counted:5"
|
||||||
|
assert thread2.value == "counted:5"
|
||||||
|
assert obj1.counted == 5
|
||||||
|
|
||||||
|
obj1.countNoblocking().join() # Allow again and wait until finishes
|
||||||
|
assert obj1.counted == 10
|
96
src/Test/TestRateLimit.py
Normal file
96
src/Test/TestRateLimit.py
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
import time
|
||||||
|
|
||||||
|
import gevent
|
||||||
|
from gevent import monkey
|
||||||
|
monkey.patch_all()
|
||||||
|
|
||||||
|
from util import RateLimit
|
||||||
|
|
||||||
|
|
||||||
|
# Time is around limit +/- 0.01 sec
|
||||||
|
def around(t, limit):
|
||||||
|
return t >= limit - 0.01 and t <= limit + 0.01
|
||||||
|
|
||||||
|
|
||||||
|
class TestClass(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.counted = 0
|
||||||
|
self.last_called = None
|
||||||
|
|
||||||
|
def count(self, back="counted"):
|
||||||
|
self.counted += 1
|
||||||
|
self.last_called = back
|
||||||
|
return back
|
||||||
|
|
||||||
|
|
||||||
|
class TestRateLimit:
|
||||||
|
def testCall(self):
|
||||||
|
obj1 = TestClass()
|
||||||
|
obj2 = TestClass()
|
||||||
|
|
||||||
|
s = time.time()
|
||||||
|
assert RateLimit.call("counting", allowed_again=0.1, func=obj1.count) == "counted"
|
||||||
|
assert around(time.time() - s, 0.0) # First allow to call instantly
|
||||||
|
assert obj1.counted == 1
|
||||||
|
|
||||||
|
# Call again
|
||||||
|
assert not RateLimit.isAllowed("counting", 0.1)
|
||||||
|
assert RateLimit.isAllowed("something else", 0.1)
|
||||||
|
assert RateLimit.call("counting", allowed_again=0.1, func=obj1.count) == "counted"
|
||||||
|
assert around(time.time() - s, 0.1) # Delays second call within interval
|
||||||
|
assert obj1.counted == 2
|
||||||
|
|
||||||
|
# Call 3 times async
|
||||||
|
s = time.time()
|
||||||
|
assert obj2.counted == 0
|
||||||
|
threads = [
|
||||||
|
gevent.spawn(lambda: RateLimit.call("counting", allowed_again=0.1, func=obj2.count)), # Instant
|
||||||
|
gevent.spawn(lambda: RateLimit.call("counting", allowed_again=0.1, func=obj2.count)), # 0.1s delay
|
||||||
|
gevent.spawn(lambda: RateLimit.call("counting", allowed_again=0.1, func=obj2.count)) # 0.2s delay
|
||||||
|
]
|
||||||
|
gevent.joinall(threads)
|
||||||
|
assert [thread.value for thread in threads] == ["counted", "counted", "counted"]
|
||||||
|
assert around(time.time() - s, 0.2)
|
||||||
|
|
||||||
|
# No queue = instant again
|
||||||
|
s = time.time()
|
||||||
|
assert RateLimit.isAllowed("counting", 0.1)
|
||||||
|
assert RateLimit.call("counting", allowed_again=0.1, func=obj2.count) == "counted"
|
||||||
|
assert around(time.time() - s, 0.0)
|
||||||
|
|
||||||
|
assert obj2.counted == 4
|
||||||
|
|
||||||
|
def testCallAsync(self):
|
||||||
|
obj1 = TestClass()
|
||||||
|
obj2 = TestClass()
|
||||||
|
|
||||||
|
s = time.time()
|
||||||
|
RateLimit.callAsync("counting async", allowed_again=0.1, func=obj1.count, back="call #1").join()
|
||||||
|
assert obj1.counted == 1 # First instant
|
||||||
|
assert around(time.time() - s, 0.0)
|
||||||
|
|
||||||
|
# After that the calls delayed
|
||||||
|
s = time.time()
|
||||||
|
t1 = RateLimit.callAsync("counting async", allowed_again=0.1, func=obj1.count, back="call #2") # Dumped by the next call
|
||||||
|
time.sleep(0.03)
|
||||||
|
t2 = RateLimit.callAsync("counting async", allowed_again=0.1, func=obj1.count, back="call #3") # Dumped by the next call
|
||||||
|
time.sleep(0.03)
|
||||||
|
t3 = RateLimit.callAsync("counting async", allowed_again=0.1, func=obj1.count, back="call #4") # Will be called
|
||||||
|
assert obj1.counted == 1 # Delay still in progress: Not called yet
|
||||||
|
t3.join()
|
||||||
|
assert t3.value == "call #4"
|
||||||
|
assert around(time.time() - s, 0.1)
|
||||||
|
|
||||||
|
# Only the last one called
|
||||||
|
assert obj1.counted == 2
|
||||||
|
assert obj1.last_called == "call #4"
|
||||||
|
|
||||||
|
# Allowed again instantly
|
||||||
|
assert RateLimit.isAllowed("counting async", 0.1)
|
||||||
|
s = time.time()
|
||||||
|
RateLimit.callAsync("counting async", allowed_again=0.1, func=obj1.count, back="call #5").join()
|
||||||
|
assert obj1.counted == 3
|
||||||
|
assert around(time.time() - s, 0.0)
|
||||||
|
assert not RateLimit.isAllowed("counting async", 0.1)
|
||||||
|
time.sleep(0.11)
|
||||||
|
assert RateLimit.isAllowed("counting async", 0.1)
|
|
@ -1,5 +1,6 @@
|
||||||
[run]
|
[run]
|
||||||
branch = True
|
branch = True
|
||||||
|
concurrency = gevent
|
||||||
omit =
|
omit =
|
||||||
src/lib/*
|
src/lib/*
|
||||||
src/Test/*
|
src/Test/*
|
||||||
|
@ -7,11 +8,8 @@ omit =
|
||||||
[report]
|
[report]
|
||||||
exclude_lines =
|
exclude_lines =
|
||||||
pragma: no cover
|
pragma: no cover
|
||||||
|
|
||||||
if __name__ == .__main__.:
|
if __name__ == .__main__.:
|
||||||
|
|
||||||
if config.debug:
|
if config.debug:
|
||||||
|
|
||||||
if config.debug_socket:
|
if config.debug_socket:
|
||||||
|
if self.logging:
|
||||||
if self.logging:
|
def __repr__
|
||||||
|
|
|
@ -25,33 +25,31 @@ class Event(list):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
def testBenchmark():
|
|
||||||
def say(pre, text):
|
|
||||||
print "%s Say: %s" % (pre, text)
|
|
||||||
|
|
||||||
import time
|
|
||||||
s = time.time()
|
|
||||||
on_changed = Event()
|
|
||||||
for i in range(1000):
|
|
||||||
on_changed.once(lambda pre: say(pre, "once"), "once")
|
|
||||||
print "Created 1000 once in %.3fs" % (time.time() - s)
|
|
||||||
on_changed("#1")
|
|
||||||
|
|
||||||
|
|
||||||
def testUsage():
|
|
||||||
def say(pre, text):
|
|
||||||
print "%s Say: %s" % (pre, text)
|
|
||||||
|
|
||||||
on_changed = Event()
|
|
||||||
on_changed.once(lambda pre: say(pre, "once"))
|
|
||||||
on_changed.once(lambda pre: say(pre, "once"))
|
|
||||||
on_changed.once(lambda pre: say(pre, "namedonce"), "namedonce")
|
|
||||||
on_changed.once(lambda pre: say(pre, "namedonce"), "namedonce")
|
|
||||||
on_changed.append(lambda pre: say(pre, "always"))
|
|
||||||
on_changed("#1")
|
|
||||||
on_changed("#2")
|
|
||||||
on_changed("#3")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
def testBenchmark():
|
||||||
|
def say(pre, text):
|
||||||
|
print "%s Say: %s" % (pre, text)
|
||||||
|
|
||||||
|
import time
|
||||||
|
s = time.time()
|
||||||
|
on_changed = Event()
|
||||||
|
for i in range(1000):
|
||||||
|
on_changed.once(lambda pre: say(pre, "once"), "once")
|
||||||
|
print "Created 1000 once in %.3fs" % (time.time() - s)
|
||||||
|
on_changed("#1")
|
||||||
|
|
||||||
|
def testUsage():
|
||||||
|
def say(pre, text):
|
||||||
|
print "%s Say: %s" % (pre, text)
|
||||||
|
|
||||||
|
on_changed = Event()
|
||||||
|
on_changed.once(lambda pre: say(pre, "once"))
|
||||||
|
on_changed.once(lambda pre: say(pre, "once"))
|
||||||
|
on_changed.once(lambda pre: say(pre, "namedonce"), "namedonce")
|
||||||
|
on_changed.once(lambda pre: say(pre, "namedonce"), "namedonce")
|
||||||
|
on_changed.append(lambda pre: say(pre, "always"))
|
||||||
|
on_changed("#1")
|
||||||
|
on_changed("#2")
|
||||||
|
on_changed("#3")
|
||||||
|
|
||||||
testBenchmark()
|
testBenchmark()
|
||||||
|
|
|
@ -43,98 +43,92 @@ class Noparallel(object): # Only allow function running once in same time
|
||||||
del(self.threads[key])
|
del(self.threads[key])
|
||||||
|
|
||||||
|
|
||||||
class Test():
|
|
||||||
|
|
||||||
@Noparallel()
|
|
||||||
def count(self, num=5):
|
|
||||||
for i in range(num):
|
|
||||||
print self, i
|
|
||||||
time.sleep(1)
|
|
||||||
return "%s return:%s" % (self, i)
|
|
||||||
|
|
||||||
|
|
||||||
class TestNoblock():
|
|
||||||
|
|
||||||
@Noparallel(blocking=False)
|
|
||||||
def count(self, num=5):
|
|
||||||
for i in range(num):
|
|
||||||
print self, i
|
|
||||||
time.sleep(1)
|
|
||||||
return "%s return:%s" % (self, i)
|
|
||||||
|
|
||||||
|
|
||||||
def testBlocking():
|
|
||||||
test = Test()
|
|
||||||
test2 = Test()
|
|
||||||
print "Counting..."
|
|
||||||
print "Creating class1/thread1"
|
|
||||||
thread1 = gevent.spawn(test.count)
|
|
||||||
print "Creating class1/thread2 (ignored)"
|
|
||||||
thread2 = gevent.spawn(test.count)
|
|
||||||
print "Creating class2/thread3"
|
|
||||||
thread3 = gevent.spawn(test2.count)
|
|
||||||
|
|
||||||
print "Joining class1/thread1"
|
|
||||||
thread1.join()
|
|
||||||
print "Joining class1/thread2"
|
|
||||||
thread2.join()
|
|
||||||
print "Joining class2/thread3"
|
|
||||||
thread3.join()
|
|
||||||
|
|
||||||
print "Creating class1/thread4 (its finished, allowed again)"
|
|
||||||
thread4 = gevent.spawn(test.count)
|
|
||||||
print "Joining thread4"
|
|
||||||
thread4.join()
|
|
||||||
|
|
||||||
print thread1.value, thread2.value, thread3.value, thread4.value
|
|
||||||
print "Done."
|
|
||||||
|
|
||||||
|
|
||||||
def testNoblocking():
|
|
||||||
test = TestNoblock()
|
|
||||||
test2 = TestNoblock()
|
|
||||||
print "Creating class1/thread1"
|
|
||||||
thread1 = test.count()
|
|
||||||
print "Creating class1/thread2 (ignored)"
|
|
||||||
thread2 = test.count()
|
|
||||||
print "Creating class2/thread3"
|
|
||||||
thread3 = test2.count()
|
|
||||||
print "Joining class1/thread1"
|
|
||||||
thread1.join()
|
|
||||||
print "Joining class1/thread2"
|
|
||||||
thread2.join()
|
|
||||||
print "Joining class2/thread3"
|
|
||||||
thread3.join()
|
|
||||||
|
|
||||||
print "Creating class1/thread4 (its finished, allowed again)"
|
|
||||||
thread4 = test.count()
|
|
||||||
print "Joining thread4"
|
|
||||||
thread4.join()
|
|
||||||
|
|
||||||
print thread1.value, thread2.value, thread3.value, thread4.value
|
|
||||||
print "Done."
|
|
||||||
|
|
||||||
|
|
||||||
def testBenchmark():
|
|
||||||
import time
|
|
||||||
|
|
||||||
def printThreadNum():
|
|
||||||
import gc
|
|
||||||
from greenlet import greenlet
|
|
||||||
objs = [obj for obj in gc.get_objects() if isinstance(obj, greenlet)]
|
|
||||||
print "Greenlets: %s" % len(objs)
|
|
||||||
|
|
||||||
printThreadNum()
|
|
||||||
test = TestNoblock()
|
|
||||||
s = time.time()
|
|
||||||
for i in range(3):
|
|
||||||
gevent.spawn(test.count, i + 1)
|
|
||||||
print "Created in %.3fs" % (time.time() - s)
|
|
||||||
printThreadNum()
|
|
||||||
time.sleep(5)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
class Test():
|
||||||
|
|
||||||
|
@Noparallel()
|
||||||
|
def count(self, num=5):
|
||||||
|
for i in range(num):
|
||||||
|
print self, i
|
||||||
|
time.sleep(1)
|
||||||
|
return "%s return:%s" % (self, i)
|
||||||
|
|
||||||
|
class TestNoblock():
|
||||||
|
|
||||||
|
@Noparallel(blocking=False)
|
||||||
|
def count(self, num=5):
|
||||||
|
for i in range(num):
|
||||||
|
print self, i
|
||||||
|
time.sleep(1)
|
||||||
|
return "%s return:%s" % (self, i)
|
||||||
|
|
||||||
|
def testBlocking():
|
||||||
|
test = Test()
|
||||||
|
test2 = Test()
|
||||||
|
print "Counting..."
|
||||||
|
print "Creating class1/thread1"
|
||||||
|
thread1 = gevent.spawn(test.count)
|
||||||
|
print "Creating class1/thread2 (ignored)"
|
||||||
|
thread2 = gevent.spawn(test.count)
|
||||||
|
print "Creating class2/thread3"
|
||||||
|
thread3 = gevent.spawn(test2.count)
|
||||||
|
|
||||||
|
print "Joining class1/thread1"
|
||||||
|
thread1.join()
|
||||||
|
print "Joining class1/thread2"
|
||||||
|
thread2.join()
|
||||||
|
print "Joining class2/thread3"
|
||||||
|
thread3.join()
|
||||||
|
|
||||||
|
print "Creating class1/thread4 (its finished, allowed again)"
|
||||||
|
thread4 = gevent.spawn(test.count)
|
||||||
|
print "Joining thread4"
|
||||||
|
thread4.join()
|
||||||
|
|
||||||
|
print thread1.value, thread2.value, thread3.value, thread4.value
|
||||||
|
print "Done."
|
||||||
|
|
||||||
|
def testNoblocking():
|
||||||
|
test = TestNoblock()
|
||||||
|
test2 = TestNoblock()
|
||||||
|
print "Creating class1/thread1"
|
||||||
|
thread1 = test.count()
|
||||||
|
print "Creating class1/thread2 (ignored)"
|
||||||
|
thread2 = test.count()
|
||||||
|
print "Creating class2/thread3"
|
||||||
|
thread3 = test2.count()
|
||||||
|
print "Joining class1/thread1"
|
||||||
|
thread1.join()
|
||||||
|
print "Joining class1/thread2"
|
||||||
|
thread2.join()
|
||||||
|
print "Joining class2/thread3"
|
||||||
|
thread3.join()
|
||||||
|
|
||||||
|
print "Creating class1/thread4 (its finished, allowed again)"
|
||||||
|
thread4 = test.count()
|
||||||
|
print "Joining thread4"
|
||||||
|
thread4.join()
|
||||||
|
|
||||||
|
print thread1.value, thread2.value, thread3.value, thread4.value
|
||||||
|
print "Done."
|
||||||
|
|
||||||
|
def testBenchmark():
|
||||||
|
import time
|
||||||
|
|
||||||
|
def printThreadNum():
|
||||||
|
import gc
|
||||||
|
from greenlet import greenlet
|
||||||
|
objs = [obj for obj in gc.get_objects() if isinstance(obj, greenlet)]
|
||||||
|
print "Greenlets: %s" % len(objs)
|
||||||
|
|
||||||
|
printThreadNum()
|
||||||
|
test = TestNoblock()
|
||||||
|
s = time.time()
|
||||||
|
for i in range(3):
|
||||||
|
gevent.spawn(test.count, i + 1)
|
||||||
|
print "Created in %.3fs" % (time.time() - s)
|
||||||
|
printThreadNum()
|
||||||
|
time.sleep(5)
|
||||||
from gevent import monkey
|
from gevent import monkey
|
||||||
monkey.patch_all()
|
monkey.patch_all()
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ queue_db = {} # Commands queued to run
|
||||||
# Return: None
|
# Return: None
|
||||||
|
|
||||||
|
|
||||||
def called(event):
|
def called(event, penalty=0):
|
||||||
called_db[event] = time.time()
|
called_db[event] = time.time() + penalty
|
||||||
|
|
||||||
|
|
||||||
# Check if calling event is allowed
|
# Check if calling event is allowed
|
||||||
|
@ -62,15 +62,15 @@ def callAsync(event, allowed_again=10, func=None, *args, **kwargs):
|
||||||
def call(event, allowed_again=10, func=None, *args, **kwargs):
|
def call(event, allowed_again=10, func=None, *args, **kwargs):
|
||||||
if isAllowed(event): # Not called recently, call it now
|
if isAllowed(event): # Not called recently, call it now
|
||||||
called(event)
|
called(event)
|
||||||
# print "Calling now"
|
# print "Calling now", allowed_again
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
else: # Called recently, schedule it for later
|
else: # Called recently, schedule it for later
|
||||||
time_left = max(0, allowed_again - (time.time() - called_db[event]))
|
time_left = max(0, allowed_again - (time.time() - called_db[event]))
|
||||||
# print "Time left: %s" % time_left, args, kwargs
|
# print "Time left: %s" % time_left, args, kwargs
|
||||||
log.debug("Calling sync (%.2fs left): %s" % (time_left, event))
|
log.debug("Calling sync (%.2fs left): %s" % (time_left, event))
|
||||||
|
called(event, time_left)
|
||||||
time.sleep(time_left)
|
time.sleep(time_left)
|
||||||
called(event)
|
|
||||||
back = func(*args, **kwargs)
|
back = func(*args, **kwargs)
|
||||||
if event in called_db:
|
if event in called_db:
|
||||||
del called_db[event]
|
del called_db[event]
|
||||||
|
|
Loading…
Reference in a new issue