Twisted Python - 两个循环调用,一个不按给定间隔触发

时间:2016-01-11 15:42:52

标签: python asynchronous twisted twisted.internet

我有一个程序结构如下:

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)

工作流程如下:

  1. 从管道获取输入(读取为非阻塞,不应影响f2)
  2. 说输入是一个列表。对列表中的每个元素执行某些操作。
  3. 对列表的每个元素执行的“某事”是阻塞操作。但是,它是一个相当短的,通常不会超过0.5到1秒。
  4. 完成该操作后,如果没有发生错误,则触发第二个回调,执行另一个阻塞操作。这通常需要1到2秒。
  5. 写入输出管道
  6. 每个单独的阻止操作需要一点时间。我开始推测这是一种复合效应。每个input有50个项目,所以如果每个项目需要1到2秒才能完成,我得到的记录时间将开始有意义。

    但是,我的问题仍然存在,输入中的项目执行阻止操作时不应该触发f2()吗?

    编辑4

    好的,所以我恢复了我认识的版本。回调用于每10秒触发一次。现在,它没有。这真的很奇怪。我认为输入项目的大小可能与此有关。

0 个答案:

没有答案