~justin-fathomdb/nova/justinsb-openstack-api-volumes

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/core/howto/pb-intro.html

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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/10.0.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><em><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.protocol.Factory.html" title="twisted.internet.protocol.Factory">Factory</a></code></em>
 
58
  : <code>internet/protocol.py</code></li>
 
59
 
 
60
  <li><em><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.spread.pb.PBServerFactory.html" title="twisted.spread.pb.PBServerFactory">PBServerFactory</a></code></em>
 
61
  : <code>spread/pb.py</code></li>
 
62
 
 
63
  <li><em><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.spread.pb.Broker.html" title="twisted.spread.pb.Broker">Broker</a></code></em>
 
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> <em><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.spread.pb.RemoteReference.html" title="twisted.spread.pb.RemoteReference">RemoteReference</a></code></em>
 
73
  : <code>spread/pb.py</code> </li>
 
74
 
 
75
  <li> <em><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.spread.pb.Root.html" title="twisted.spread.pb.Root">pb.Root</a></code></em>
 
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> <em><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.spread.pb.Referenceable.html" title="twisted.spread.pb.Referenceable">pb.Referenceable</a></code></em>
 
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><em><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.cred.portal.Portal.html" title="twisted.cred.portal.Portal">Portal</a></code></em>
 
92
  : <code>cred/portal.py</code></li>
 
93
 
 
94
  <li><em><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.cred.portal.IRealm.html" title="twisted.cred.portal.IRealm">IRealm</a></code></em>
 
95
  : <code>cred/portal.py</code></li>
 
96
  
 
97
  <li><em><code class="API"><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.spread.pb.IPerspective.html" title="twisted.spread.pb.IPerspective">IPerspective</a></code></em>
 
98
  : <code>spread/pb.py</code>, which you will usually be interacting
 
99
  with via pb.Avatar (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/10.0.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/10.0.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/10.0.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/10.0.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/10.0.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/10.0.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/10.0.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/10.0.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/10.0.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/10.0.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/10.0.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/10.0.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/10.0.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/10.0.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/10.0.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/10.0.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/10.0.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: 10.0.0</span>
 
319
  </body>
 
320
</html>
 
 
b'\\ No newline at end of file'