在gatherResults完成后停止扭曲的反应堆 [英] stop a twisted reactor after a gatherResults has finished

查看:95
本文介绍了在gatherResults完成后停止扭曲的反应堆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

刚开始扭曲,只是尝试了一些延迟的东西。我有以下代码组成了100个延迟调用的列表-每个等待一个随机时间并返回一个值。该列表将打印结果,并最终终止反应堆。

new to twisted and just trying some deferred stuff out. I have the following code that makes up a list of 100 deferred calls - each waiting a random time and returning a value. That list the prints the results and finally terminates the reactor.

但是,我很确定我停止反应堆的方式可能是……不太好。

However, I'm pretty sure the way I'm stopping the reactor is probably... not great.

__author__ = 'Charlie'

from twisted.internet import defer, reactor
import random

def getDummyData(x):
    """returns a deferred object that will have a value in some random seconds
    sets up a callLater on the reactor to trgger the callback of d"""
    d = defer.Deferred()
    pause = random.randint(1,10)
    reactor.callLater(pause, d.callback, (x, pause))
    return d


def printData(result):
    """prints whatever is passed to it"""
    print result


def main():
    """makes a collection of deffered calls and then fires them. Stops reactor at end"""
    deferred_calls = [getDummyData(r) for r in range(0,100)]
    d = defer.gatherResults(deferred_calls, consumeErrors = True)
    d.addCallback(printData)

    # this additional callback on d stops the reacor
    # it fires after all the delayed callbacks have printed their values
    # the lambda ignored: ractor.stop() is required as callback takes a function
    # that takes a parameter.
    d.addCallback(lambda ignored: reactor.stop())

    # start the reactor.
    reactor.run()

if __name__ == "__main__":
    main()

我假设通过添加回调:

d.addCallback(lambda ignored: reactor.stop())

到收集的结果中实际上在所有延迟项目上添加了回调?

to the gathered results actually adds that callback on all the deferred items?

如果这样的话,可能有一种更优雅/更正确的方法呢?

if so then there is probably a more elegant / correct way to do it?

干杯! / p>

Cheers!

推荐答案


我假设通过添加回调:
d.addCallback(lambda被忽略:reactor.stop())
实际上会在所有延迟项上添加该回调吗?

I'm assuming that by adding a callback: d.addCallback(lambda ignored: reactor.stop()) to the gathered results actually adds that callback on all the deferred items?

这并非如此。 gatherResults 返回一个 new Deferred 。就像您遇到的任何其他 Deferred 一样。它的 addCallback 方法与往常一样:添加一个将在一个回调链中的某一时刻被调用的函数。

This isn't the case. gatherResults returns a new Deferred. It's just like any other Deferred you might come across. Its addCallback method does the same thing as usual: adds one function that will be called at one point in one callback chain.

之所以一切正常,正常且非常规,是因为 gatherResults 照顾了 only 赋予常规 Deferred ,它在所有输入 Deferred 都具有结果之后返回结果。

The reason everything is nice and regular and unspecial like this is that gatherResults takes care of all the logic necessary to only give that regular Deferred that it returns a result after all of the input Deferreds have a result.

因此,随时使用 gatherResults ,就像您使用任何其他 Deferred -返回API。

So, feel free to use gatherResults just like you're use any other Deferred-returning API. It's not special!

也就是说,从Twisted 12.3开始,您可能想要使用一种方便的实用程序- twisted。 internet.task.react 。如果您使用它,这就是您的 main 函数的样子:

That said, starting with Twisted 12.3 there's a handy utility that you might want to use for this sort of thing - twisted.internet.task.react. Here's what your main function would look like if you used it:

def main(reactor):
    """makes a collection of deffered calls and then fires them. Stops reactor at end"""
    deferred_calls = [getDummyData(r) for r in range(0,100)]
    d = defer.gatherResults(deferred_calls, consumeErrors = True)
    d.addCallback(printData)
    return d

if __name__ == "__main__":
    from twisted.internet import task
    task.react(main, [])

请注意,您可以更改 getDummyData ,以便它也不依赖于全局反应堆:

And notice that you could change getDummyData so that it doesn't depend on the global reactor either:

def getDummyData(reactor, x):
    """returns a deferred object that will have a value in some random seconds
    sets up a callLater on the reactor to trgger the callback of d"""
    d = defer.Deferred()
    pause = random.randint(1,10)
    reactor.callLater(pause, d.callback, (x, pause))
    return d

def main(reactor):
    """makes a collection of deffered calls and then fires them. Stops reactor at end"""
    deferred_calls = [getDummyData(reactor, r) for r in range(0,100)]
    d = defer.gatherResults(deferred_calls, consumeErrors = True)
    d.addCallback(printData)
    return d

现在您的代码不需要任何 twisted.internet.reactor 导入。

And now your code does't need any twisted.internet.reactor imports at all.

您还可以使用 twisted.internet.task。 getDummyData 中的deferLater 可以节省更多键入:

You could also use twisted.internet.task.deferLater in getDummyData to save a bit more typing:

def getDummyData(reactor, x):
    """returns a deferred object that will have a value in some random seconds
    sets up a callLater on the reactor to trgger the callback of d"""
    pause = random.randint(1,10)
    return deferLater(reactor, pause, lambda: (x, pause))

这篇关于在gatherResults完成后停止扭曲的反应堆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