简体   繁体   English

扭曲的插件错误

[英]Twisted plugin error

A have created a dead simple twisted application that starts a TCP protocol and echo out what you type in STDIN. A 创建了一个简单的扭曲应用程序,它启动 TCP 协议并回显您在 STDIN 中键入的内容。

I am now trying to create a twistd plugin to be able to run my application this way: echo start or either twistd -n echo我现在正在尝试创建一个twistd插件,以便能够以这种方式运行我的应用程序: echo starttwistd -n echo

When running twistd -n echo everything works as expected, when using the echo start command I get the error: /home/vagrant/.env/bld/bin/echo: Unknown command: echo当运行twistd -n echo一切正常,当使用echo start命令时,我收到错误: /home/vagrant/.env/bld/bin/echo: Unknown command: echo

Here is my code:这是我的代码:

echo/plugins.py回声/插件.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from twisted.application import internet
from twisted.internet import endpoints
from twisted.internet.protocol import Factory
from twisted.python import usage

from echo.protocol import EchoProtocol


class Options(usage.Options):
    optParameters = [['port', 'p', 1234, 'Service port.']]


def makeService(options):
    from twisted.internet import reactor

    f = Factory()
    f.protocol = EchoProtocol

    ep = endpoints.TCP4ServerEndpoint(reactor, int(options['port']))
    return internet.StreamServerEndpointService(ep, f)

echo/protocol.py回声/协议.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from twisted.internet.protocol import Protocol


class EchoProtocol(Protocol):
    def dataReceived(self, data):
        self.transport.write('You entered: {data}'.format(data=data))

echo/tap.py回声/点击.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys

from twisted.python import usage
from twisted.scripts import twistd


class Start(twistd.ServerOptions):
    def parseOptions(self, args):
        sys.argv[1:] = self.getArguments(args)
        print('Starting echo service...')
        twistd.run()

    def getArguments(self, args):
        args.extend(['--pidfile', self.parent.pid])
        args.extend(['_bld_echo'])
        return args


class Options(usage.Options):
    pid = '/tmp/echo.pid'
    subCommands = [['start', None, Start, 'Launch echo service.']]


def main(argv=None):
    o = Options()
    try:
        o.parseOptions(argv)
    except usage.UsageError, e:
        raise SystemExit(str(e))

twisted/plugins/echo_plugin.py扭曲/插件/echo_plugin.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from twisted.application.service import ServiceMaker

Finger = ServiceMaker(
    'EchoServiceMaker',  # name
    'echo.plugins',  # module
    'Description blah-blah.',  # description
    '_plgn_echo')  # tapname

setup.py设置文件

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from setuptools import find_packages
from setuptools import setup

setup(
    name='Echo',
    version='0.0.1',
    packages=find_packages(),
    entry_points={
        'console_scripts': [
            '_ep_echo=echo.tap:main',
        ],
    },
    install_requires=[
        'Twisted==16.0.0',
    ],
    include_package_data=True,
    zip_safe=False,)

Here my virtualenv setup:这是我的 virtualenv 设置:

(bld)vagrant@/code/echo $ pip list
Echo (0.0.1)
pip (1.4.1)
setuptools (20.3.1)
Twisted (16.0.0)
wsgiref (0.1.2)
zope.interface (4.1.3)

I have prefixed my commands with _ep_ and _bld_ because I was not sure which one were called when invoking the program through twistd or by directly calling the entry_point, but I have tried any possible combination without success...我在命令前加上了_ep__bld_前缀,因为我不确定在通过扭曲或直接调用 entry_point 调用程序时调用了哪一个,但是我尝试了任何可能的组合都没有成功......

When I run _ep_echo start I get:当我运行_ep_echo start我得到:

[twistd -help output...]

twistd reads a twisted.application.service.Application out of a file and runs
it.
Commands:
    conch            A Conch SSH service.
    dns              A domain name server.
    ftp              An FTP server.
    inetd            An inetd(8) replacement.
    mail             An email service
    manhole          An interactive remote debugger service accessible via
                     telnet and ssh and providing syntax coloring and basic line
                     editing functionality.
    manhole-old      An interactive remote debugger service.
    news             A news server.
    portforward      A simple port-forwarder.
    procmon          A process watchdog / supervisor
    socks            A SOCKSv4 proxy service.
    telnet           A simple, telnet-based remote debugging service.
    web              A general-purpose web server which can serve from a
                     filesystem or application resource.
    words            A modern words server
    xmpp-router      An XMPP Router server

/home/vagrant/.env/bld/bin/_ep_echo: Unknown command: _bld_echo

The same goes if I replace _bld_echo with _ep_echo .如果我用_bld_echo替换_bld_echo _ep_echo

One thing is weird when looking at the output: the twistd does not have the echo subcommand registered.查看输出时有一件事很奇怪:twisdd 没有注册echo子命令。

If I run twistd --help I get:如果我运行twistd --help我得到:

twistd reads a twisted.application.service.Application out of a file and runs
it.
Commands:
    _plgn_echo       Description blah-blah.
    conch            A Conch SSH service.
    dns              A domain name server.
    ftp              An FTP server.
    inetd            An inetd(8) replacement.
    mail             An email service
    manhole          An interactive remote debugger service accessible via
                     telnet and ssh and providing syntax coloring and basic line
                     editing functionality.
    manhole-old      An interactive remote debugger service.
    news             A news server.
    portforward      A simple port-forwarder.
    procmon          A process watchdog / supervisor
    socks            A SOCKSv4 proxy service.
    telnet           A simple, telnet-based remote debugging service.
    web              A general-purpose web server which can serve from a
                     filesystem or application resource.
    words            A modern words server
    xmpp-router      An XMPP Router server

And there you can see the echo command registered.在那里您可以看到已注册的echo命令。

This is driving me crazy, any ideas about what's the problem here ??这让我发疯了,关于这里有什么问题的任何想法?

Notice that I run python setup.py install and not python setup.py develop , the latter command works but I do not want to run that in production请注意,我运行python setup.py install而不是python setup.py develop ,后一个命令有效,但我不想在生产中运行它


EDIT编辑

Ok after searching why the axiomatic start worked and not my echo start I found out the reason by removing all unneeded code from the install and here what I have found (I do not claim this is the solution, I would love to hear @glyph answer on this)好的,在搜索了为什么axiomatic start工作而不是我的echo start axiomatic start工作之后,我通过从安装中删除所有不需要的代码来找出原因,在这里我发现了什么(我不声称这是解决方案,我很想听到@glyph 的回答在这个)

The major difference between Axiom and Echo is this line in setup.py : AxiomEcho之间的主要区别在于setup.py这一行:

packages=find_packages() + ['twisted.plugins']

I did not have the + ['twisted.plugins'] addition to the packages line and now it works, but there is still this error happening:我没有将+ ['twisted.plugins']添加到packages line ,现在它可以工作了,但是仍然发生此错误:

Unexpected error while writing cache file
Traceback (most recent call last):
  File "/home/vagrant/.env/bld/lib/python2.7/site-packages/Twisted-16.0.0-py2.7-linux-x86_64.egg/twisted/application/app.py", line 579, in parseOptions
    usage.Options.parseOptions(self, options)
  File "/home/vagrant/.env/bld/lib/python2.7/site-packages/Twisted-16.0.0-py2.7-linux-x86_64.egg/twisted/python/usage.py", line 262, in parseOptions
    for (cmd, short, parser, doc) in self.subCommands:
  File "/home/vagrant/.env/bld/lib/python2.7/site-packages/Twisted-16.0.0-py2.7-linux-x86_64.egg/twisted/application/app.py", line 596, in subCommands
    for plug in sorted(plugins, key=attrgetter('tapname')):
  File "/home/vagrant/.env/bld/lib/python2.7/site-packages/Twisted-16.0.0-py2.7-linux-x86_64.egg/twisted/plugin.py", line 213, in getPlugins
    allDropins = getCache(package)
--- <exception caught here> ---
  File "/home/vagrant/.env/bld/lib/python2.7/site-packages/Twisted-16.0.0-py2.7-linux-x86_64.egg/twisted/plugin.py", line 185, in getCache
    dropinPath.setContent(pickle.dumps(dropinDotCache))
exceptions.AttributeError: 'ZipPath' object has no attribute 'setContent'

The plugin works but I would really love to know why my original way of installing it did not work...该插件有效,但我真的很想知道为什么我原来的安装方式不起作用......

Thank you for an extremely thorough explanation of your problem;感谢您对您的问题的极其详尽的解释; I was able to reproduce it exactly with only one minor tweak (creating a __init__.py inside echo/ to make it a proper package).我只需要一个小的调整就可以完全重现它(在echo/创建一个__init__.py以使其成为一个合适的包)。

First, here's the fix:首先,这里是修复:

diff --git a/echo/tap.py b/echo/tap.py
index d23571f..8e1ea84 100644
--- a/echo/tap.py
+++ b/echo/tap.py
@@ -15,7 +15,7 @@ class Start(twistd.ServerOptions):

     def getArguments(self, args):
         args.extend(['--pidfile', self.parent.pid])
-        args.extend(['_bld_echo'])
+        args.extend(['_plgn_echo'])
         return args

The reason that this works is that what you are doing when you are writing a command like this is you are wrapping the execution of the Twisted plugin , which means the thing that goes on your synthetic command line constructed by args.extend is the tapname of the Twisted plugin , the same thing that would go on the twistd command line.之所以说这个作品是什么,当你写这样的命令,你正在做的是你的包裹扭曲的插件,这意味着推移构建了您的合成命令行上的东西的执行args.extendtapname的Twisted 插件,与twistd命令行上的内容相同。

Hopefully it's clear why this is _plgn_echo .希望很清楚为什么这是_plgn_echo

I also have to commend you on adding these prefixes to clearly try to clearly understand which name, particularly, is being referred to in each area of the code.我也有赞扬你添加这些前缀,以清晰的态度清楚地了解哪些名字,特别是被在代码的每个区域提及。 Assuming that this answer makes sense to you, you will have a far better understanding of the code here than you would have if you had just stuck echo everywhere, even if it had happened to work at first :-).假设这个答案对您有意义,那么您对这里的代码的理解将比将echo卡在任何地方的情况要好得多,即使它一开始碰巧起作用:-)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM