我有一个程序结构如下:
main():
LoopingCall(f1).start(1)
LoopingCall(f2).start(10)
reactor.run()
f1有一些处理某些阻塞操作的延迟。像这样:
f1():
deferred = some_blocking_operation()
deferred.addCallback(do_something_with_blocking_operartion_result)
deffered.addErrback(do_something_in_case_of_error)
f2进行一些记录。它没有扭曲的代码。
无论f1发生了什么,我都希望f2每10秒记录一次。
但事实并非如此。 f2以非常狂野的间隔调用,间隔50秒到2秒。
为什么会这样?
编辑1:
根据要求,f2代码:
f2():
logging.info("Last log: " + str(time.time() - self.last_log_time))
self.last_log_time = time.time()
f2是一个对象的方法,但是这个对象是一个帮助器,它实际上并不执行操作。对象f2是更多数据持有者的一部分。
修改2
因此,记录时间(f2)与f1所需的时间直接相关。如果f1需要30秒,从开始到结束,日志之间的时间(f2)也将是30秒。当f1等待some_blocking_operation()时,不应该调用f2吗?
编辑2的补遗:
问题显然是f1的结果,因为如果我将循环调用注释到f1,f2的循环调用正常工作(每10秒记录一次)。
我将添加更详细的f1草图,以更好地说明我正在做的事情。
编辑3:
这是f1中发生的更详细的草图。
class c1():
def __init__(self):
helper_object = c2() # f2 is part of c2, it is a helper function in a helper object
# I timed the read time, it's in the miliseconds, something like 1.5436354746e for example.
def read_from_pipe(self):
data = ""
try:
while True:
data += self.input_pipe.read(1)
except IOError:
pass
return data
# I timed this as well, it's also in the order of miliseconds.
def write_to_pipe(to_write):
self.output_pipe.write(to_write)
def success(self, result):
self.write_to_pipe("Good")
def fail(reason):
self.write_to_pipe("Bad")
def process_item(self, item):
deferred = some_blocking_operation_with_item(item)
deferred.addCallback(do_another_blocking_operation) # This appear to be the longest in terms of time, however, it's still 1 or 2 seconds, not 80 (longest time between f2 calls so far was 83)
deferred.addCallback(success)
deffered.addErrback(fail)
def schedule_input_for_processing(self, input):
for item in input: # There are no more than 50 items at a time
process_item(item)
def f1(self):
input = self.read_from_pipe() # read is non blocking - I do something like this
self.schedule_input_for_processing(input)
工作流程如下:
每个单独的阻止操作需要一点时间。我开始推测这是一种复合效应。每个input
有50个项目,所以如果每个项目需要1到2秒才能完成,我得到的记录时间将开始有意义。
但是,我的问题仍然存在,输入中的项目执行阻止操作时不应该触发f2()吗?
编辑4
好的,所以我恢复了我认识的版本。回调用于每10秒触发一次。现在,它没有。这真的很奇怪。我认为输入项目的大小可能与此有关。