[Twisted-Python] Hip-bone's connected to the...

Glyph Lefkowitz glyph at twistedmatrix.com
Fri Aug 3 14:05:56 EDT 2001

Thank you, kevin, for doing this write-up... I hope this feedback enables
you to keep going with it.

I'd highly encourage you to write some code though :)

On Thu, 2 Aug 2001, Kevin Turner wrote:

> Application (twisted.internet.main.Application):
> The overall container and entry point for your program as a whole.  The
> answer to the question "Uh, okay, now how do I start it?".  In addition
> to starting, it also handles shutdown, typically pickling itself to disk
> in the process.  And yes, that means that when you pickle.load an object
> from a twisted .spl file, an Application is what you are getting.

Now .tap file...

> When Applications are running, they typically have at least one Port
> (see below) listening for connections, as internet..Applications which
> don't communicate with anyone are less fun than dead puppies.  Ports
> are added with the .addPort() method, and the Application has them
> startListening as soon as it is run().

You may want to add the fact that they'll often have a Delayed as well.

> Port (twisted.internet.tcp.Port):

Your description of Ports is fairly accurate.

> Broker (twisted.spread.pb.Broker)
> Typically created by a pb.BrokerFactory, these broker between a

Or manually instantiated for use with a tcp.Client!

> connection (from the Port) and a pb.Service.  The services available to
> the broker are those which have been added to the BrokerFactory with its
> addService method.

> Service (twisted.spread.pb.Service)
> The service you are providing (XXX: a less vauge, circular description?)

No, sounds good -- I want to reinforce that these classes are what they
sound like :)

> is defined as a subclass of pb.Service (ex: web.ResourcePublisher).
> I expect the common usage is to only have no more than one instance
> of a given Service class, as it defines the service *as a whole*,
> and generally does not bother itself with the details of a request.
> Instead, Services are asked (through the broker) for Perspectives,
> through the getPerspectiveNamed method.

Might want to be a little clearer about the service doing the
authentication here...

> Perspective (twisted.spread.pb.Perspective)

> The reason the client is asking the server to perform a service is
> because the server is able to see and do things the client does not
> have access to.  That is, from the client's perspective, these things
> are not visible, but from the server's perspective, they're perfectly
> accessible.
> Enter one Perspective Broker.  Through the Perspective Broker, clients
> may have actions performed from the perspective of an object on the
> server.

I think it would make sense to explain references first, even though you
can't get to them without perspectives (because on the client, you have a
reference to a perspective); the notion of translating calls on references
into 'special' calls on instances is important for Perspective, Proxied,
Referenced, and Cached...

Also don't talk so much about "client" and "server" when referring to the
perspective; this is objects-to-objects.

> These objects are instances of classes descended from pb.Perspective.
> If a client runs a method .foo() on a reference to such an object, the
> server will run the method .perspective_foo() on the instance on the
> server side.


> XXX: Examples would help loads.

# Here's one to get you started.
class Foo(pb.Perspective):
  def perspective_bar(self, baz):
    print 'received remote method call'

> Note: Since all commands over the broker happen asynchronously, the
> client cannot receive return values from a perspective_foo() method.

Yes it can, actually.  If you pass a keyword parameter 'pbcallback', that
callback will be invoked on the client when the return value is
received.  However, you can't get that as a return value from the .foo
call on the client (obviously).

> Referenced (twisted.spread.pb.Referenced)
> Since a Perspective object cannot pass data back to the client through
> return values, how does the client ever learn anything about what
> it's done through the broker?  If the client passes an object that is
> Referenced through to the perspective, then the perspective on the
> server side will be able to pass data to methods of the Referenced
> object.  A call to .foo() on the server's side will call .remote_foo()
> on the object in the client.  This works in much the same way as clients
> calling methods of Perspective objects.

Speaking in terms of client and server still doesn't make sense.  The
server can send Referenced instances to the client too.  And the lead-in
sentence is wrong anyway :)

Additionally, you can pass a reference in to the requestPerspective method
now, to provide an analogue for the "client" object that you'd send
messages to in many other protocols.

> Ports get added to Applications
> (a BrokerFactory is attached to the port)
> Services get added to BrokerFactories
> Perspectives are issued by Services

Proxies are issued by returning Proxied instances from Perspective methods
(or from Proxied methods)

Copies are made    [ditto]      Copied  [ditto]

Caches are like copies, but they maintain identity rather than being
re-sent each time. (optional)

> How does error notification work?

Similiarly to return-value notification.

  myReference.do(arg,arg,pbcallback=myCallback, pberrback=myErrorCallback)

All you get as an argument to the error callback is is a traceback or
error message string though.

> What naming conventions should application authors use?

Just stick to the Twisted coding standard and you'll be fine.

> Any other must-have pb classes?

Copied and Proxied are worth explaining.  Reference is crucial.  Cached is
interesting, but complex and you'll know if you need it.  Other things are

Hope this helps.

                      ______      __   __  _____  _     _
                     |  ____ |      \_/   |_____] |_____|
                     |_____| |_____  |    |       |     |
                     @ t w i s t e d m a t r i x  . c o m

More information about the Twisted-Python mailing list