Ticket #1490: tap.diff

File tap.diff, 6.3 KB (added by exarkun, 7 years ago)
  • doc/core/howto/tap.xhtml

     
    7373<h2>Using the run plugin</h2> 
    7474 
    7575<p> 
    76    The most simple way to run your service is using the <code class="shell">twistd 
    77    run</code> plugin. It allows your application to put the service wherever 
    78    you want, and it doesn't have to be a plugin. Thus, the interface to provide 
    79    is simple: it just needs an <code>options</code> attribute and a 
    80    <code>makeService</code>method.  Let's imagine a directory structure: 
     76   The simplest way to run your service is using the <code class="shell">twistd 
     77   run</code> command.  It allows you to use <code class="shell">twistd</code> to 
     78   start a service with a minimum of coding overhead.  The interface to provide 
     79   to use this is simple: just provide <code>options</code> and <code>makeService 
     80   </code>.  Imagine the following directory structure: 
    8181</p> 
    8282 
    8383<ul> 
     
    9292</ul> 
    9393 
    9494<p> 
    95     Fill <strong>service.py</strong> with the following code: 
     95    And imagine <strong>service.py</strong> contains the following code: 
    9696</p> 
    9797 
    9898<pre class="python"> 
     
    105105from myproject import MyFactory 
    106106 
    107107 
    108 class Options(usage.Options): 
     108class MyServiceOptions(usage.Options): 
    109109    optParameters = [["port", "p", 1235, "The port number to listen on."]] 
    110110    longdesc = "Run this! It'll make your dog happy." 
    111111 
    112112 
    113113class MyServiceMaker(object): 
    114114    implements(ISimpleServiceMaker) 
    115     options = Options 
    116115 
     116    options = MyServiceOptions 
     117 
    117118    def makeService(self, options): 
    118119        """ 
    119120        Construct a TCPServer from a factory defined in myproject. 
     
    125126</pre> 
    126127 
    127128<p> 
    128     The <code>Options</code> class defines the options your service needs.  The 
    129     <code>longdesc</code> attribute will be printed when you'll call <code 
    130     class="shell">--help</code> on you service. The <code>MyServiceMaker</code> 
    131     implements the <code>ISimpleServiceMaker</code> interface, which needs an 
    132     <code>options</code> attribute and a <code>makeService</code> method. This 
    133     method is called with an <code>options</code> argument, instance of the 
    134     <code>option</code> attribute filled with the data passed at command line. 
    135     It returns a service you want to run, here a 
    136     <code>internet.TCPServer</code>. Note that you need to create an instance 
    137     of <code>MyServiceMaker</code>: <code class="shell">twistd shell</code> 
    138     takes an object that <strong>provides</strong> 
    139     <code>ISimpleServiceMaker</code>, not just implements it. 
     129    <code class="python">MyServiceMaker</code> implements <code class="API" 
     130    base="twisted.application.service">ISimpleServiceMaker</code>, providing 
     131    two important attributes.  First, <code class="python">options</code> is a 
     132    callable which returns a new option parsing object.  This object will 
     133    have <code class="python">parseOptions</code> called on it with a list of 
     134    arguments from the command line.  Afterwards, the object will be passed as 
     135    the only argument to <code class="python">MyServiceMaker.makeService 
     136    </code>.  <code class="python">makeService</code> is to return the <code 
     137    class="API" base="twisted.application.service">IService</code> 
     138    implementation which will be run by <code class="shell">twistd</code>, 
     139    in this case an <code class="API" base="twisted.application"> 
     140    internet.TCPServer</code>.  Note that you need to create an instance of 
     141    <code class="python">MyServiceMaker</code> because <code class="shell"> 
     142    twistd run</code> accepts the name of an object that <strong>provides 
     143    </strong> <code class="API" base="twisted.application.service"> 
     144    ISimpleServiceMaker</code>, not the name of an object that <strong> 
     145    implements</strong> it. 
    140146</p> 
    141147 
    142148<p> 
    143149    To run this service, you call the run plugin with twistd, passing the fully 
    144     qualified named of your object providing <code>ISimpleServiceMaker</code>. 
     150    qualified named of your object providing <code class="API" base="twisted.application.service"> 
     151    ISimpleServiceMaker</code>. 
    145152</p> 
    146153 
    147154<pre class="shell"> 
     
    149156</pre> 
    150157 
    151158<p> 
    152     If you want to be even straightforward, it's important to know that a 
    153     module can provide the <code class="python">ISimpleServiceMaker</code> 
    154     interface. So if you put the following code instead in service.py: 
     159    It's also possible for a module to provide <code class="API" 
     160    base="twisted.application.service">ISimpleServiceMaker</code>.  This 
     161    is useful if the implementation is stateless or multiple instances 
     162    are not required.  For example, the above service.py could be rewritten 
     163    like this: 
    155164</p> 
    156165 
    157166<pre class="python"> 
     167from zope.interface import moduleProvides 
     168 
    158169from twisted.python import usage 
    159 from twisted.application import internet 
    160  
     170from twisted.application import service, internet 
    161171from myproject import MyFactory 
    162172 
    163173 
    164 class Options(usage.Options): 
     174class options(usage.Options): 
    165175    optParameters = [["port", "p", 1235, "The port number to listen on."]] 
    166176    longdesc = "Run this! It'll make your dog happy." 
    167177 
     
    171181    Construct a TCPServer from a factory defined in myproject. 
    172182    """ 
    173183    return internet.TCPServer(int(options["port"]), MyFactory()) 
     184 
     185moduleProvides(service.ISimpleServiceMaker) 
    174186</pre> 
    175187 
    176188<p> 
     
    186198<p> 
    187199    The other way to run a server is by creating a <code 
    188200    class="shell">twistd</code> plugin. The main advantage of this method 
    189     towards the <code>run</code> plugin is automatic discovery: whereas you 
     201    over the <code>run</code> plugin is automatic discovery: whereas you 
    190202    have to know the full name of your service to use the <code>run</code> 
    191     plugin, <code class="shell">twistd</code> will list you every plugin it can 
    192     found. It also supports a description that will be printed when you call 
    193     <code class="shell">twistd --help</code> .The following directory structure 
    194     is assumed of your project:</p> 
     203    plugin, <code class="shell">twistd</code> can present a list of every 
     204    plugin available.  Plugins also add support for descriptions which will 
     205    be included in the list presented by <code class="shell">twistd --help 
     206    </code> .The following directory structure is assumed of your project: 
     207</p> 
     208 
    195209<ul> 
    196210  <li><strong>MyProject</strong> - Top level directory 
    197211    <ul>