~ubuntu-branches/debian/sid/pyro/sid

« back to all changes in this revision

Viewing changes to docs/4-usage.html

  • Committer: Bazaar Package Importer
  • Author(s): Carl Chenet, Carl Chenet, Jakub Wilk
  • Date: 2010-09-14 01:04:28 UTC
  • Revision ID: james.westby@ubuntu.com-20100914010428-02r7p1rzr7jvw94z
Tags: 1:3.9.1-2
[Carl Chenet]
* revert to 3.9.1-1 package because of the development status 
  of the 4.1 package is unsuitable for stable use
  DPMT svn #8557 revision (Closes: #589172) 
* added debian/source
* added debian/source/format
* package is now 3.0 (quilt) source format
* debian/control
  - Bump Standards-Version to 3.9.1

[Jakub Wilk]
* Add ‘XS-Python-Version: >= 2.5’ to prevent bytecompilation with python2.4
  (closes: #589053).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 
2
<html>
 
3
<!-- $Id: 4-usage.html,v 2.37.2.11 2009/04/02 00:40:54 irmen Exp $ -->
 
4
<head>
 
5
  <title>PYRO - Usage</title>
 
6
  <link rel="stylesheet" type="text/css" href="pyromanual_print.css" media="print">
 
7
  <link rel="stylesheet" type="text/css" href="pyromanual.css" media="screen">
 
8
</head>
 
9
 
 
10
<body>
 
11
  <div class="nav">
 
12
  <table width="100%">
 
13
    <tr>
 
14
      <td align="left"><a href="3-install.html">&lt;previous</a> | <a href="PyroManual.html">contents</a> | <a href=
 
15
      "5-nameserver.html">next&gt;</a></td>
 
16
 
 
17
      <td align="right">Pyro Manual</td>
 
18
    </tr>
 
19
  </table>
 
20
<hr></div>
 
21
 
 
22
  <h2>4. Pyro Usage</h2>
 
23
 
 
24
  <ul>
 
25
    <li><a href="#intro">Introduction</a></li>
 
26
 
 
27
    <li><a href="#scripts">Pyro script tools</a></li>
 
28
 
 
29
    <li><a href="#class">Writing the remote class</a></li>
 
30
 
 
31
    <li><a href="#server">Writing the server</a></li>
 
32
 
 
33
    <li><a href="#client">Writing the client</a></li>
 
34
 
 
35
    <li><a href="#runtime">Runtime setup</a></li>
 
36
 
 
37
    <li><a href="#runtimectrl">Runtime control and Logging</a></li>
 
38
 
 
39
    <li><a href="#sessions">Threads, sessions and objects</a></li>
 
40
 
 
41
    <li><a href="#notes">Last Notes</a></li>
 
42
  </ul>
 
43
 
 
44
  <h3><a name="intro" id="intro"></a>Introduction</h3>This chapter will show the Pyro development process: how to build
 
45
  a Pyro application. Let's repeat the <a href="1-intro.html">scenario</a> from the Introduction chapter here, but with
 
46
  some more detail:
 
47
 
 
48
  <ol>
 
49
    <li>You write a Python class that you want to access remotely. Do this as if it were a normal Python class (but see
 
50
    the <a href="7-features.html#rules">Features and Guidelines</a> chapter).</li>
 
51
 
 
52
    <li>Write a server process that performs the following tasks:
 
53
 
 
54
      <ul>
 
55
        <li>Create one or more instances of your remote object.</li>
 
56
 
 
57
        <li>Create a Pyro Daemon instance.</li>
 
58
 
 
59
        <li>Find the Name Server.</li>
 
60
 
 
61
        <li>Connect the remote object instances to the Daemon that will register them with the Name Server.</li>
 
62
 
 
63
        <li>Sit in a loop telling the Daemon to handle incoming requests.</li>
 
64
      </ul>
 
65
    </li>
 
66
 
 
67
    <li>Write a client program that does the following:
 
68
 
 
69
      <ul>
 
70
        <li>Find the Name Server.</li>
 
71
 
 
72
        <li>Query the NS for the requires objects. You'll get URIs back.</li>
 
73
 
 
74
        <li>Create a Dynamic Proxy for the URI.</li>
 
75
 
 
76
        <li>Call methods on the proxy object as if it were the real thing.</li>
 
77
      </ul>
 
78
    </li>
 
79
 
 
80
    <li>Make sure the Pyro Name Server is running.</li>
 
81
 
 
82
    <li>Start your server process. If it complains that the names it wants to register already exist, use the
 
83
    <code>pyro-nsc</code> tool to unregister them, or restart the NS.</li>
 
84
 
 
85
    <li>Run the client!</li>
 
86
  </ol>In the following sections each step is explained in more detail.
 
87
 
 
88
  <h3><a name="scripts" id="scripts"></a>Pyro script tools</h3>
 
89
  <p>Before using them let us first study the usage of the
 
90
  script tools. Pyro comes with two flavors, Un*x-style shellscripts and Windows/DOS command files. The Windows-style
 
91
command files have the '.cmd' extension. </p>
 
92
 
 
93
  <dl>
 
94
    <dt><code>pyro-genguid</code> &nbsp;&nbsp;(GUID generator)</dt>
 
95
 
 
96
    <dd>No arguments.</dd>
 
97
    <dd>This is a very simple GUID generator. It uses the internal Pyro GUID generator to print a new GUID.</dd>
 
98
    <br>
 
99
 
 
100
    <dt><code>pyro-ns, pyro-rns</code> &nbsp;&nbsp;(Name Server)</dt>
 
101
 
 
102
    <dd>These scripts are explained in the <a href="5-nameserver.html#cmds">Name Server chapter</a>.</dd>
 
103
    <br>
 
104
 
 
105
    <dt><code>pyro-es</code> &nbsp;&nbsp;(Event Server)</dt>
 
106
 
 
107
    <dd>This script is explained in the <a href="11-services.html#event">Event Server (Pyro Services) chapter</a>.</dd>
 
108
    <br>
 
109
 
 
110
    <dt><code>pyro-nsc</code> &nbsp;&nbsp;(Name Server Control tool)</dt>
 
111
 
 
112
    <dd>
 
113
      - Arguments: [-h host] [-p port] [-c bcaddr] [-i identification] command [args...]<br>
 
114
      - Controls the Pyro Name Server. '-h host' specifies the host where the Name Server should be contacted. '-p
 
115
      port' specifies a non-standard NS broadcast port to contact.
 
116
      '-c bcaddr' allows you to override the broadcast address.
 
117
       With '-i identification' you can supply the
 
118
      authentication passphrase that is used to connect to the Name Server. When it contains spaces, use quotes around
 
119
      it. 'command' is one of the following:
 
120
 
 
121
      <ul>
 
122
        <li>ping: just check if the NS is up and running.</li>
 
123
 
 
124
        <li>list: prints the contents of a name group. Argument is the group name to list.</li>
 
125
 
 
126
        <li>listall: prints a list of all registered names (expanded).</li>
 
127
 
 
128
        <li>register: register a new name. Arguments are the name and the URI.</li>
 
129
 
 
130
        <li>resolve: search for names. Arguments are the names to search for.</li>
 
131
 
 
132
        <li>remove: remove registered names from the NS. Arguments are the names to remove.</li>
 
133
 
 
134
        <li>creategroup: create a name group. Argument is the group to create.</li>
 
135
 
 
136
        <li>deletegroup: delete a name group and all contents. Argument is the group to delete.</li>
 
137
 
 
138
        <li>showmeta: Shows system and user meta info. Argument is the group or object to show meta info from.</li>
 
139
 
 
140
        <li>setmeta: Set user meta info. Arguments are the object name and the meta data string.</li>
 
141
 
 
142
        <li>shutdown: send the NS a shutdown request, so that a clean shutdown is performed. No arguments.</li>
 
143
      </ul><br>
 
144
    </dd>
 
145
 
 
146
    <dt><code>pyro-xnsc</code> &nbsp;&nbsp;(Graphical NS control tool)</dt>
 
147
 
 
148
    <dd>- No arguments<br>
 
149
    - This is a graphical version of the <code>nsc</code> command-line tool. Currently it needs Tk for the GUI, so you
 
150
    have to have a Tk-enabled Python on your system. The GUI is simple and
 
151
    should explain itself. You can enter the hostname in the textbox at the top and press &lt;enter&gt; to contact the
 
152
    NS at that host, or just press the 'Auto Discover' button at the top right. If the NS has been found, the rest of
 
153
    the buttons are enabled. If your Name Server requires an authorization passphrase, you must enter that first in the
 
154
    ID entry box. After that, you can connect to the NS. Once connected, the passphrase is erased in the display for
 
155
    security reasons. You have to type it again if you need to reconnect.<br>
 
156
    <br></dd>
 
157
    
 
158
    <dt><code>pyro-wxnsc</code> &nbsp;&nbsp;(Alternative Graphical NS control tool)</dt>
 
159
    <dd>- No arguments<br>
 
160
        - This is similar to the <code>xnsc</code> tool, but based on the WxPython GUI toolkit.
 
161
        <br>
 
162
    <br></dd>
 
163
 
 
164
    <dt><code>pyro-nssvc, pyro-essvc</code> &nbsp;&nbsp;(Windows-only Name Server and Event Server 'NT-service' control
 
165
    scripts)</dt>
 
166
 
 
167
    <dd>These scripts are explained in the <a href="5-nameserver.html#cmds">Name Server chapter</a> and the <a href=
 
168
    "6-eventserver.html#starting">Event Server chapter</a>.<br>
 
169
    <br></dd>
 
170
    
 
171
    <dt>Using <code>python -m</code> to start various tools</dt>
 
172
    <dd><code>python -m Pyro.naming</code> - start the name server</dd>
 
173
    <dd><code>python -m Pyro.EventService.Server</code> - start the event server</dd>
 
174
    <dd><code>python -m Pyro.nsc</code> - start the nsc tool. Also works with xnsc and wxnsc.</dd>
 
175
    <dd><code>python -m Pyro.configuration</code> - print a dump of Pyro's active configuration settings.</dd>
 
176
    
 
177
  </dl>
 
178
  
 
179
 
 
180
  <h3><a name="class" id="class"></a>Steps 1, 2 and 3: Writing the remote class</h3>Just create a Python module
 
181
  containing the classes you want to access remotely. There are some restrictions induced by Pyro:
 
182
 
 
183
  <ul>
 
184
    <li>The remote class can't have a remote <code>__init__</code> method. You should use a regular initialization
 
185
    method that you must call explicitly after binding to the remote object. The <code>__init__</code> method will only
 
186
    be called on the server side when the object is created.</li>
 
187
 
 
188
    <li>The remote class can't have direct attribute access unless you conciously choose to use a special proxy that
 
189
    supports attribute access. See below. You don't have to use <em>getters</em> and <em>setters</em> for each member
 
190
    variable any more.</li>
 
191
  </ul>If you keep those in mind, you should be safe. You can use all Python types and parameter lists and exceptions
 
192
  in your code. Pyro will deal with those nicely.
 
193
 
 
194
  <h3><a name="server" id="server"></a>Step 4: Writing the server</h3>
 
195
 
 
196
  <h4>Initialization</h4>You should initialize Pyro before using it in your server program. This is done by calling
 
197
  <pre>
 
198
   Pyro.core.initServer()
 
199
</pre>If you provide the optional argument <code>banner=1</code>, a short version message is
 
200
printed on the standard output. There is also a second optional argument <code>storageCheck</code>. By default it is 1
 
201
and Pyro will check the availability of the <code>PYRO_STORAGE</code> directory. If you set it to 0, Pyro will not
 
202
perform this check.
 
203
 
 
204
  <p>If the tracelevel is not zero, a startup message is written to the log. This message shows the active
 
205
  configuration options.</p>
 
206
 
 
207
  <p>It is not strictly required to call <code>Pyro.core.initServer()</code>, if you are creating a Pyro Daemon first.
 
208
  If you're doing that (see next paragraph-- it's a very common thing to do first), Pyro will initialise itself
 
209
  automatically. If you're not doing this, and are using other Pyro things first, it won't work because Pyro will then
 
210
  think you are a client, and call the wrong initialization function. So it's best to call
 
211
  <code>Pyro.core.initServer()</code> yourself. All Pyro code you see in this manual and the Pyro examples do this
 
212
  too.</p>
 
213
 
 
214
  <h4>Create a Pyro Daemon</h4>Your server program must create a Pyro Daemon object, which contains all logic necessary
 
215
  for accepting incoming requests and dispatching them to your objects by invoking their methods. You also have to tell
 
216
  the daemon which Name Server to use. When connecting objects to the daemon (<a href="#connecting">see below</a>) it
 
217
  uses this NS to register those objects for you. This is convenient as you don't have to do it yourself.
 
218
  <pre>
 
219
   daemon = Pyro.core.Daemon()
 
220
   daemon.useNameServer(ns)
 
221
</pre>You can provide several arguments when creating the Daemon:
 
222
 
 
223
  <table>
 
224
    <tr valign="top">
 
225
      <td><code>protocol</code></td>
 
226
 
 
227
      <td>the protocol to use (defaults to &quot;PYRO&quot;)</td>
 
228
    </tr>
 
229
 
 
230
    <tr valign="top">
 
231
      <td><code>host</code></td>
 
232
 
 
233
      <td>the hostname to bind the server on (defaults to '' - the default host). This may be necessary in the case
 
234
      where your system has more than one hostname/IP address, for instance, when it has multiple network adapters.
 
235
      With this argument you can select the specific hostname to bind the server on.</td>
 
236
    </tr>
 
237
 
 
238
    <tr valign="top">
 
239
      <td><code>port</code></td>
 
240
 
 
241
      <td>the socket number to use (defaults to the <code>PYRO_PORT</code> configuration item). Keep in mind that Pyro
 
242
      will pay attention to the <code>PYRO_PORT_RANGE</code> config item: if it cannot claim the socket on the given
 
243
      port, it will try the next higher port, and so on, as long as <code>PYRO_PORT_RANGE</code> allows.
 
244
        Setting this to 0 lets the operating system choose a random port for you (you need to set <code>norange</code>
 
245
        to 1 or True as well, if you want this).</td>
 
246
    </tr>
 
247
 
 
248
    <tr valign="top">
 
249
      <td><code>norange</code></td>
 
250
 
 
251
      <td>whether or not to try a range of sockets, i.e. don't pay attention to the <code>PYRO_PORT_RANGE</code>
 
252
      setting. (It's usually best leave this at the default value, 0)
 
253
      You need to set this to 1 or True if you want to use the random port selection (when setting <code>port=0</code>).</td>
 
254
    </tr>
 
255
 
 
256
    <tr valign="top">
 
257
      <td><code>publishhost</code></td>
 
258
 
 
259
      <td>the hostname that the daemon will use when publishing URIs, in case of a firewall/NAT setup. See the Features
 
260
      chapter. Defaults to the value given to the <code>host</code> parameter.</td>
 
261
    </tr>
 
262
  </table>
 
263
  <p>
 
264
  The second line tells the daemon to use a certain Name Server (<code>ns</code> is a proxy for the NS, see the next
 
265
  paragraph how to get this proxy). It's possible to omit this call but the Daemon will no longer be able to register
 
266
  your objects with the NS. If you didn't register them yourself, it is impossible to find them. The daemon will log a
 
267
warning if it doesn't know your NS.</p>
 
268
 
 
269
  <p>If your daemon is no longer referenced, it might be garbage collected (destroyed) by Python. Even if you connected
 
270
  Pyro objects to the daemon. So you have to make sure that you keep a reference to your daemon object at all time.
 
271
  This is recommended anyway because you can then cleanly terminate your Pyro application by calling
 
272
  <code>daemon.shutdown()</code> when it exits. Usually this is not a problem because your program creates a deamon and
 
273
  calls its <code>requestLoop</code>. But a situation might arise where you don't keep a reference to the daemon
 
274
  object, and then things break.</p>
 
275
 
 
276
  <h4>Find the Name Server</h4>You have to get a reference to the Pyro Name Server, which itself is a Pyro object. The
 
277
  easiest way is by using the NS Locator:
 
278
  <pre>
 
279
   locator = Pyro.naming.NameServerLocator()
 
280
   ns = locator.getNS()
 
281
</pre><code>ns</code> now contains a reference. There are more advanced ways to get a reference to the NS, please read
 
282
the chapter about the <a href="5-nameserver.html#locator">Name Server</a> to find out about them.
 
283
 
 
284
  <h4>Create object instances</h4>The objects you create in the server that have to be remotely accessible can't be
 
285
  created bare-bones. They have to be decorated with some logic to fool them into thinking it is a regular python
 
286
  program that invokes their methods. This logic is incorporated in a special generic <em>object base class</em> that
 
287
  is part of the Pyro core: <code>Pyro.core.ObjBase</code>. There are three ways to achieve this:
 
288
 
 
289
  <ul>
 
290
    <li>Derive a new class from both <code>Pyro.core.ObjBase</code> and your original class. The class body can be a
 
291
    simple '<code>pass</code>'. If you want to add a custom <code>__init__</code> method, make sure you call the <code>
 
292
      __init__</code> method of <code>Pyro.core.ObjBase</code> and of your own class, if it has one.
 
293
      <pre>
 
294
   class ObjectImpl(Pyro.core.ObjBase, test.MyClass):
 
295
      def __init__(self):
 
296
         Pyro.core.ObjBase.__init__(self)
 
297
         test.MyClass.__init__(self)
 
298
      ...
 
299
   obj = ObjectImpl()
 
300
    ... use obj ...
 
301
</pre>
 
302
    </li>
 
303
 
 
304
    <li>Delegate Pattern. In this pattern you create two objects, and you tell one of them to delegate all calls to the
 
305
    other. Instead of deriving from <code>Pyro.core.ObjBase</code> you just create that object and tell it to use your
 
306
    own object as a <em>delegate</em>, by calling the <code>delegateTo</code> method.
 
307
      <pre>
 
308
   obj = Pyro.core.ObjBase()
 
309
   myobj = MyClass()
 
310
   obj.delegateTo(myobj)
 
311
    ... use obj ...
 
312
</pre>
 
313
    </li>
 
314
 
 
315
    <li>Direct inheritance: subclass your class directly from <code>Pyro.core.ObjBase</code>. This is the least hassle
 
316
    but you have to change existing code if you want to make classes suitable for Pyro.
 
317
      <pre>
 
318
   class MyPyroObj(Pyro.core.ObjBase):
 
319
      def __init__(self):
 
320
         Pyro.core.ObjBase.__init__(self)
 
321
         ...obj init here...
 
322
       ...
 
323
   obj = MyPyroObj()
 
324
    ... use obj ...
 
325
</pre>
 
326
    </li>
 
327
  </ul>For advanced purposes, there are two other base classes that you can use instead of <code>ObjBase</code>:
 
328
 
 
329
  <dl>
 
330
    <dt><code>Pyro.core.SynchronizedObjBase</code></dt>
 
331
 
 
332
    <dd>Use this to make your Pyro object thread-safe; all (remote) method calls are automatically synchronized for
 
333
    this object.</dd>
 
334
 
 
335
    <dt><code>Pyro.core.CallbackObjBase</code></dt>
 
336
 
 
337
    <dd>Use this for special <em>callback</em> objects that need to report errors also on the client, not only on the
 
338
    server. For more information, please read about Callbacks in the <a href="7-features.html#callback">Features and
 
339
    Guidelines</a> chapter.</dd>
 
340
  </dl>
 
341
 
 
342
  <h4><a name="connecting" id="connecting"></a>Connect object instances</h4>Ok, we're going nicely up to this point. We
 
343
  have some objects that even already have gotten a unique ID (that's part of the logic <code>Pyro.core.ObjBase</code>
 
344
  gives us). But Pyro still knows nothing about them. We have to let Pyro know we've created some objects and how they
 
345
  are called. Only then can they be accessed by remote client programs. So let's connect our objects with the Pyro
 
346
  Daemon we've created before:
 
347
  <pre>
 
348
   daemon.connect(obj,'our_object')
 
349
</pre>
 
350
  That done, the daemon has registered our object with the NS too (if you told it where to find the NS,
 
351
  as we explained earlier: <code>daemon.useNameServer(ns)</code>). The NS will now have an entry in its
 
352
  table that connects the name &quot;our_object&quot; to our specific object.<br>
 
353
  Note 1: if you don't provide a name, your object is a so-called <em>transient</em> object. The daemon will not
 
354
  register it with the Name Server. This is useful when you create new Pyro objects on the server that are not
 
355
  full-blown objects but rather objects that are only accessible by the code that created them. Have a look at the
 
356
  factory and Bank2 examples if this is not clear.<br>
 
357
  Note 2: the <code>connect</code> method actually returns the URI that will identify this object. You can ignore this
 
358
  if you don't want to use it immediately without having to consult the name service.<br>
 
359
  Note 3: there is also a <code>connectPersistent</code> method that is used for a special purpose. Look
 
360
  under the &quot;Automatic Rebinding&quot; topic in the &quot;Features and guidelines&quot; chapter for more
 
361
  info.
 
362
 
 
363
  <p>In contrast to the simple (flat) name shown above (&quot;our_object&quot;), Pyro's Name Server supports
 
364
      a <a href=
 
365
  "5-nameserver.html#naming">hierarchical object naming scheme</a>.</p>
 
366
 
 
367
  <h4><a name="disconnecting" id="disconnecting"></a>Disconnecting object instances</h4>Usually you don't have to worry
 
368
  about cleaning up, the daemon will cleanly remove any registered objects from the Name Server if it exits. (Note that
 
369
  'persistently' connected objects are not removed automatically.) But sometimes it can be better to manually remove
 
370
  any objects that you don't need any longer. Use the following method to do that:
 
371
  <pre>
 
372
   daemon.disconnect(obj)
 
373
</pre>Just pass the Pyro object you want to remove from the Daemon (and the Name Server).
 
374
 
 
375
  <h4>The Daemon handleRequest loop</h4>We're near the end of our server coding effort. The only thing left is the code
 
376
  that sits in a loop and processes incoming requests. Fortunately most of that is handled by a single method in the
 
377
  daemon. For many applications calling <code>daemon.requestLoop()</code> is enough. For finer control, you can give a
 
378
  few arguments to the function:
 
379
  <pre>
 
380
requestLoop(condition, timeout, others, callback)
 
381
</pre>All arguments are optional. The default is that <code>requestLoop</code> enters an endless loop waiting and
 
382
handling Pyro requests. You can specify a <code>condition</code> callable object (for instance, a lambda function) that
 
383
is evaluated each cycle of the loop to see if the loop should continue (the condition must evaluate to 1). The
 
384
<code>timeout</code> can be used to adjust the timeout between loop cycles (default=3 seconds). The
 
385
<code>requestLoop</code> doesn't use the timeout (it only returns when the optional loop condition is no longer true),
 
386
the timeout is simply passed to the underlying <code>handleRequests</code> call. This is required on some platforms
 
387
(windows) to cleanly handle break signals like ^C. The <code>others</code> and <code>callbacks</code> can be used to
 
388
add your own socket or file objects to the request handling loop, and act on them if they trigger. For more details,
 
389
see the paragraph below.
 
390
 
 
391
  <p>For those that like to have more control over the request handling loop, there is also
 
392
  <code>handleRequests</code>. Usually your loop will look something like this:</p>
 
393
  <pre>
 
394
   while continueLoop:
 
395
      daemon.handleRequests(3.0)
 
396
      ... do something when a timeout occured ...
 
397
</pre>The timeout value in this example is three seconds. The call to <code>handleRequests</code> returns when the
 
398
timeout period has passed, or when a new proxy object got a connection to the daemon. You could use '<code>0</code>' for timeout, but
 
399
this means the call returns directly if no requests are pending. If you want infinite timeout, use '<code>None</code>'.
 
400
You can also provide additional objects the daemon should wait on (multiplexing), to avoid having to split your program
 
401
into multiple threads. You pass those objects, including a special callback function, as follows:
 
402
  <pre>
 
403
   daemon.handleRequests(timeout, [obj1,obj2,obj3], callback_func)
 
404
</pre>The second argument is a list of objects suitable for passing as <em>ins</em> list to the <code>select</code>
 
405
system call. The last argument is a callback function. This function will be called when one of the objects in your
 
406
list triggers. The function is called with one argument: the list of ready objects. For more information about this
 
407
multiplexing issue, see the manual page about the Un*x <code>select</code> system call.
 
408
 
 
409
  <h4>Including the Pyro Daemon in another (external) event loop</h4>Some applications already have their own event
 
410
  loop. If it is <code>select</code>-based, or can process additional sockets to wait on, you can also use your
 
411
  application's event loop instead of the Daemon's <code>requestLoop</code>. Do this by querying the Daemon for a list
 
412
  of active socket objects that it is currently listening on, and pass every socket in that list to your external event
 
413
  loop. The Daemon has a method <code>getServerSockets()</code> that returns this list of <code>socket</code> objects.
 
414
  This list changes so you have to call it every time you enter the 'foreign' event loop. When your code returns from
 
415
  the 'foreign' event loop, check if one of Pyro's sockets has an event, and if so, call the regular
 
416
  <code>handleRequests()</code>. Pyro will then process every event that's pending for it. An example:
 
417
  <pre>
 
418
while some_condition :
 
419
        socks=daemon.getServerSockets()
 
420
        ins,outs,exs=select.select(socks,[],[],2)   # 'foreign' event loop
 
421
        for s in socks:
 
422
                if s in ins:
 
423
                        daemon.handleRequests()
 
424
                        break    # no need to continue with the for loop
 
425
</pre>
 
426
  Have a look at the &quot;AllInOne&quot; example. It shows two approaches of starting various Pyro servers
 
427
  from within a single program and then using a custom event loop to wait for incoming requests. That
 
428
  code is easily adapted to integrate Pyro in a GUI toolkit's event loop, for instance.
 
429
 
 
430
  <h4>Stopping the server, cleaning up</h4>To signal the Daemon that it should stop its requestloop, you can call
 
431
  <code>daemon.shutdown()</code> or send the process a break signal (ctrl-C). This issues an asynchronous request to
 
432
  the Daemon to terminate the request loop once any processing that is currently going on, is finished (it can still
 
433
  take a while before the requestloop is actually stopped). Once the loop stops, and all references to the daemon
 
434
  object are gone, it is garbage collected and Python tries to run the finalizer code that nicely unregisters any
 
435
  connected objects (so their names are removed from the Name Server unless you're using persistent mode).
 
436
 
 
437
  <p>However this may not work in all cases, or perhaps you want to control it explicitly. If you want to explicitly
 
438
  tell the daemon to unregister its objects and shut down, you should use <code>daemon.shutdown(True)</code>. So your
 
439
  code might look like this:</p>
 
440
  <pre>
 
441
 &hellip;
 
442
daemon.connect( &hellip; )
 
443
try:
 
444
    daemon.requestLoop()
 
445
finally:
 
446
    daemon.shutdown(True)
 
447
    # at this moment, the objects have been unregistered
 
448
 &hellip;
 
449
</pre>
 
450
 
 
451
  <p>If you're not doing any more processing in your server after the requestloop, it is usually not necessary to add
 
452
  this explicit cleanup logic. However, if the server is aborted in a 'hard' way (terminated, crash) instead of a
 
453
  normal shutdown or ctrl-C signal, Python may not execute the finalizer code and your objects are still registered in
 
454
  the NS. There is not much you can do about this; even the explicit shutdown code above doesn't help (because it is
 
455
  not executed as well!). A solution is to change the registration of the objects: if you encounter errors because the
 
456
  name already exists in the NS, just unregister the old name and re-register.</p>
 
457
 
 
458
  <p><em>This concludes our server. Full listings can be found in the <a href="8-example.html">Example
 
459
  chapter</a>.</em></p>
 
460
 
 
461
  <h3><a name="client" id="client"></a>Step 5: Writing the client</h3>
 
462
 
 
463
  <h4>Initialization</h4>You should initialize Pyro before using it in your client program. This is done by calling
 
464
  <pre>
 
465
   Pyro.core.initClient()
 
466
</pre>If you provide the argument 'banner=1', a short version message is printed on the standard
 
467
output. In contrast to the server initialization (see above), this method does <em>not</em> check the availability of
 
468
the <code>PYRO_STORAGE</code> directory. This means that you can run Pyro clients on a read-only system, as long as
 
469
they don't have to write something (log!) to <code>PYRO_STORAGE</code>!
 
470
 
 
471
  <p>If the tracelevel is not zero, a startup message is written to the log. This message shows the active
 
472
  configuration options.</p>
 
473
 
 
474
  <p>It is not strictly required to call <code>Pyro.core.initClient()</code>. If you don't call it, Pyro will
 
475
  initialise itself automatically.</p>
 
476
 
 
477
  <h4>Find the Name Server</h4>This part is identical to the way this is done in the server. See above. Let's assume
 
478
  that the variable <code>ns</code> now contains the proxy for the NS.
 
479
 
 
480
  <h4>Find object URIs</h4>There are essentially three ways to find an object URI by name:
 
481
 
 
482
  <ul>
 
483
    <li>Query the NS. This is the best way to go. You ask the NS to give you the URI for the object with
 
484
        the right name (&quot;my_object&quot; in this example):
 
485
        <pre>
 
486
   uri = ns.resolve('my_object')
 
487
</pre>
 
488
    </li>
 
489
 
 
490
    <li>Read it from a special file that was written by the object. This is like what is done in the <a href=
 
491
    "#server">previous paragraph</a>, about finding the NameServer. Be sure to convert the string you read from the
 
492
    file to a real <code>PyroURI</code> object before you use it. Just pass it to the constructur of
 
493
    <code>PyroURI</code> and you'll be fine.</li>
 
494
 
 
495
    <li>Use the special <code>PYRONAME://</code> or <code>PYROLOC://</code> URI strings. The first is a shortcut to the
 
496
    Name Server, the second bypasses the Name Server completely. More info is in the <a href=
 
497
    "5-nameserver.html#pyroname">Name Server chapter</a>.</li>
 
498
  </ul>
 
499
 
 
500
  <h4>Create a proxy</h4>You now have a URI in your posession. But you need an object to call methods on. So you create
 
501
  a proxy object for the URI.
 
502
  <pre>
 
503
   obj = Pyro.core.getProxyForURI(uri)     # get a dynamic proxy
 
504
   obj = Pyro.core.getAttrProxyForURI(uri) # get a dyn proxy with attribute support
 
505
 
 
506
   # if you're sure that the URI is a real PyroURI object, you can do this:
 
507
   obj = uri.getProxy()                    # get a dynamic proxy directly from the URI  
 
508
   obj = uri.getAttrProxy()                # same, but with attribute support
 
509
</pre>If you're using attribute proxies, be aware of their <a href="2-concepts.html#proxy">properties and
 
510
limitations</a>.
 
511
 
 
512
  <h4>Remote method invocations</h4>And now what we've all been waiting for: calling remote methods. This is what's
 
513
  Pyro's all about: there is <em>no difference</em> in calling a remote method or calling a method on a regular (local)
 
514
  Python object. Just go on and write:
 
515
  <pre>
 
516
   obj.method(arg1, arg2)
 
517
   print obj.getName()
 
518
   a = obj.answerQuestion('What is the meaning of life?')
 
519
   # the following statements only work with a attribute-capable proxy:
 
520
   attrib = obj.attrib
 
521
   obj.sum = obj.sum+1
 
522
</pre>or whatever methods your objects provide. The only thing to keep in mind is that you need a <em>proxy</em> object
 
523
whose methods you call.
 
524
 
 
525
  <p>This concludes our client. Full listings can be found in the <a href="8-example.html">Example chapter</a>. For
 
526
  information on using Pyro's logging/tracing facility, see <a href="#runtimectrl">Runtime control and Logging</a>,
 
527
  below.</p>
 
528
 
 
529
  <h3><a name="runtime" id="runtime"></a>Steps 6, 7 and 8: Runtime setup</h3>This part is a no-brainer, really. There
 
530
  may be some extra configuration necessary when you're running Pyro behind a firewall, and want to access it from
 
531
  outside the firewall, or have machines with dynamic IP addresses. You can find more information about this in the
 
532
  <a href="7-features.html">Features and Guidelines</a> chapter. Otherwise it's simple:
 
533
 
 
534
  <h4>Starting the Name Server</h4>A Pyro system needs at least one running Name Server. So, if it's not already
 
535
  running, start one using the <code>ns</code> utility. See <a href="#scripts">Pyro script tools</a>. After starting it
 
536
  will print some information and then the Name Server sits in a loop waiting for requests:
 
537
  <pre>
 
538
irmen@atlantis:~ &gt; projects/Pyro/bin/ns
 
539
*** Pyro Name Server ***
 
540
Pyro Server Initialized. Using Pyro V2.4
 
541
Will accept shutdown requests.
 
542
URI written to: /home/irmen/Pyro_NS_URI
 
543
URI is: PYRO://10.0.0.150:9090/0a000096-08620ada-6697d564-62110a9f
 
544
Name Server started.  
 
545
</pre>The NS writes its URI to a file, as it says. This file can be read by other programs, and this is another -very
 
546
portable- way to discover the NS. Usually you'll want to use the default mechanism from the
 
547
<code>NameServerLocator</code> (automatic discovery using broadcasting). This is easier. But if your network doesn't
 
548
support broadcasting, or the NS can't be reached by a broadcast (because it sits on another subnet, for instance), you
 
549
<em>have</em> to use another method to reach the NS.
 
550
 
 
551
  <h4>Running the server</h4>Just start the python module as you do normally. Before starting, you may want to set
 
552
  certain environment variables to change some of Pyro's configuration items. After starting, your server will usually
 
553
  sit in a loop waiting for incoming requests (method calls, actually).
 
554
 
 
555
  <h4>Running the client</h4>Just start the python module as you do normally. Before starting, you may want to set
 
556
  certain environment variables to change some of Pyro's configuration items.
 
557
 
 
558
  <h3><a name="runtimectrl" id="runtimectrl"></a>Runtime control and Logging</h3>
 
559
 
 
560
  <h4>Controlling the Name Server</h4>You might want to control the NS while it's running. For instance, to inspect the
 
561
  current registered names or to remove an old name, or to register a new one by hand. You use the <code>pyro-nsc</code>
 
562
  command-line utility or the <code>pyro-xnsc</code> graphical tool for this purpose, see <a href="#scripts">Pyro script
 
563
  tools</a>.
 
564
 
 
565
  <h4>Controlling Pyro</h4>Pyro has many configuration items that can be changed also during runtime. You might want to
 
566
  set the tracelevel to 3 during a special function, for instance. See the <a href="3-install.html">Installation and
 
567
  Configuration</a> chapter for more information.
 
568
 
 
569
  <h4>Tracing (logging)</h4>Pyro has two distinct logs: the system log and the user log. The system log is used by Pyro
 
570
  itself. You can use it in your own code too, but generally it's better to use the user log.
 
571
 
 
572
  <ul>
 
573
    <li><strong>System Log</strong><br>
 
574
    The system log is implemented by the <code>Pyro.util.Log</code> object, which is an instance of
 
575
    <code>Pyro.util.SystemLogger</code>. System log tracelevel is configured using the <code>PYRO_TRACELEVEL</code>
 
576
    config item, the logfile location is configured using the <code>PYRO_LOGFILE</code> config item.</li>
 
577
 
 
578
    <li><strong>User log</strong><br>
 
579
    You should create your own user log object by creating a <code>Pyro.util.UserLogger</code> instance. User log
 
580
    tracelevel is configured using the <code>PYRO_USER_TRACELEVEL</code> config item, the user logfile location is
 
581
    configured using the <code>PYRO_USER_LOGFILE</code> config item.</li>
 
582
 
 
583
    <li>
 
584
      <strong>Using the Logger object: logging entries</strong><br>
 
585
      The logger class provides four methods:
 
586
 
 
587
      <ul>
 
588
        <li><code>msg(source, *args)</code> - log a simple message (note). <code>source</code> is a string that
 
589
        identifies the source of the log entry, after that, any argument may follow to be printed in the logfile.</li>
 
590
 
 
591
        <li><code>error(source, *args)</code> - log an error. <code>source</code> is a string that identifies the
 
592
        source of the log entry, after that, any argument may follow to be printed in the logfile.</li>
 
593
 
 
594
        <li><code>warn(source, *args)</code> - log a warning. <code>source</code> is a string that identifies the
 
595
        source of the log entry, after that, any argument may follow to be printed in the logfile.</li>
 
596
 
 
597
        <li><code>raw(string)</code> - log a string (unformatted). <code>string</code> is the string to write to the
 
598
        logfile. This logging is done unconditionally, the tracelevel setting has no influence here.</li>
 
599
      </ul>Logfile entries have the following format:<br>
 
600
      &quot;<code>2002-01-16 16:45:02 [5884:MainThread] ** ERR! ** NameServerLocator ** Name Server not
 
601
      responding</code>&quot;<br>
 
602
      (a date and timestamp, process ID:thread name, then &quot;NOTE&quot;, &quot;WARN&quot; or &quot;ERR!&quot;,
 
603
      indicating if this was a simple message, a warning or an error. After that, the source of the log
 
604
      entry - this can be any string but should be meaningful for the developer. After that, the actual
 
605
      log message. All elements are separated by two asterisks). Each log entry is one line in the logfile.
 
606
      Entries written by the <code>raw</code> method can have any format,
 
607
      including multiple lines.
 
608
    </li>
 
609
  </ul>
 
610
 
 
611
  <h3><a name="sessions" id="sessions"></a>Threads, sessions and objects</h3>
 
612
  <p>For more complex uses of Pyro, it is important to understand how Pyro uses threads and how the objects interact.
 
613
Below are, in condensed form, the rules Pyro follows. 
 
614
For detailed information about these subjects, please refer to the relevant chapters elsewhere in the manual.
 
615
</p>
 
616
<ul>
 
617
        <li>A Pyro server object is only created once. The same instance is reused over and over by the Daemon. It is never deleted, unless the Daemon itself shuts down or
 
618
                the object is explicitly disconnected from it.</li>
 
619
        <li>Nameless ('transient') objects created on the server are not automatically deleted, the follow the same rules. You can use Pyro's transient object timeout feature to get rid of them.</li>
 
620
        <li>Pyro server objects may be accessed from multiple threads at the same time. So they need to be reentrant (threadsafe).</li>
 
621
        <li>A thread is created for every distinct connection that is created to the Daemon.</li>
 
622
        <li>A connection is a link between a Pyro proxy object and a Pyro Daemon. A proxy object has exactly one connection to a Daemon,
 
623
                a Daemon can have lots of connected proxy objects.</li>
 
624
        <li>Every distinct proxy object has its own connection. That means that when you create a new proxy object,
 
625
        a new connection will be made to the Daemon, and a new thread to handle the method calls will be spawned.</li>
 
626
        <li>Multiple method calls can occur over a single connection, they are handled serially by the thread associated to the connection.
 
627
                If you share a proxy object among several threads in your client application, all method calls
 
628
                will be serialized. If you make a copy of the proxy object and use those in different threads in your client application,
 
629
                the method calls will not be serialized and the server object will process them concurrently.</li>
 
630
        <li>'oneway' calls can be an exception and can execute in their own short-lived thread.</li>
 
631
        <li>TLS can be used to store objects that must be unique to a <em>thread</em> or to a <em>client session</em>.
 
632
                For example, open files or database connection objects.</li>
 
633
        <li>You can use the <code>caller</code> property of the TLS object if required: that object
 
634
                 always equals the currently active client connection. Multithreaded or not.</li>
 
635
        <li>If you disable multithreading using the config item, there will be only a single thread that
 
636
                will be shared by all method calls from all proxies! There will only be one shared TLS as well!
 
637
                If your code needs to be able to deal with this possibility, you always have to use the <code>caller</code>
 
638
                property of the TLS in some way instead of just storing stuff on the TLS directly.</li>
 
639
        
 
640
</ul>
 
641
</p>
 
642
 
 
643
 
 
644
  <h3><a name="notes" id="notes"></a>Last Notes</h3>Please be sure to read the chapter on <a href=
 
645
  "3-install.html">Configuration</a>, the <a href="5-nameserver.html">Name Server</a> and the chapter about <a href=
 
646
  "7-features.html">Pyro's Features and Guidelines</a>.
 
647
 
 
648
  <p>These chapters contain invaluable information about the more detailed aspects and possibilities of Pyro.</p>
 
649
 
 
650
  <p>Also have a look at the extensions package <code>Pyro.ext</code>, it contains two modules that provide
 
651
      extremely easy remoting for your programs. Take a look at the &quot;quickstart&quot; and &quot;quickstart-noNS&quot;
 
652
      examples for more details.</p>
 
653
  <div class="nav">
 
654
  <hr>
 
655
  <table width="100%">
 
656
    <tr>
 
657
      <td align="left"><a href="3-install.html">&lt;previous</a> | <a href="PyroManual.html">contents</a> | <a href=
 
658
      "5-nameserver.html">next&gt;</a></td>
 
659
 
 
660
      <td align="right">Pyro Manual</td>
 
661
    </tr>
 
662
  </table></div>
 
663
</body>
 
664
</html>