Twisted 中的新传输和读取器类型

发布于 2024-08-13 01:13:22 字数 452 浏览 9 评论 0原文

我正在尝试向 Twisted 添加新的传输,它将从流中读取数据 - 要么以 tail -f 方式读取文件,要么从管道读取数据,但我在 Twisted 架构方面遇到了一些问题。

我已经准备好传输本身(实现ITransport) - 它处理所有文件打开。我已经准备好流函数/延迟函数。现在我该如何将它们组合在一起?我想将新数据报告回某些协议的 dataReceived()

我当然可以创建一个新对象,该对象将使用适当的回调设置 I/O 监视器,在反应器关闭时注册回调(以关闭文件/协议)并手动启动所有内容 - 但这是“正确的方式” ?我可以使用更好的抽象吗?我见过reactor.connectWith(),但它并没有真正提供太多的抽象...

另外 - 我应该如何将数据从阅读器传递到协议? ITransport 没有为它定义任何接口,尽管它看起来完全是传输的责任。

I'm trying to add a new transport to Twisted, which will read data from a stream - either a file in a tail -f way, or from a pipe, but I have some problems with Twisted architecture.

I've got the transport itself (implements ITransport) ready - it handles all file opening. I've got streaming functions/deferreds ready. How do I put it together now? I'd like to report the new data back to some protocol's dataReceived().

I could of course create a new object that will set up the I/O monitors with proper callbacks, register a callback on reactor shutting down (to close the files / protocols) and start everything up manually - but is that "the right way"? Is there any nicer abstraction I could use? I've seen reactor.connectWith(), but it doesn't really provide much of an abstraction...

Also - how am I supposed to pass the data from my reader to the protocol? ITransport doesn't define any interface for it, even though it seems like exactly the transport's responsibility.

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

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

发布评论

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

评论(1

总攻大人 2024-08-20 01:13:22

听起来您已经大致了解了如何做到这一点。您可能对twisted.internet.fdesc.readFromFD感兴趣,但它只有几行长,并且没有做任何特别复杂的事情(不过,有几行您不需要维护)。除此之外 - 是的,在这种情况下您必须进行 I/O 监视,因为 select/poll/epoll 不支持常规文件描述符(它们总是报告为就绪,而不是您想要的)。

在 Twisted 中支持 inotify 方面已经做了一些工作 (http://twistedmatrix.com/trac/ticket/972< /a>)但这还没有完成,所以现在它不会直接对你有用(除非你想帮助完成它然后使用它)。假设您只使用基于时间的轮询,反应器中的大部分内容不会对您有太大帮助,因为该代码专注于使用系统提供的就绪 API(即 select/poll/epoll)来触发事件。

不过,对于管道情况,您应该能够使用 IReactorFDSet 的方法并从中受益 - addReader 等。

基于时间的轮询传输仍可能受益于实现 ITransport - 尽管我不确定您将如何为 tail -f 实现 write类似的运输。您肯定会受益于让您的传输通过 IProtocol 接口传送数据,因为这简化了代码重用。 IProtocol.dataReceived 正是您想要从读取器传递数据的方式(我认为这与您的传输相同,不是吗? )。它没有在 ITransport 上定义,因为它是您在非传输的其他对象上调用的方法。

reactor.connectWith 可能不会给你买任何东西。正如你所说,这并不是一个抽象的概念。我想说这更像是一个错误。 :)

不要太担心无法直接向反应器添加方法。接受反应器作为参数的自由函数也同样易于使用。

对于关闭回调,addReader 实际上应该可以帮助您完成大部分工作。关闭时反应堆中的任何读取器都会调用 connectionLostIFileDescriptor 的一部分)。您应该实现它来清理文件和协议。

It sounds like you've mostly figured out how to do this. You might be interested in twisted.internet.fdesc.readFromFD, but it's only a few lines long and it's not doing anything particularly complicated (it's a few lines you don't have to maintain, though). Aside from that - yes, you have to do the I/O monitoring in this case, because regular file descriptors aren't supported by select/poll/epoll (they always get reported as ready, not what you want).

Some work has been done on supporting inotify in Twisted (http://twistedmatrix.com/trac/ticket/972) but this isn't complete yet, so it's not going to be directly useful to you now (unless you want to help finish it and then use it). Assuming you just use time-based polling, much of what's in the reactor isn't going to help you out much, since that code is focused on using a system-provided readiness API (ie, select/poll/epoll) to trigger events.

For the pipe case, though, you should be able to use and benefit from IReactorFDSet's methods - addReader et al.

Your time-based polling transport may still benefit from implementing ITransport - although I'm not sure how you would implement write for a tail -f-like transport. You will definitely benefit from having your transport deliver data via the IProtocol interface, since this simplifies code-reuse. IProtocol.dataReceived is exactly how you want to pass data from your reader (I think that's the same as your transport, isn't it?). This isn't defined on ITransport because it's a method you call on some other object which is not the transport.

reactor.connectWith probably isn't going to buy you anything. As you say, it's not much of an abstraction; I'd say it's more of a mistake. :)

Don't worry too much about not being able to add methods directly to the reactor. A free-function which accepts a reactor as a parameter is just as easy to use.

For the shutdown callback, addReader should actually get you most of the way there. Any reader in the reactor at shutdown time will have connectionLost called on it (part of IFileDescriptor). You should implement this to clean up the files and protocol.

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