在 Twisted 应用程序中使用延迟对象
我觉得我在编写 Twisted 应用程序(.tac 文件)时不理解一些事情。在 .py 脚本中使用延迟对象很简单,只需在最后调用 reactor.run()
即可,但我还没有看到 reactor.run()
在任何扭曲的应用程序中使用示例代码。
有人可以解释一下:
- 为什么在扭曲的应用程序中不调用reactor.run()(或者如果这是一个错误的结论)
- 我如何在扭曲的应用程序中使用延迟对象而不调用reactor。 run()
- 以及编写扭曲脚本与应用程序的一般差异。
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:
- why
reactor.run()
is not called in twisted applications (or if this is an erroneous conclusion) - how I can use deferred objects inside a twisted application perhaps without calling
reactor.run()
- and general differences in writing twisted scripts vs applications.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
1. 为什么示例
.tac
文件中没有调用reactor.run()
?.tac
文件旨在由“twistd
”命令行工具加载,该工具为您运行反应器。运行反应器只需执行一次,无论是作为程序要点的任何代码。大多数 Twisted 代码实际上是某种插件,旨在在更大的系统环境中运行。
在
.tac
文件的特殊情况下,它们永远不会作为独立的 Python 程序运行:它们的工作是生成一个Application
对象(带有附加的一堆Service
对象),它们在反应器运行时启动。重要的是,tac
文件本身不能单独做太多工作,因为(例如)相关的Service
实现可能需要将需要运行特权的代码与需要运行的代码分开。无特权,这是一个严格的过程;如果工作是在.tac
本身中执行的,则可能会以错误的用户身份随意执行。2. 如何在 Twisted 应用程序中使用 Deferred,而不调用reactor.run()?
Deferred
只是一种管理回调链的机制。您不需要调用reactor.run(),甚至根本不需要反应器来使用它们。例如:也就是说,许多返回
Deferred
的 API 需要反应器做一些工作,以便最终调用.callback()
。例如,如果你这样做……你将永远坐在那里等待它点火,除非有人运行反应堆。在此之前,不会打印任何内容。
但是,如果反应器已经在运行 - 例如,如果您在
python -m twins.conch.stdio
而不是python
中运行此交互式示例,您会看到Deferred
一秒钟后被回调,因为交互式提示已经在运行反应器。3. Twisted 脚本与应用程序之间有什么区别?
这些并不是真正正式分开的术语。任何 Python 脚本都可以从 Twisted 导入代码并以任何想要的方式使用它,因此很难说任何特定属性都适用于“脚本”,除非它们是计算机程序:-)。
如果 Twisted Application 您指的是
.tac
文件或插件,则不同之处在于这种代码被分离到构建服务的部分(中顶层的代码) >tac
文件或插件)和实际执行工作的部分(privilegedStartService
/startService
/stopService
服务的实现表示顶层代码设置)。此外,在此上下文中运行的代码(即由twistd
驱动)不需要运行反应器本身,因为反应器将由twistd
本身设置和运行。因此,此类代码还必须小心避免导入twisted.internet.reactor
,因为twistd
提供了使用不同反应器的能力(select
、poll
、epoll
、kqueue
等)并在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 anApplication
object (with an attached bunch ofService
objects) that get started up when the reactor runs. It's important that thetac
file itself not do much work on its own, because (for example) theService
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
Deferred
s inside a Twisted application, without callingreactor.run()
?Deferred
is simply a mechanism for managing chains of callbacks. You don't need to callreactor.run()
, or indeed, even have a reactor at all, to use them. For example: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 ...... 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 thanpython
, you would see thatDeferred
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 yourtac
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 bytwistd
) does not need to run the reactor itself, since one will be set up and run bytwistd
itself. Such code must also therefore be careful to avoid importingtwisted.internet.reactor
, becausetwistd
provides the ability to use different reactors (select
,poll
,epoll
,kqueue
, etc) and importing the reactor yourself beforetwistd
has a chance to set it up will break this feature.