[Twisted-Python] Problem with Jelly

Hi,
I thought I was following the doc 'Passing Complex Types' but am still getting unsecure Jellies.
I've got a file, imported by both pb.Client and pb.Server:
#------------------------------------------------ #jellyable.gameObject.py
class GameObject: # full of stuff pass
class PortableGameObject(GameObject, pb.Copyable): pass
class GameObjectReceiver(GameObject, pb.RemoteCopy): pass
pb.setUnjellyableForClass(PortableGameObject, GameObjectReceiver)
#------------------------------------------------
The client is trying to send an instance of a PortableGameObject thru PB, but the server spits out:
twisted.spread.jelly.InsecureJelly: Module jellyable.gameObject not allowed (in type jellyable.gameObject.PortableGameObject).
Why does it refer to 'Module jellyable.gameObject'? I know I am sending this thru the pipe:
Sat Apr 26 20:06:57 2008 - BROKER: Do Remote Call - target: None, msg: OBJECT_CHANGESECTOR, data: (<jellyable.gameObject.PortableGameObject instance at 0x87bab4c>,)
I remember reading that it is crucial to get the naming right on send and receive. How have I got it wrong?
Thanks
Simon

Simon Pickles wrote:
Hi,
I thought I was following the doc 'Passing Complex Types' but am still getting unsecure Jellies.
I've got a file, imported by both pb.Client and pb.Server:
#------------------------------------------------ #jellyable.gameObject.py
class GameObject: # full of stuff pass
class PortableGameObject(GameObject, pb.Copyable): pass
class GameObjectReceiver(GameObject, pb.RemoteCopy): pass
pb.setUnjellyableForClass(PortableGameObject, GameObjectReceiver)
#------------------------------------------------
The client is trying to send an instance of a PortableGameObject thru PB, but the server spits out:
twisted.spread.jelly.InsecureJelly: Module jellyable.gameObject not allowed (in type jellyable.gameObject.PortableGameObject).
Why does it refer to 'Module jellyable.gameObject'? I know I am sending this thru the pipe:
Sat Apr 26 20:06:57 2008 - BROKER: Do Remote Call - target: None, msg: OBJECT_CHANGESECTOR, data: (<jellyable.gameObject.PortableGameObject instance at 0x87bab4c>,)
I remember reading that it is crucial to get the naming right on send and receive. How have I got it wrong?
Thanks
Simon
Okay, well I think my first issue was I wasn't importing jellyable.gameObject into the server.
After doing this, I now get this slightly vague error:
twisted.spread.jelly.InsecureJelly: method
I think this may be because GameObject is a compound class, including instance of Mobile, Selectable, Intelligent and Container component classes.
Is it possible to send Compound classes? or should I distil my GameObject for transportation? (i'd rather not, obviously!)
Thanks
Si

Simon Pickles wrote:
Simon Pickles wrote:
Hi,
I thought I was following the doc 'Passing Complex Types' but am still getting unsecure Jellies.
I've got a file, imported by both pb.Client and pb.Server:
#------------------------------------------------ #jellyable.gameObject.py
class GameObject: # full of stuff pass
class PortableGameObject(GameObject, pb.Copyable): pass
class GameObjectReceiver(GameObject, pb.RemoteCopy): pass
pb.setUnjellyableForClass(PortableGameObject, GameObjectReceiver)
#------------------------------------------------
The client is trying to send an instance of a PortableGameObject thru PB, but the server spits out:
twisted.spread.jelly.InsecureJelly: Module jellyable.gameObject not allowed (in type jellyable.gameObject.PortableGameObject).
Why does it refer to 'Module jellyable.gameObject'? I know I am sending this thru the pipe:
Sat Apr 26 20:06:57 2008 - BROKER: Do Remote Call - target: None, msg: OBJECT_CHANGESECTOR, data: (<jellyable.gameObject.PortableGameObject instance at 0x87bab4c>,)
I remember reading that it is crucial to get the naming right on send and receive. How have I got it wrong?
Thanks
Simon
Okay, well I think my first issue was I wasn't importing jellyable.gameObject into the server.
After doing this, I now get this slightly vague error:
twisted.spread.jelly.InsecureJelly: method
I think this may be because GameObject is a compound class, including instance of Mobile, Selectable, Intelligent and Container component classes.
Is it possible to send Compound classes? or should I distil my GameObject for transportation? (i'd rather not, obviously!)
Thanks
Si
Update #3
Using a simple test class, TestJelly, I was able to succeed in transferring the instance. It was fairly trivial to also make those component classes jellyable in the same manner as their owner.
I kept adding complexity to TestJelly, approaching the structure of my GameObject class. It failed (with the InsecureJelly:method error) when I needed to make the passed class type an inherited one.
I realised that GameObject is a subclass of Actor, and calls Actor.__init__() in its own __init__.
So I tried making the actor jellyable too by doing this: ---------------------- #actor.py import stackless from log import logger from twisted.spread import pb
class Actor: def __init__(self, ch, logFunction): self.rx = ch self.logger = logFunction self.processMessageMethod = self.MessageHandler self.logger("rx: %s" % self.rx) stackless.tasklet(self.ProcessMessage)()
def ProcessMessage(self): while 1: self.logger("...... waiting for event message ......") self.processMessageMethod(self.rx.receive())
def MessageHandler(self,args): # Overridden by subclasses self.logger("ERROR - Unhandled Message: %s" % args)
class PortableActor(Actor, pb.Copyable): pass
class ActorReceiver(pb.RemoteCopy, Actor): pass
pb.setUnjellyableForClass(PortableActor, ActorReceiver) ---------------------- # testJelly.py # An instance of which I am trying to pass
from twisted.spread import pb import stackless
from actor import PortableActor from log import logger
class TestJelly(PortableActor): def __init__(self): PortableActor.__init__(self, stackless.channel(), logger.SYS)
class PortableTestJelly(TestJelly, pb.Copyable): pass
class TestJellyReceiver(pb.RemoteCopy, TestJelly): pass
pb.setUnjellyableForClass(PortableTestJelly, TestJellyReceiver)
------------------
No good! Something about the PortableActor.__init__ is breaking it.
Advice gratefully received.
Thanks Si

On Sun, 27 Apr 2008 12:07:37 +0100, Simon Pickles sipickles@hotmail.com wrote:
[snip]
I kept adding complexity to TestJelly, approaching the structure of my GameObject class. It failed (with the InsecureJelly:method error) when I needed to make the passed class type an inherited one.
I realised that GameObject is a subclass of Actor, and calls Actor.__init__() in its own __init__.
So I tried making the actor jellyable too by doing this:
#actor.py import stackless from log import logger from twisted.spread import pb
class Actor: def __init__(self, ch, logFunction): self.rx = ch self.logger = logFunction self.processMessageMethod = self.MessageHandler
What are these three attributes? `self.rx´, `self.logger´, and `self.processMessageMethod´ have to be jellyable if you want to mix `Actor´ into a class that you are going to jelly. If these attributes aren't supposed to be sent to the peer, then you need to provide custom jellying logic to exclude them.
Jean-Paul

The solution seems to be to use pb.Copyable.getStateToCopy() to control which members to send.
I am then replacing problem ones (stackless channels and tasklets mainly) with new local references at the receiving end.
(As Jean says I notice!)
Thanks
Si

So.... what are the ramifications of doing this:
class PortableGameObject(GameObject, pb.Copyable, pb.RemoteCopy): def getStateToCopy(self): d = self.__dict__.copy() return d def setCopyableState(self, state): #newDict = { 'newness' : 1 } self.__dict__ = state
pb.setUnjellyableForClass(PortableGameObject, PortableGameObject)
I only ask since I want to make the objects transmittable and receivable.
Thanks
Si
participants (2)
-
Jean-Paul Calderone
-
Simon Pickles