~jk0/nova/xs-ipv6

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/doc/historic/2002/ipc10/twisted-network-framework/errata.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"?>
 
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 
3
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
4
 
 
5
<html xmlns="http://www.w3.org/1999/xhtml">
 
6
  <head>
 
7
    <title>The World of Software is a World of Constant
 
8
    Change</title>
 
9
  </head>
 
10
 
 
11
  <body>
 
12
    <p><em><strong>Note:</strong> This document is relevant for the
 
13
    version of Twisted that was current at <a
 
14
    href="http://www.python10.com">IPC10</a>. It has since been
 
15
    superseded by many changes to the Python API. It is remaining
 
16
    unchanged for historical reasons, but please refer to
 
17
    documentation for the specific system you are looking for and
 
18
    not these papers for current information.</em></p>
 
19
 
 
20
    <h1>The World of Software is a World of Constant Change</h1>
 
21
 
 
22
    <p>Twisted has undergone several major revisions since Moshe
 
23
    Zadka and I wrote the <a href="ipc10paper.html">"The Twisted
 
24
    Network Framework"</a>. Most of these changes have not deviated
 
25
    from the central vision of the framework, but almost all of the
 
26
    code listings have been re-visited and enhanced in some
 
27
    way.</p>
 
28
 
 
29
    <p>So, while the paper was correct at the time that it was
 
30
    originally written, a few things have changed which have
 
31
    invalidated portions of it.</p>
 
32
 
 
33
    <p>Most significant is the fact that almost all methods which
 
34
    pass callbacks of some kind have been changed to take no
 
35
    callback or error-callback arguments, and instead return an
 
36
    instance of a <code
 
37
    class="API">twisted.python.defer.Deferred</code>. This means
 
38
    that an asynchronous function can be easily identified visually
 
39
    because it will be of the form: <code
 
40
    class="python">async_obj.asyncMethod("foo")<b>.addCallbacks(succeded,
 
41
    failed)</b></code>. There is also a utility method <code
 
42
    class="python">addCallback</code> which makes it more
 
43
    convenient to pass additional arguments to a callback function
 
44
    and omit special-case error handling.</p>
 
45
 
 
46
    <p>While it is still backwards compatible, <code
 
47
    class="API">twisted.internet.passport</code> has been re-named
 
48
    to <code class="API">twisted.cred</code>, and the various
 
49
    classes in it have been split out into submodules of that
 
50
    package, and the various remote-object superclasses have been
 
51
    moved out of twisted.spread.pb and put into
 
52
    twisted.spread.flavors.</p>
 
53
 
 
54
    <p><code class="python">Application.listenOn</code> has been
 
55
    replaced with the more descripively named <code
 
56
    class="python">Application.listenTCP</code>, <code
 
57
    class="python">Application.listenUDP</code>, and <code
 
58
    class="python">Application.listenSSL</code>.</p>
 
59
 
 
60
    <p><code class="API">twisted.web.widgets</code> has progressed
 
61
    quite far since the paper was written! One description
 
62
    specifically given in the paper is no longer correct:</p>
 
63
 
 
64
    <blockquote>
 
65
      The namespace for evaluating the template expressions is
 
66
      obtained by scanning the class hierarchy for attributes, and
 
67
      getting each of those attributes from the current instance.
 
68
      This means that all methods will be bound methods, so
 
69
      indicating "self" explicitly is not required. While it is
 
70
      possible to override the method for creating namespaces,
 
71
      using this default has the effect of associating all
 
72
      presentation code for a particular widget in one class, along
 
73
      with its template. If one is working with a non-programmer
 
74
      designer, and the template is in an external file, it is
 
75
      always very clear to the designer what functionality is
 
76
      available to them in any given scope, because there is a list
 
77
      of available methods for any given class.
 
78
    </blockquote>
 
79
<p>This is still possible to avoid breakages in old code, but
 
80
after some experimentation, it became clear that simply passing
 
81
    <code class="python">self</code> was an easier method for
 
82
    creating the namespace, both for designers and programmers.</p>
 
83
    <p>In addition, since the advent of Zope3, interoperability
 
84
    with Zope has become increasingly interesting possibility for
 
85
    the Twisted development team, since it would be desirable if
 
86
    Twisted could use their excellent strategy for
 
87
    content-management, while still maintaining Twisted's
 
88
    advantages in the arena of multi-protocol servers. Of
 
89
    particular interest has been Zope Presentation Templates, since
 
90
    they seem to be a truly robust solution for keeping design
 
91
    discrete from code, compatible with the event-based method in
 
92
    which twisted.web.widgets processes web requests. <code
 
93
    class="API">twisted.web.widgets.ZopePresentationTemplate</code>
 
94
    may be opening soon in a theatre near you!</p>
 
95
 
 
96
    <p>The following code examples are corrected or modernized
 
97
    versions of the ones that appear in the paper.</p>
 
98
 
 
99
    <blockquote>
 
100
      Listing 9: A remotely accessible object and accompanying call
 
101
      
 
102
<pre class="python">
 
103
# Server Side
 
104
class MyObject(pb.Referenceable):
 
105
    def remote_doIt(self):
 
106
        return "did it"
 
107
 
 
108
# Client Side
 
109
    ...
 
110
    def myCallback(result):
 
111
        print result # result will be 'did it'
 
112
    def myErrback(stacktrace):
 
113
        print 'oh no, mr. bill!'
 
114
        print stacktrace
 
115
    myRemoteReference.doIt().addCallbacks(myCallback,
 
116
                                          myErrback)
 
117
</pre>
 
118
    </blockquote>
 
119
 
 
120
    <blockquote>
 
121
      Listing 10: An object responding to its calling perspective 
 
122
<pre class="python">
 
