[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 -- http://www.squirtual-reality.com -------------------------------- Linux user #458601 - http://counter.li.org.
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 -- http://www.squirtual-reality.com -------------------------------- Linux user #458601 - http://counter.li.org.
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 -- http://www.squirtual-reality.com -------------------------------- Linux user #458601 - http://counter.li.org.
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 -- http://www.squirtual-reality.com -------------------------------- Linux user #458601 - http://counter.li.org.
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 -- http://www.squirtual-reality.com -------------------------------- Linux user #458601 - http://counter.li.org.
participants (2)
-
Jean-Paul Calderone
-
Simon Pickles