在 Twisted 应用程序中使用延迟对象

发布于 2024-12-12 05:23:46 字数 313 浏览 0 评论 0原文

我觉得我在编写 Twisted 应用程序(.tac 文件)时不理解一些事情。在 .py 脚本中使用延迟对象很简单,只需在最后调用 reactor.run() 即可,但我还没有看到 reactor.run() 在任何扭曲的应用程序中使用示例代码。

有人可以解释一下:

  1. 为什么在扭曲的应用程序中不调用reactor.run()(或者如果这是一个错误的结论)
  2. 我如何在扭曲的应用程序中使用延迟对象而不调用reactor。 run()
  3. 以及编写扭曲脚本与应用程序的一般差异。

I feel like I am not understanding some things in writing Twisted applications (.tac files). Using deferred objects in .py scripts is easy by just calling reactor.run() at the end, but I have not seen reactor.run() used in any twisted application sample code.

Can someone explain:

  1. why reactor.run() is not called in twisted applications (or if this is an erroneous conclusion)
  2. how I can use deferred objects inside a twisted application perhaps without calling reactor.run()
  3. and general differences in writing twisted scripts vs applications.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无力看清 2024-12-19 05:23:46

1. 为什么示例.tac文件中没有调用reactor.run()

.tac 文件旨在由“twistd”命令行工具加载,该工具为您运行反应器。

运行反应器只需执行一次,无论是作为程序要点的任何代码。大多数 Twisted 代码实际上是某种插件,旨在在更大的系统环境中运行。

.tac 文件的特殊情况下,它们永远不会作为独立的 Python 程序运行:它们的工作是生成一个 Application 对象(带有附加的一堆Service 对象),它们在反应器运行时启动。重要的是,tac 文件本身不能单独做太多工作,因为(例如)相关的 Service 实现可能需要将需要运行特权的代码与需要运行的代码分开。无特权,这是一个严格的过程;如果工作是在 .tac 本身中执行的,则可能会以错误的用户身份随意执行。

2. 如何在 Twisted 应用程序中使用 Deferred,而不调用reactor.run()?

Deferred 只是一种管理回调链的机制。您不需要调用reactor.run(),甚至根本不需要反应器来使用它们。例如:

>>> from twisted.internet.defer import Deferred
>>> d = Deferred()
>>> def hello(result):
...     print "'d' was fired:", result
...     return result + 3
... 
>>> d.addCallback(hello)
<Deferred at ...>
>>> print d
<Deferred at ...>
>>> d.callback(7)
'd' was fired: 7
>>> print d
<Deferred at ... current result: 10>

也就是说,许多返回 Deferred 的 API 需要反应器做一些工作,以便最终调用 .callback() 。例如,如果你这样做……

>>> from twisted.internet.task import deferLater
>>> from twisted.internet import reactor
>>> deferLater(reactor, 1.0, lambda: 20).addCallback(hello)
<Deferred at ...>
>>>

你将永远坐在那里等待它点火,除非有人运行反应堆。在此之前,不会打印任何内容。

但是,如果反应器已经在运行 - 例如,如果您在 python -m twins.conch.stdio 而不是 python 中运行此交互式示例,您会看到Deferred 一秒钟后被回调,因为交互式提示已经在运行反应器。

3. Twisted 脚本与应用程序之间有什么区别?

这些并不是真正正式分开的术语。任何 Python 脚本都可以从 Twisted 导入代码并以任何想要的方式使用它,因此很难说任何特定属性都适用于“脚本”,除非它们是计算机程序:-)。

如果 Twisted Application 您指的是 .tac 文件或插件,则不同之处在于这种代码被分离到构建服务的部分(中顶层的代码) >tac 文件或插件)和实际执行工作的部分(privilegedStartService/startService/stopService 服务的实现表示顶层代码设置)。此外,在此上下文中运行的代码(即由 twistd 驱动)不需要运行反应器本身,因为反应器将由 twistd 本身设置和运行。因此,此类代码还必须小心避免导入 twisted.internet.reactor,因为 twistd 提供了使用不同反应器的能力(selectpollepollkqueue 等)并在 twistd 之前自行导入反应器有机会设置它会打破这个 特征。

1. Why is reactor.run() not called in example .tac files?

.tac files are meant to be loaded by the "twistd" command-line tool, which runs the reactor for you.

Running the reactor is something that's done once, by whatever bit of code is serving as the main-point for your program. Most Twisted code is effectively a plug-in of some kind, meant to operate in the context of a larger system.

In the particular case of .tac files, they are never meant to be run as stand-alone Python programs: their job is to produce an Application object (with an attached bunch of Service objects) that get started up when the reactor runs. It's important that the tac file itself not do much work on its own, because (for example) the Service implementations in question may need to separate code which needs to run privileged and unprivileged, which is an exacting process; if work is performed in the .tac itself, it may be haphazardly executed as the wrong user.

2. How I can use Deferreds inside a Twisted application, without calling reactor.run()?

Deferred is simply a mechanism for managing chains of callbacks. You don't need to call reactor.run(), or indeed, even have a reactor at all, to use them. For example:

>>> from twisted.internet.defer import Deferred
>>> d = Deferred()
>>> def hello(result):
...     print "'d' was fired:", result
...     return result + 3
... 
>>> d.addCallback(hello)
<Deferred at ...>
>>> print d
<Deferred at ...>
>>> d.callback(7)
'd' was fired: 7
>>> print d
<Deferred at ... current result: 10>

That said, many APIs that return a Deferred need the reactor to do some work in order to eventually call .callback() on it. For example, if you do ...

>>> from twisted.internet.task import deferLater
>>> from twisted.internet import reactor
>>> deferLater(reactor, 1.0, lambda: 20).addCallback(hello)
<Deferred at ...>
>>>

... you'll be sitting around forever waiting for that to fire unless somebody runs the reactor. Nothing will print until that happens.

But, if the reactor is already running - for example, if you were running this interactive example in python -m twisted.conch.stdio rather than python, you would see that Deferred get called back a second later, because that interactive prompt is already running the reactor.

3. What are the differences between Twisted scripts vs. applications?

These aren't really formally separated terms. Any Python script can potentially import code from Twisted and use it any way it wants to, so it's hard to say that any particular property applies to "scripts" except that they are computer programs :-).

If by Twisted Application you mean a .tac file or a plugin, the difference is that this kind of code is separated out into the part the builds the service (the code at the top level in your tac file or plugin) and the part that actually does the work (privilegedStartService/startService/stopService implementations of the services that said top-level code sets up). Also, code that runs in this context (i.e. is driven by twistd) does not need to run the reactor itself, since one will be set up and run by twistd itself. Such code must also therefore be careful to avoid importing twisted.internet.reactor, because twistd provides the ability to use different reactors (select, poll, epoll, kqueue, etc) and importing the reactor yourself before twistd has a chance to set it up will break this feature.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文