[Twisted-Python] Adapting RemoteReferences

Sam Jordan sam at twistedmatrix.com
Mon Nov 3 20:59:04 EST 2003


Hi,

Thanks for the response Jp ...

On Mon, Nov 03, 2003 at 07:43:10AM -0500, Jp Calderone wrote:
>   I think the preferred approach is the opposite.  Instead of taking remote
> references and trying to treat them as local, take local references and
> treat them as remote (this makes sense from an interface enforcement
> consistency point of view, too -- it's easier to throw away some information
> than you have than to pull information you don't have out of thin air).

Indeed, this does make more sense, I don't know why I didn't think of it in this
way. The way you have described also takes care of emulating the Deferred result
instead of having to specify it as part of the interface as well.

On the other hand, you still end up with basically the same level of interface
enforcement; that is, you can guarantee the interface characteristics of local
objects but not remote objects. This is unlikely to change however, without either
the protocol changing (unlikely - "did somebody mention IDL? :-)") or people obeying
their own interface definition conventions. Still, I can certainly see your point that
publishing an object as implementing an interface when it possibly doesn't is worse
than wrapping a local object with a single string-based dispatching method. 

Other small differences I can think of are that in cases where a system has already
been written and a remote interface is being provided, it may be easier to make
chanes to the effect of:

    # part of remote system wrapper class
    def remote_addObserver(self, observer):
        underlyingSystem.addObserver(observer.adaptTo(IUserInterface))

    # part of the underlying system
    # (code that was written prior to considering a remote interface)
    def addObserver(self, observer): self.observers.append(observer)

So if the underlying system was built without a remote interface in mind
it may be easier to just adapt the remote refs than to change every instance
of calls to the local objects.

If it _was_ written with the knowledge that a remote interface will be placed
on top in the future, I assume the code would look something like:

    # part of remote system wraper class
    def remote_addObserver(self, observer):
        underlyingSystem.addObserver(observer)

    # part of underlying system
    def addObserver(self, observer):
        if not isinstance(observer, RemoteReference):
            observer = LocalAsyncForwarder(observer, IUserInterface)
        # rest of method ...

And then all subsequent calls would use callRemote.

I guess which one you prefer is purely a matter of style and I can
see no real disadvantages from the later approach unless of course,
the system has already been written.

>   See twisted.spread.util.LocalAsyncForwarder.

Thanks for pointing this out.

Cheers,

Sam.




More information about the Twisted-Python mailing list