예제 #1
0
    def test_env_setting(self):
        """
        Test that and environment variable passed to the process starter
        is correctly passed to the child process.
        """
        s = sio()
        a = FakeAMP(s)
        STRING = "ciao"
        BOOT = """\
import sys, os
def main():
    os.write(4, os.getenv("FOOBAR"))
main()
"""
        starter = main.ProcessStarter(bootstrap=BOOT,
                                      packages=("twisted", "ampoule"),
                                      env={"FOOBAR": STRING})
        amp, finished = starter.startPythonProcess(main.AMPConnector(a),
                                                   "I'll be ignored")

        def _eb(reason):
            print reason

        finished.addErrback(_eb)
        return finished.addCallback(
            lambda _: self.assertEquals(s.getvalue(), STRING))
예제 #2
0
    def test_startProcess(self):
        """
        Test that startProcess actually starts a subprocess and that
        it receives data back from the process through AMP.
        """
        s = sio()
        a = FakeAMP(s)
        STRING = "ciao"
        BOOT = """\
import sys, os
def main(arg):
    os.write(4, arg)
main(sys.argv[1])
"""
        starter = main.ProcessStarter(bootstrap=BOOT,
                                      args=(STRING, ),
                                      packages=("twisted", "ampoule"))

        amp, finished = starter.startPythonProcess(main.AMPConnector(a))

        def _eb(reason):
            print reason

        finished.addErrback(_eb)
        return finished.addCallback(
            lambda _: self.assertEquals(s.getvalue(), STRING))
def start_plugin_services(server):
    """
    This will be called by the Evennia Server when starting up.

    server - the main Evennia server application
    """
    if not PROCPOOL_ENABLED:
        return

    # terminal output
    print '  amp (Process Pool): %s' % PROCPOOL_PORT

    from contrib.procpools.ampoule import main as ampoule_main
    from contrib.procpools.ampoule import service as ampoule_service
    from contrib.procpools.ampoule import pool as ampoule_pool
    from contrib.procpools.ampoule.main import BOOTSTRAP as _BOOTSTRAP
    from contrib.procpools.python_procpool import PythonProcPoolChild

    # for some reason absolute paths don't work here, only relative ones.
    apackages = ("twisted",
                 os.path.join(os.pardir, "contrib", "procpools",
                              "ampoule"), os.path.join(os.pardir,
                                                       "ev"), "settings")
    aenv = {
        "DJANGO_SETTINGS_MODULE":
        "settings",
        "DATABASE_NAME":
        settings.DATABASES.get("default", {}).get("NAME")
        or settings.DATABASE_NAME
    }
    if PROCPOOL_DEBUG:
        _BOOTSTRAP = _BOOTSTRAP % "log.startLogging(sys.stderr)"
    else:
        _BOOTSTRAP = _BOOTSTRAP % ""
    procpool_starter = ampoule_main.ProcessStarter(
        packages=apackages,
        env=aenv,
        path=PROCPOOL_DIRECTORY,
        uid=PROCPOOL_UID,
        gid=PROCPOOL_GID,
        bootstrap=_BOOTSTRAP,
        childReactor=sys.platform == 'linux2' and "epoll" or "default")
    procpool = ampoule_pool.ProcessPool(name=SERVICE_NAME,
                                        min=PROCPOOL_MIN_NPROC,
                                        max=PROCPOOL_MAX_NPROC,
                                        recycleAfter=500,
                                        timeout=PROCPOOL_TIMEOUT,
                                        maxIdle=PROCPOOL_IDLETIME,
                                        ampChild=PythonProcPoolChild,
                                        starter=procpool_starter)
    procpool_service = ampoule_service.AMPouleService(procpool,
                                                      PythonProcPoolChild,
                                                      PROCPOOL_PORT,
                                                      PROCPOOL_INTERFACE)
    procpool_service.setName(SERVICE_NAME)
    # add the new services to the server
    server.services.addService(procpool_service)
예제 #4
0
 def checkPool(_):
     pp = pool.ProcessPool(starter=main.ProcessStarter(
         childReactor=SECOND, packages=("twisted", "ampoule")),
                           ampChild=ReactorChild,
                           min=MIN,
                           max=MAX)
     pp.start()
     return pp.doWork(Reactor).addCallback(self.assertEquals, {
         'classname': "PollReactor"
     }).addCallback(lambda _: pp.stop())
예제 #5
0
    def test_roundtripError(self):
        """
        Test that invoking a child using an unreachable class raises
        a L{RunTimeError} .
        """
        class Child(child.AMPChild):
            pass

        starter = main.ProcessStarter(packages=("twisted", "ampoule"))

        self.assertRaises(RuntimeError,
                          starter.startAMPProcess,
                          ampChild=Child)
예제 #6
0
    def test_startAMPProcess(self):
        """
        Test that you can start an AMP subprocess and that it correctly
        accepts commands and correctly answers them.
        """
        STRING = "ciao"

        starter = main.ProcessStarter(packages=("twisted", "ampoule"))
        c, finished = starter.startAMPProcess(child.AMPChild)
        c.callRemote(commands.Echo, data=STRING).addCallback(
            lambda response: self.assertEquals(response['response'], STRING)
        ).addCallback(lambda _: c.callRemote(commands.Shutdown))
        return finished
예제 #7
0
    def test_BootstrapContext(self):
        starter = main.ProcessStarter(packages=('twisted', 'ampoule'))
        c, finished = starter.startAMPProcess(TempDirChild)
        cwd = []

        def checkBootstrap(response):
            cwd.append(response['cwd'])
            self.assertNotEquals(cwd, os.getcwd())

        d = c.callRemote(GetCWD)
        d.addCallback(checkBootstrap)
        d.addCallback(lambda _: c.callRemote(commands.Shutdown))
        finished.addCallback(
            lambda _: self.assertFalse(os.path.exists(cwd[0])))
        return finished
예제 #8
0
    def __init__(self,
                 ampChild=None,
                 ampParent=None,
                 min=5,
                 max=20,
                 name=None,
                 maxIdle=20,
                 recycleAfter=500,
                 starter=None,
                 timeout=None,
                 timeout_signal=DIE,
                 ampChildArgs=()):
        self.starter = starter
        self.ampChildArgs = tuple(ampChildArgs)
        if starter is None:
            self.starter = main.ProcessStarter(packages=("twisted", "ampoule"))
        self.ampParent = ampParent
        self.ampChild = ampChild
        if ampChild is None:
            from contrib.procpools.ampoule.child import AMPChild
            self.ampChild = AMPChild
        self.min = min
        self.max = max
        self.name = name
        self.maxIdle = maxIdle
        self.recycleAfter = recycleAfter
        self.timeout = timeout
        self.timeout_signal = timeout_signal
        self._queue = []

        self.processes = set()
        self.ready = set()
        self.busy = set()
        self._finishCallbacks = {}
        self._lastUsage = {}
        self._calls = {}
        self.looping = task.LoopingCall(self._pruneProcesses)
        self.looping.start(maxIdle, now=False)
예제 #9
0
    def test_startAMPAndParentProtocol(self):
        """
        Test that you can start an AMP subprocess and the children can
        call methods on their parent.
        """
        DATA = "CIAO"
        APPEND = "123"

        class Parent(amp.AMP):
            def pong(self, data):
                return {'response': DATA + APPEND}

            Pong.responder(pong)

        starter = main.ProcessStarter(packages=("twisted", "ampoule"))

        subp, finished = starter.startAMPProcess(ampChild=Child,
                                                 ampParent=Parent)
        subp.callRemote(
            Ping, data=DATA).addCallback(lambda response: self.assertEquals(
                response['response'], DATA + APPEND)).addCallback(
                    lambda _: subp.callRemote(commands.Shutdown))
        return finished
예제 #10
0
    def test_failing_deferToProcess(self):
        """
        Test failing subprocesses and the way they terminate and preserve
        failing information.
        """
        s = sio()
        a = FakeAMP(s)
        STRING = "ciao"
        BOOT = """\
import sys
def main(arg):
    raise Exception(arg)
main(sys.argv[1])
"""
        starter = main.ProcessStarter(bootstrap=BOOT,
                                      args=(STRING, ),
                                      packages=("twisted", "ampoule"))
        ready, finished = starter.startPythonProcess(main.AMPConnector(a),
                                                     "I'll be ignored")

        self.assertFailure(finished, error.ProcessTerminated)
        finished.addErrback(
            lambda reason: self.assertEquals(reason.getMessage(), STRING))
        return finished