123
# Server Side
 
124
class Greeter(pb.Viewable):
 
125
    def view_greet(self, actor):
 
126
        return "Hello %s!\n" % actor.perspectiveName
 
127
 
 
128
# Client Side
 
129
    ...
 
130
    remoteGreeter.greet().addCallback(sys.stdout.write)
 
131
    ...
 
132
</pre>
 
133
    </blockquote>
 
134
     
 
135
 
 
136
    <blockquote>
 
137
      Listing 12: A client for Echoer objects. 
 
138
<pre class="python">
 
139
from twisted.spread import pb
 
140
from twisted.internet import main
 
141
def gotObject(object):
 
142
    print "got object:",object
 
143
    object.echo("hello network".addCallback(gotEcho)
 
144
def gotEcho(echo):
 
145
    print 'server echoed:',echo
 
146
    main.shutDown()
 
147
def gotNoObject(reason):
 
148
    print "no object:",reason
 
149
    main.shutDown()
 
150
pb.getObjectAt("localhost", 8789, gotObject, gotNoObject, 30)
 
151
main.run()
 
152
</pre>
 
153
    </blockquote>
 
154
 
 
155
    <blockquote>
 
156
      Listing 13: A PB server using twisted's "passport"
 
157
      authentication. 
 
158
<pre class="python">
 
159
from twisted.spread import pb
 
160
from twisted.internet import main
 
161
class SimplePerspective(pb.Perspective):
 
162
    def perspective_echo(self, text):
 
163
        print 'echoing',text
 
164
        return text
 
165
class SimpleService(pb.Service):
 
166
    def getPerspectiveNamed(self, name):
 
167
        return SimplePerspective(name, self)
 
168
if __name__ == '__main__':
 
169
    import pbecho
 
170
    app = main.Application("pbecho")
 
171
    pbecho.SimpleService("pbecho",app).getPerspectiveNamed("guest").makeIdentity("guest")
 
172
    app.listenTCP(pb.portno, pb.BrokerFactory(pb.AuthRoot(app)))
 
173
    app.save("start")
 
174
</pre>
 
175
    </blockquote>
 
176
 
 
177
    <blockquote>
 
178
      Listing 14: Connecting to an Authorized Service 
 
179
<pre class="python">
 
180
from twisted.spread import pb
 
181
from twisted.internet import main
 
182
def success(message):
 
183
    print "Message received:",message
 
184
    main.shutDown()
 
185
def failure(error):
 
186
    print "Failure...",error
 
187
    main.shutDown()
 
188
def connected(perspective):
 
189
    perspective.echo("hello world").addCallbacks(success, failure)
 
190
    print "connected."
 
191
 
 
192
pb.connect("localhost", pb.portno, "guest", "guest",
 
193
           "pbecho", "guest", 30).addCallbacks(connected,
 
194
                                               failure)
 
195
main.run()
 
196
</pre>
 
197
    </blockquote>
 
198
 
 
199
    <blockquote>
 
200
      Listing 15: A Twisted GUI application 
 
201
<pre class="python">
 
202
from twisted.internet import main, ingtkernet
 
203
from twisted.spread.ui import gtkutil
 
204
import gtk
 
205
ingtkernet.install()
 
206
class EchoClient:
 
207
    def __init__(self, echoer):
 
208
        l.hide()
 
209
        self.echoer = echoer
 
210
        w = gtk.GtkWindow(gtk.WINDOW_TOPLEVEL)
 
211
        vb = gtk.GtkVBox(); b = gtk.GtkButton("Echo:")
 
212
        self.entry = gtk.GtkEntry(); self.outry = gtk.GtkEntry()
 
213
        w.add(vb)
 
214
        map(vb.add, [b, self.entry, self.outry])
 
215
        b.connect('clicked', self.clicked)
 
216
        w.connect('destroy', gtk.mainquit)
 
217
        w.show_all()
 
218
    def clicked(self, b):
 
219
        txt = self.entry.get_text()
 
220
        self.entry.set_text("")
 
221
        self.echoer.echo(txt).addCallback(self.outry.set_text)
 
222
l = gtkutil.Login(EchoClient, None, initialService="pbecho")
 
223
l.show_all()
 
224
gtk.mainloop()
 
225
</pre>
 
226
    </blockquote>
 
227
 
 
228
    <blockquote>
 
229
      Listing 16: an event-based web widget. 
 
230
<pre class="python">
 
231
from twisted.spread import pb
 
232
from twisted.python import defer
 
233
from twisted.web import widgets
 
234
class EchoDisplay(widgets.Gadget, widgets.Presentation):
 
235
    template = """&lt;H1&gt;Welcome to my widget, displaying %%%%echotext%%%%.&lt;/h1&gt;
 
236
    &lt;p&gt;Here it is: %%%%getEchoPerspective()%%%%&lt;/p&gt;"""
 
237
    echotext = 'hello web!'
 
238
    def getEchoPerspective(self):
 
239
        return ['&lt;b&gt;',
 
240
            pb.connect("localhost", pb.portno,
 
241
                   "guest", "guest", "pbecho", "guest", 1).
 
242
                addCallbacks(self.makeListOf, self.formatTraceback)
 
243
            ,'&lt;/b&gt;']
 
244
    def makeListOf(self, echoer):
 
245
        return [echoer.echo(self.echotext).addCallback(lambda x: [x])]
 
246
if __name__ == "__main__":
 
247
    from twisted.web import server
 
248
    from twisted.internet import main
 
249
    a = main.Application("pbweb")
 
250
    a.listenTCP(8080, server.Site(EchoDisplay()))
 
251
    a.run()
 
252
</pre>
 
253
    </blockquote>
 
254
  </body>
 
255
</html>
 
256