<div dir="ltr">Background<div><br></div><div>Currently, "twistd" assumes one-run-one-plugin. It would be nice to load up multiple plug-ins in Twisted, for many reasons. These include: serving the same in-memory content via separate protocols, adding manhole to other plug-ins (so the end-deployer can add it to other things, as opposed to the original implementor, and a catch-all category of "auxiliary services".</div><div><br></div><div>Auxiliary services are those which are not useful in and of themselves, but add value to a service which does something else of use.</div><div><br></div><div>Examples of auxiliary services -- a logging service (that connects to some logging protocol on start-up), a metrics service (that sends statistics to a collector like statsd or riemann) or an error-sending service (to something like Sentry).</div><div><br></div><div>Proposal</div><div><br></div><div>tl;dr: four new tickets (codenamed SUBCOMMANDS, SERVICES, MANHOLE and PROVIDERS) and one old ticket (3538) </div><div><br></div><div>SUBCOMMANDS: Add '+' as a special character in t.p.usage.Options. This behavior will be off by default, and controlled by an attribute on the Options instance "allowMultipleSubcommands".</div><div><br></div><div>The attribute will only be checked when the first sub-command starts, to allow setting it based on global flags. When the option is on, '-+' will be passed as '+' to the Options instance, to allow sending plain '+' to sub-commands.</div><div><br></div><div>Glyph thinks there's a ticket for it. I couldn't find it in "search for tickets in 'core' whose description mentionds 'command'". Unless anyone can find it, I'll open a new ticket.</div><div><br></div><div>SERVICES (depends on SUBCOMMANDS): In twistd, set the flag aMS if '--allow-multiple-services' is given. Add to the application all services.</div><div><br></div><div>3538 (depends on SERVICES): If '--allow-multiple-services' is given, and '--python <.tac file>' is given, process subcommands as usual. </div><div><br></div><div>PROVIDERS: Add a function,</div><div>       "providersInHierarchy(IService, IInterface) -> List[IInterface]"</div><div>that returns all services in the hierarchy which provide the interface. This ticket does not depend on any other tickets.</div><div><br></div><div>MANHOLE (depends on PROVIDERS, SERVICES): Add a built-in twistd plugin named "manhole". The plugin will expose manhole as PB/telnet with a namespace that includes</div><div>  {'services': providersInHierarchy(manholeService, IService)}</div><div>This ticket technically could only depend on PROVIDERS, but to be useful, it also depends on SERVICES<br></div></div>