Initial import to Tizen
[profile/ivi/python-twisted.git] / doc / core / howto / pb-intro.html
1 <?xml version="1.0" encoding="utf-8"?><!DOCTYPE html  PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
2   <head>
3 <title>Twisted Documentation: Introduction to Perspective Broker</title>
4 <link href="stylesheet.css" rel="stylesheet" type="text/css"/>
5   </head>
6
7   <body bgcolor="white">
8     <h1 class="title">Introduction to Perspective Broker</h1>
9     <div class="toc"><ol><li><a href="#auto0">Introduction</a></li><li><a href="#auto1">Object Roadmap</a></li><ul><li><a href="#auto2">Subclassing and Implementing</a></li></ul><li><a href="#auto3">Things you can Call Remotely</a></li><li><a href="#auto4">Things you can Copy Remotely</a></li></ol></div>
10     <div class="content">
11 <span/>
12
13 <h2>Introduction<a name="auto0"/></h2>
14
15 <p>Suppose you find yourself in control of both ends of the wire: you
16 have two programs that need to talk to each other, and you get to use any
17 protocol you want. If you can think of your problem in terms of objects that
18 need to make method calls on each other, then chances are good that you can
19 use Twisted's Perspective Broker protocol rather than trying to shoehorn
20 your needs into something like HTTP, or implementing yet another RPC
21 mechanism<a href="#footnote-1" title="Most of Twisted is like this. Hell, most of Unix is like this: if you think it would be useful, someone else has probably thought that way in the past, and acted on it, and you can take advantage of the tool they created to solve the same problem you're facing now."><super>1</super></a>.</p>
22
23 <p>The Perspective Broker system (abbreviated <q>PB</q>, spawning numerous
24 sandwich-related puns) is based upon a few central concepts:</p>
25
26 <ul>
27
28   <li><em>serialization</em>: taking fairly arbitrary objects and types,
29   turning them into a chunk of bytes, sending them over a wire, then
30   reconstituting them on the other end. By keeping careful track of object
31   ids, the serialized objects can contain references to other objects and
32   the remote copy will still be useful. </li>
33
34   <li><em>remote method calls</em>: doing something to a local object and
35   causing a method to get run on a distant one. The local object is called a
36   <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.RemoteReference.html" title="twisted.spread.pb.RemoteReference">RemoteReference</a></code>, and you
37   <q>do something</q> by running its <code>.callRemote</code> method.
38   </li>
39
40 </ul>
41
42 <p>This document will contain several examples that will (hopefully) appear
43 redundant and verbose once you've figured out what's going on. To begin
44 with, much of the code will just be labelled <q>magic</q>: don't worry about how
45 these parts work yet. It will be explained more fully later.</p>
46
47 <h2>Object Roadmap<a name="auto1"/></h2>
48
49 <p>To start with, here are the major classes, interfaces, and
50 functions involved in PB, with links to the file where they are
51 defined (all of which are under twisted/, of course). Don't worry
52 about understanding what they all do yet: it's easier to figure them
53 out through their interaction than explaining them one at a time.</p>
54
55 <ul>
56
57   <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.internet.protocol.Factory.html" title="twisted.internet.protocol.Factory">Factory</a></code>
58   : <code>internet/protocol.py</code></li>
59
60   <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.PBServerFactory.html" title="twisted.spread.pb.PBServerFactory">PBServerFactory</a></code>
61   : <code>spread/pb.py</code></li>
62
63   <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.Broker.html" title="twisted.spread.pb.Broker">Broker</a></code>
64   : <code>spread/pb.py</code></li>
65
66 </ul>
67
68 <p>Other classes that are involved at some point:</p>
69
70 <ul>
71
72   <li> <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.RemoteReference.html" title="twisted.spread.pb.RemoteReference">RemoteReference</a></code>
73   : <code>spread/pb.py</code> </li>
74
75   <li> <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.Root.html" title="twisted.spread.pb.Root">pb.Root</a></code>
76   : <code>spread/pb.py</code>, actually defined as
77   <code>twisted.spread.flavors.Root</code>
78   in <code>spread/flavors.py</code> </li>
79
80   <li> <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.Referenceable.html" title="twisted.spread.pb.Referenceable">pb.Referenceable</a></code>
81   : <code>spread/pb.py</code>, actually defined as
82   <code>twisted.spread.flavors.Referenceable</code>
83   in <code>spread/flavors.py</code> </li>
84
85 </ul>
86
87 <p>Classes and interfaces that get involved when you start to care
88 about authorization and security:</p>
89
90 <ul>
91   <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.cred.portal.Portal.html" title="twisted.cred.portal.Portal">Portal</a></code>
92   : <code>cred/portal.py</code></li>
93
94   <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.cred.portal.IRealm.html" title="twisted.cred.portal.IRealm">IRealm</a></code>
95   : <code>cred/portal.py</code></li>
96   
97   <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.IPerspective.html" title="twisted.spread.pb.IPerspective">IPerspective</a></code>
98   : <code>spread/pb.py</code>, which you will usually be interacting
99   with via <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.Avatar.html" title="twisted.spread.pb.Avatar">pb.Avatar</a></code> (a basic implementor of the interface).</li>
100 </ul>
101
102 <h3>Subclassing and Implementing<a name="auto2"/></h3>
103
104 <p>Technically you can subclass anything you want, but technically you
105 could also write a whole new framework, which would just waste a lot
106 of time. Knowing which classes are useful to subclass or which
107 interfaces to implement is one of the bits of knowledge that's crucial
108 to using PB (and all of Twisted) successfully. Here are some hints to
109 get started:</p>
110
111 <ul>
112
113   <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.Root.html" title="twisted.spread.pb.Root">pb.Root</a></code>, <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.Referenceable.html" title="twisted.spread.pb.Referenceable">pb.Referenceable</a></code>: you'll
114   subclass these to make remotely-referenceable objects (i.e., objects
115   which you can call methods on remotely) using PB. You don't need to
116   change any of the existing behavior, just inherit all of it and add
117   the remotely-accessible methods that you want to export.</li>
118
119   <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.Avatar.html" title="twisted.spread.pb.Avatar">pb.Avatar</a></code>: You'll
120   be subclassing this when you get into PB programming with
121   authorization. This is an implementor of IPerspective.</li>
122
123   <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.cred.checkers.ICredentialsChecker.html" title="twisted.cred.checkers.ICredentialsChecker">ICredentialsChecker</a></code>: Implement this if
124   you want to authenticate your users against some sort of data store:
125   i.e., an LDAP database, an RDBMS, etc. There are already a few
126   implementations of this for various back-ends in
127   twisted.cred.checkers.</li>
128
129 </ul>
130
131
132
133 <h2>Things you can Call Remotely<a name="auto3"/></h2>
134
135 <p>At this writing, there are three <q>flavors</q> of objects that can
136 be accessed remotely through <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.RemoteReference.html" title="twisted.spread.pb.RemoteReference">RemoteReference</a></code> objects. Each of these
137 flavors has a rule for how the <code class="python">callRemote</code>
138 message is transformed into a local method call on the server.  In
139 order to use one of these <q>flavors</q>, subclass them and name your
140 published methods with the appropriate prefix.
141
142 <ul>
143   <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.IPerspective.html" title="twisted.spread.pb.IPerspective">twisted.spread.pb.IPerspective</a></code> implementors
144
145   <p>This is the first interface we deal with. It is a <q>perspective</q>
146   onto your PB application.  Perspectives are slightly special because
147   they are usually the first object that a given user can access in
148   your application (after they log on).  A user should only receive a
149   reference to their <em>own</em> perspective. PB works hard to
150   verify, as best it can, that any method that can be called on a
151   perspective directly is being called on behalf of the user who is
152   represented by that perspective.  (Services with unusual
153   requirements for <q>on behalf of</q>, such as simulations with the
154   ability to posess another player's avatar, are accomplished by
155   providing indirected access to another user's perspective.)
156
157   </p>
158
159   <p>Perspectives are not usually serialized as remote references, so
160   do not return an IPerspective-implementor directly. </p>
161
162   <p>The way most people will want to implement IPerspective is by
163   subclassing pb.Avatar. Remotely accessible methods on pb.Avatar
164   instances are named with the <code class="python">perspective_</code> prefix. </p>
165
166   </li>
167
168   <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.Referenceable.html" title="twisted.spread.pb.Referenceable">twisted.spread.pb.Referenceable</a></code>
169
170   <p>Referenceable objects are the simplest kind of PB object.  You can call
171   methods on them and return them from methods to provide access to other
172   objects' methods.  </p>
173
174   <p>However, when a method is called on a Referenceable, it's not possible to
175   tell who called it.</p>
176
177   <p>Remotely accessible methods on Referenceables are named with the
178   <code class="python">remote_</code> prefix.</p>
179
180   </li>
181
182   <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.Viewable.html" title="twisted.spread.pb.Viewable">twisted.spread.pb.Viewable</a></code>
183
184   <p>Viewable objects are remotely referenceable objects which have the
185   additional requirement that it must be possible to tell who is calling them.
186   The argument list to a Viewable's remote methods is modified in order to
187   include the Perspective representing the calling user.</p>
188
189   <p>Remotely accessible methods on Viewables are named with the
190   <code class="python">view_</code> prefix.</p>
191
192   </li>
193
194 </ul>
195
196 </p>
197
198 <h2>Things you can Copy Remotely<a name="auto4"/></h2>
199
200 <p>In addition to returning objects that you can call remote methods on, you
201 can return structured copies of local objects.</p>
202
203 <p>There are 2 basic flavors that allow for copying objects remotely.  Again,
204 you can use these by subclassing them.  In order to specify what state you want
205 to have copied when these are serialized, you can either use the Python default 
206  <code class="python">__getstate__</code> or specialized method calls for that
207 flavor.</p>
208
209 <p>
210 <ul>
211   <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.Copyable.html" title="twisted.spread.pb.Copyable">twisted.spread.pb.Copyable</a></code>
212
213   <p>This is the simpler kind of object that can be copied.  Every time this
214   object is returned from a method or passed as an argument, it is serialized
215   and unserialized.</p>
216
217   <p><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.Copyable.html" title="twisted.spread.pb.Copyable">Copyable</a></code>
218   provides a method you can override, <code class="py-prototype">getStateToCopyFor(perspective)</code>, which
219   allows you to decide what an object will look like for the
220   perspective who is requesting it. The <code class="python">perspective</code> argument will be the perspective
221   which is either passing an argument or returning a result an
222   instance of your Copyable class. </p>
223
224   <p>For security reasons, in order to allow a particular Copyable class to
225   actually be copied, you must declare a <code class="python">RemoteCopy</code>
226   handler for
227   that Copyable subclass.  The easiest way to do this is to declare both in the
228   same module, like so:
229
230   <pre class="python"><p class="py-linenumber">1
231 2
232 3
233 4
234 5
235 6
236 </p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">spread</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">flavors</span>
237 <span class="py-src-keyword">class</span> <span class="py-src-identifier">Foo</span>(<span class="py-src-parameter">flavors</span>.<span class="py-src-parameter">Copyable</span>):
238     <span class="py-src-keyword">pass</span>
239 <span class="py-src-keyword">class</span> <span class="py-src-identifier">RemoteFoo</span>(<span class="py-src-parameter">flavors</span>.<span class="py-src-parameter">RemoteCopy</span>):
240     <span class="py-src-keyword">pass</span>
241 <span class="py-src-variable">flavors</span>.<span class="py-src-variable">setUnjellyableForClass</span>(<span class="py-src-variable">Foo</span>, <span class="py-src-variable">RemoteFoo</span>)
242 </pre>
243
244   In this case, each time a Foo is copied between peers, a RemoteFoo will be
245   instantiated and populated with the Foo's state.  If you do not do this, PB
246   will complain that there have been security violations, and it may close the
247   connection.
248   </p>
249
250   </li>
251
252   <li><code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.Cacheable.html" title="twisted.spread.pb.Cacheable">twisted.spread.pb.Cacheable</a></code>
253
254   <p>Let me preface this with a warning: Cacheable may be hard to understand.
255   The motivation for it may be unclear if you don't have some experience with
256   real-world applications that use remote method calling of some kind.  Once
257   you understand why you need it, what it does will likely seem simple and
258   obvious, but if you get confused by this, forget about it and come back
259   later.  It's possible to use PB without understanding Cacheable at all.
260   </p>
261
262   <p>Cacheable is a flavor which is designed to be copied only when necessary,
263   and updated on the fly as changes are made to it.  When passed as an argument
264   or a return value, if a Cacheable exists on the side of the connection it is
265   being copied to, it will be referred to by ID and not copied.</p>
266
267   <p>Cacheable is designed to minimize errors involved in replicating an object
268   between multiple servers, especially those related to having stale
269   information.  In order to do this, Cacheable automatically registers
270   observers and queries state atomically, together.  You can override the
271   method <code class="py-prototype">getStateToCacheAndObserveFor(self,
272   perspective, observer)</code> in order to specify how your observers will be
273   stored and updated.
274   </p>
275
276   <p>Similar to
277   <code class="python">getStateToCopyFor</code>,
278   <code class="python">getStateToCacheAndObserveFor</code> gets passed a
279   perspective.  It also gets passed an
280   <code class="python">observer</code>, which is a remote reference to a
281   <q>secret</q> fourth referenceable flavor:
282   <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.RemoteCache.html" title="twisted.spread.pb.RemoteCache">RemoteCache</a></code>.</p>
283
284   <p>A <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.RemoteCache.html" title="twisted.spread.pb.RemoteCache">RemoteCache</a></code> is simply
285   the object that represents your
286   <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.Cacheable.html" title="twisted.spread.pb.Cacheable">Cacheable</a></code> on the other side
287   of the connection.  It is registered using the same method as
288   <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.RemoteCopy.html" title="twisted.spread.pb.RemoteCopy">RemoteCopy</a></code>, above.
289   RemoteCache is different, however, in that it will be referenced by its peer.
290   It acts as a Referenceable, where all methods prefixed with
291   <code class="python">observe_</code> will be callable remotely.  It is
292   recommended that your object maintain a list (note: library support for this
293   is forthcoming!) of observers, and update them using
294   <code class="python">callRemote</code> when the Cacheable changes in a way
295   that should be noticeable to its clients.  </p>
296
297   <p>Finally, when all references to a
298   <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.Cacheable.html" title="twisted.spread.pb.Cacheable">Cacheable</a></code> from a given
299   perspective are lost,
300   <code class="py-prototype">stoppedObserving(perspective, observer)</code>
301   will be called on the
302   <code class="API"><a href="http://twistedmatrix.com/documents/12.1.0/api/twisted.spread.pb.Cacheable.html" title="twisted.spread.pb.Cacheable">Cacheable</a></code>, with the same
303   perspective/observer pair that <code>getStateToCacheAndObserveFor</code> was
304   originally called with.  Any cleanup remote calls can be made there, as well
305   as removing the observer object from any lists which it was previously in.
306   Any further calls to this observer object will be invalid.</p>
307   </li>
308 </ul>
309 </p>
310
311 <h2>Footnotes</h2><ol><li><a name="footnote-1"><span class="footnote">Most of Twisted is like this.  Hell, most of
312 Unix is like this: if <em>you</em> think it would be useful, someone else has
313 probably thought that way in the past, and acted on it, and you can take
314 advantage of the tool they created to solve the same problem you're facing
315 now.</span></a></li></ol></div>
316
317     <p><a href="index.html">Index</a></p>
318     <span class="version">Version: 12.1.0</span>
319   </body>
320 </html>