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 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Corrected the code with a "better one" sorry. But this time I kept RuntimeError: maximum recursion depth exceeded when using addChild while proxy seems to be ok. addChild comes from a Composite taken there code.activestate.com/recipes/498249/#clast and makes internally use of "getattr" that seems to be responsible of the bad recusion. Any Idea??
Now you have no controller.py code anywhere in your question -- making it harder and harder to offer you any help...!-).
really again sorry, I thought it would be more simple :-( without not necessary controller. But this problem it's making me crazy
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?).
I suppose it can effectively do the job once manager.py is run and put in background (python manager.py &) and then run python consumer.py

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.