Hi All,

We create our customised manager which will fork child process with 
baseManager. Because we registered SIGCHLD to reap the zombie for manager, we 
found this causes baseManager raise RemoteError when called twice.(Test script 
attached.)

After look at baseManager.py we found recv() in handling the request has been 
interrupted by comming SIGCHLD, not retry recv(), but raise to client side 
directly.
            try:

                methodname = obj = None

                request = recv()<------------------this line been interrupted 
by SIGCHLD

                ident, methodname, args, kwds = request

                obj, exposed, gettypeid = id_to_obj[ident]

                if methodname not in exposed:

                    raise AttributeError(

                        'method %r of %r object is not in exposed=%r' %

                        (methodname, type(obj), exposed)

                        )

                function = getattr(obj, methodname)
                try:

                    res = function(*args, **kwds)

                except Exception, e:

                    msg = ('#ERROR', e)

                else:

                    typeid = gettypeid and gettypeid.get(methodname, None)

                    if typeid:

                        rident, rexposed = self.create(conn, typeid, res)

                        token = Token(typeid, self.address, rident)

                        msg = ('#PROXY', (rexposed, token))

                    else:

                        msg = ('#RETURN', res)
            except AttributeError:
                if methodname is None:
                    msg = ('#TRACEBACK', format_exc())
                else:
                    try:
                        fallback_func = self.fallback_mapping[methodname]
                        result = fallback_func(
                            self, conn, ident, obj, *args, **kwds
                            )
                        msg = ('#RETURN', result)
                    except Exception:
                        msg = ('#TRACEBACK', format_exc())

            except EOFError:
                util.debug('got EOF -- exiting thread serving %r',
                           threading.current_thread().name)
                sys.exit(0)

            except Exception:<------does not handle IOError,INTR here should 
retry recv()
                msg = ('#TRACEBACK', format_exc())


REF: http://bugs.python.org/issue17097


import sys
import os
from time import sleep
import signal
from multiprocessing import Process
from multiprocessing.managers import BaseManager
import threading


class _SuperVdsmManager(BaseManager):
    pass


def func():
    return 'func'


class _SuperVdsm(object):
    def runChild(self):
        proc = Process(target=func)
        proc.start()
        proc.terminate()


def _zombieReaper(signum, frame):
    print "sigchld!"


def startSuper():
    try:
        address = '/home/lvroyce.sock'
        if os.path.exists(address):
            os.unlink(address)

        signal.signal(signal.SIGCHLD, _zombieReaper)
        try:
            manager = _SuperVdsmManager(address=address, authkey='abc')
            manager.register('instance', callable=_SuperVdsm)

            server = manager.get_server()
            servThread = threading.Thread(target=server.serve_forever)
            servThread.setDaemon(True)
            servThread.start()
            while servThread.isAlive():
                servThread.join(5)
        except:
            raise
        finally:
            if os.path.exists(address):
                os.unlink(address)

    except Exception:
        sys.exit(1)


def main():
    sv = Process(target=startSuper)
    sv.start()
    sleep(2)
    _manager = _SuperVdsmManager(address='/home/lvroyce.sock',
                                 authkey='abc')
    _manager.register('instance')
    _manager.connect()
    _svdsm = _manager.instance()
    _svdsm.runChild()
    sleep(4)
    _svdsm.runChild()

if __name__ == '__main__':
    main()
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to