views:

327

answers:

1

I have a 2 processes:

the first process is manager.py starts in backgroung:

from multiprocessing.managers import SyncManager, BaseProxy
from CompositeDict import *

class CompositeDictProxy(BaseProxy):

    _exposed_ = ('addChild', 'setName')
    def addChild(self, child):
        return self._callmethod('addChild', [child])

    def setName(self, name):
        return self._callmethod('setName', [name])

class Manager(SyncManager):
    def __init__(self):
        super(Manager, self).__init__(address=('127.0.0.1', 50000), authkey='abracadabra')

def start_Manager():
    Manager().get_server().serve_forever()

if __name__=="__main__":
    Manager.register('get_plant', CompositeDict, proxytype=CompositeDictProxy)
    start_Manager()


and the second is consumer.py supposed to use registered objects defined into the manager:

from manager import *
import time
import random

class Consumer():

    def __init__(self):
        Manager.register('get_plant')

        m = Manager()
        m.connect()
        plant = m.get_plant()
        #plant.setName('alfa')
        plant.addChild('beta')


if __name__=="__main__":
    Consumer()


Running the manager in background, and than the consumer I get the error message: RuntimeError: maximum recursion depth exceeded, when using addChild into the consumer, while I can correctly use setName.

Methods addChild and setName belongs to CompositeDict, I suppose to be proxied.

What's wrong?

CompositeDict overwrites native __getattr__** method and is involved in the error message. I suppose, in some way, it's not used the right one __getattr__ method. If so how could I solve this problem??


The detailed error message is:

Traceback (most recent call last):
  File "consumer.py", line 21, in <module>
    Consumer()
  File "consumer.py", line 17, in __init__
    plant.addChild('beta')
  File "<string>", line 2, in addChild
  File "/usr/lib/python2.5/site-packages/multiprocessing-2.6.1.1-py2.5-linux-i686.egg/multiprocessing/managers.py", line 729, in _callmethod
    kind, result = conn.recv()
  File "/home/--/--/CompositeDict.py", line 99, in __getattr__
    child = self.findChild(name)
  File "/home/--/--/CompositeDict.py", line 185, in findChild
    for child in self.getAllChildren():
  File "/home/--/--/CompositeDict.py", line 167, in getAllChildren
    l.extend(child.getAllChildren())
  File "/home/--/--/CompositeDict.py", line 165, in getAllChildren
    for child in self._children:
  File "/home/--/--/CompositeDict.py", line 99, in __getattr__
    child = self.findChild(name)
  File "/home/--/--/CompositeDict.py", line 185, in findChild
    for child in self.getAllChildren():
  File "/--/--/prove/CompositeDict.py", line 165, in getAllChildren
    for child in self._children:
  ...
  File "/home/--/--/CompositeDict.py", line 99, in __getattr__
    child = self.findChild(name)
  File "/home/--/--/CompositeDict.py", line 185, in findChild
    for child in self.getAllChildren():
  RuntimeError: maximum recursion depth exceeded
+1  A: 

Besides fixing many other bugs in the above which I assume are accidental (init must be __init__, you're missing several instances of self, misindentation, etc, etc), the key bit is to make the registration in manager.py into:

Manager.register('get_plant', CompositeDict,   proxytype=CompositeDictProxy)

no idea what you're trying to accomplish w/that lambda as the second arg, but the second arg must be the callable that makes the type you need, not one that makes a two-items tuple like you're using.

Alex Martelli
Corrected the code with a "better one" sorry.But this time I kept RuntimeError: maximum recursion depth exceededwhen using addChild while proxy seems to be ok. addChild comes from a Composite taken there http://code.activestate.com/recipes/498249/#clastand makes internally use of "__getattr__" that seems to be responsible of the bad recusion. Any Idea??
DrFalk3n
Now you have no controller.py code anywhere in your question -- making it harder and harder to offer you any help...!-).
Alex Martelli
really again sorry, I thought it would be more simple :-( without not necessary controller. But this problem it's making me crazy
DrFalk3n
So what about adding a controller again? right now the code as given just doesn't DO much (e.g. if you just run manager.py, consumer.py is never involved -- how could it be?).
Alex Martelli
AlberT