コード例 #1
0
 def __init__(self, multiengine):
     xmlrpc.XMLRPC.__init__(self)
     # Adapt the raw multiengine to `ISynchronousMultiEngine` before saving
     # it.  This allow this class to do two adaptation steps.
     log.msg("Adapting: %r"%multiengine)
     self.smultiengine = ISynchronousMultiEngine(multiengine)
     self._deferredIDCallbacks = {}
コード例 #2
0
class SynchronousMultiEngineTestCase(DeferredTestCase,
                                     IMultiEngineBaseTestCase):
    def setUp(self):
        self.controller = ControllerService()
        self.controller.startService()
        self.multiengine = IMultiEngine(self.controller)
        self.smultiengine = ISynchronousMultiEngine(self.multiengine)
        self.engines = []

    def tearDown(self):
        self.controller.stopService()
        for e in self.engines:
            e.stopService()

    def testExecuteNoBlock(self):
        self.addEngine(2)
        result = [{
            'commandIndex': 0,
            'stdin': 'a=5',
            'id': 0,
            'stderr': '',
            'stdout': ''
        }, {
            'commandIndex': 0,
            'stdin': 'a=5',
            'id': 1,
            'stderr': '',
            'stdout': ''
        }]
        cid = self.smultiengine.registerClient()
        d = self.smultiengine.execute(cid, False, 'all', 'a=5')
        d.addCallback(
            lambda r: self.smultiengine.getPendingDeferred(cid, r, True))
        d.addCallback(lambda r: self.assert_(r == result))
        return d

    def testExecuteBlock(self):
        self.addEngine(2)
        result = [{
            'commandIndex': 0,
            'stdin': 'a=5',
            'id': 0,
            'stderr': '',
            'stdout': ''
        }, {
            'commandIndex': 0,
            'stdin': 'a=5',
            'id': 1,
            'stderr': '',
            'stdout': ''
        }]
        cid = self.smultiengine.registerClient()
        d = self.smultiengine.execute(cid, True, 'all', 'a=5')
        d.addCallback(lambda r: self.assert_(r == result))
        return d
コード例 #3
0
    def __init__(self, multiengine):
        self.smultiengine = ISynchronousMultiEngine(multiengine)
        self.child_execute = HTTPMultiEngineExecute(self.smultiengine)
        self.child_push = HTTPMultiEnginePush(self.smultiengine)
        self.child_pull = HTTPMultiEnginePull(self.smultiengine)
        self.child_get_result = HTTPMultiEngineGetResult(self.smultiengine)
        self.child_reset = HTTPMultiEngineReset(self.smultiengine)
        self.child_keys = HTTPMultiEngineKeys(self.smultiengine)
        self.child_kill = HTTPMultiEngineKill(self.smultiengine)
        self.child_clear_queue = HTTPMultiEngineClearQueue(self.smultiengine)
        self.child_queue_status = HTTPMultiEngineQueueStatus(self.smultiengine)
        self.child_get_properties = HTTPMultiEngineGetProperties(
            self.smultiengine)
        self.child_get_ids = HTTPMultiEngineGetIDs(self.smultiengine)

        self.child_get_properties = HTTPMultiEngineGetProperties(
            self.smultiengine)
        self.child_set_properties = HTTPMultiEngineSetProperties(
            self.smultiengine)
        self.child_has_properties = HTTPMultiEngineHasProperties(
            self.smultiengine)
        self.child_del_properties = HTTPMultiEngineDelProperties(
            self.smultiengine)
        self.child_clear_properties = HTTPMultiEngineClearProperties(
            self.smultiengine)

        self.child_getPendingResult = HTTPMultiEngineGetPendingResult(
            self.smultiengine)
        self.child_getAllPendingResults = HTTPMultiEngineGetAllPendingResults(
            self.smultiengine)
        self.child_registerClient = HTTPMultiEngineRegisterClient(
            self.smultiengine)
        self.child_unregisterClient = HTTPMultiEngineUnregisterClient(
            self.smultiengine)
コード例 #4
0
class SynchronousMultiEngineTestCase(DeferredTestCase,
                                     IMultiEngineBaseTestCase):
    def setUp(self):
        self.controller = ControllerService()
        self.controller.startService()
        self.multiengine = IMultiEngine(self.controller)
        self.smultiengine = ISynchronousMultiEngine(self.multiengine)
        self.engines = []

    def tearDown(self):
        self.controller.stopService()
        for e in self.engines:
            e.stopService()

    def testExecuteNoBlock(self):
        nengines = 2
        self.addEngine(nengines)
        cmd = 'a=5'
        results = [self.createShell().execute(cmd) for i in range(nengines)]
        for i, s in enumerate(results):
            s['id'] = i
        cid = self.smultiengine.registerClient()
        d = self.smultiengine.execute(cid, False, 'all', cmd)
        d.addCallback(
            lambda r: self.smultiengine.getPendingDeferred(cid, r, True))
        d.addCallback(lambda r: self.assert_(r == results))
        return d

    def testExecuteBlock(self):
        nengines = 2
        self.addEngine(nengines)
        cmd = 'a=5'
        results = [self.createShell().execute(cmd) for i in range(nengines)]
        for i, s in enumerate(results):
            s['id'] = i
        cid = self.smultiengine.registerClient()
        d = self.smultiengine.execute(cid, True, 'all', cmd)
        d.addCallback(lambda r: self.assert_(r == results))
        return d
コード例 #5
0
    def __init__(self, multiengine):
        self.smultiengine = ISynchronousMultiEngine(multiengine)
        self.child_execute = HTTPMultiEngineExecute(self.smultiengine)
        self.child_push = HTTPMultiEnginePush(self.smultiengine)
        self.child_pull = HTTPMultiEnginePull(self.smultiengine)
        self.child_getResult = HTTPMultiEngineGetResult(self.smultiengine)
        self.child_reset = HTTPMultiEngineReset(self.smultiengine)
        self.child_keys = HTTPMultiEngineKeys(self.smultiengine)
        self.child_kill = HTTPMultiEngineKill(self.smultiengine)
        self.child_clearQueue = HTTPMultiEngineClearQueue(self.smultiengine)
        self.child_queueStatus = HTTPMultiEngineQueueStatus(self.smultiengine)
        self.child_scatter = HTTPMultiEngineScatter(self.smultiengine)
        self.child_gather = HTTPMultiEngineGather(self.smultiengine)
        self.child_getIDs = HTTPMultiEngineGetIDs(self.smultiengine)

        self.child_getPendingResult = HTTPMultiEngineGetPendingResult(
            self.smultiengine)
        self.child_getAllPendingResults = HTTPMultiEngineGetAllPendingResults(
            self.smultiengine)
        self.child_registerClient = HTTPMultiEngineRegisterClient(
            self.smultiengine)
        self.child_unregisterClient = HTTPMultiEngineUnregisterClient(
            self.smultiengine)
コード例 #6
0
 def setUp(self):
     self.controller = ControllerService()
     self.controller.startService()
     self.multiengine = IMultiEngine(self.controller)
     self.smultiengine = ISynchronousMultiEngine(self.multiengine)
     self.engines = []
コード例 #7
0
 def __init__(self, multiengine):
     xmlrpc.XMLRPC.__init__(self)
     # Adapt the raw multiengine to `ISynchronousMultiEngine` before saving
     # it.  This allow this class to do two adaptation steps.
     self.smultiengine = ISynchronousMultiEngine(multiengine)
コード例 #8
0
class XMLRPCMultiEngineFromMultiEngine(xmlrpc.XMLRPC):
    """Adapt `IMultiEngine` -> `ISynchronousMultiEngine` -> `IXMLRPCMultiEngine`.
    """
    
    implements(IXMLRPCMultiEngine)
    
    addSlash = True
    
    def __init__(self, multiengine):
        xmlrpc.XMLRPC.__init__(self)
        # Adapt the raw multiengine to `ISynchronousMultiEngine` before saving
        # it.  This allow this class to do two adaptation steps.
        self.smultiengine = ISynchronousMultiEngine(multiengine)

    #---------------------------------------------------------------------------
    # Non interface methods
    #---------------------------------------------------------------------------
    
    def packageFailure(self, f):
        f.cleanFailure()
        return self.packageSuccess(f)

    def packageSuccess(self, obj):    
        serial = pickle.dumps(obj, 2)
        return xmlrpc.Binary(serial)
       
    #---------------------------------------------------------------------------
    # IEngineMultiplexer related methods
    #---------------------------------------------------------------------------
    
    @packageResult
    def xmlrpc_execute(self, request, clientID, block, targets, lines):     
        return self.smultiengine.execute(clientID, block, targets, lines)
    
    @packageResult    
    def xmlrpc_push(self, request, clientID, block, targets, binaryNS):
        try:
            namespace = pickle.loads(binaryNS.data)
        except:
            d = defer.fail(failure.Failure())
        else:
            d = self.smultiengine.push(clientID, block, targets, **namespace)
        return d

    @packageResult
    def xmlrpc_pull(self, request, clientID, block, targets, *keys):
        return self.smultiengine.pull(clientID, block, targets, *keys)
    
    @packageResult
    def xmlrpc_getResult(self, request, clientID, block, targets, i=None):
        if i == 'None':
            i = None
        return self.smultiengine.getResult(clientID, block, targets, i)
    
    @packageResult
    def xmlrpc_reset(self, request, clientID, block, targets):
        return self.smultiengine.reset(clientID, block, targets)
    
    @packageResult
    def xmlrpc_keys(self, request, clientID, block, targets):
        return self.smultiengine.keys(clientID, block, targets)
    
    @packageResult
    def xmlrpc_kill(self, request, clientID, block, targets, controller=False):
        return self.smultiengine.kill(clientID, block, targets, controller)

    @packageResult
    def xmlrpc_clearQueue(self, request, clientID, targets):
        return self.smultiengine.clearQueue(clientID, True, targets)

    @packageResult
    def xmlrpc_queueStatus(self, request, clientID, targets):
        return self.smultiengine.queueStatus(clientID, True, targets)
    
    #---------------------------------------------------------------------------
    # IMultiEngine related methods
    #---------------------------------------------------------------------------
    
    def xmlrpc_getIDs(self, request):
        return self.smultiengine.getIDs()
     
    #---------------------------------------------------------------------------
    # IEngineCoordinator related methods
    #---------------------------------------------------------------------------
    
    @packageResult
    def xmlrpc_scatter(self, request, clientID, block, targets, key, bseq, style='basic', flatten=False):
        try:
            seq = pickle.loads(bseq.data)
        except:
            d = defer.fail(failure.Failure())
        else:
            d = self.smultiengine.scatter(clientID, block, targets, key, seq, style, flatten)
        return d      
    
    @packageResult
    def xmlrpc_gather(self, request, clientID, block, targets, key, style='basic'):
        return self.smultiengine.gather(clientID, block, targets, key, style)
    
    #---------------------------------------------------------------------------
    # Pending Deferred related methods
    #---------------------------------------------------------------------------            
    
    def xmlrpc_registerClient(self, request):
        """"""
        clientID = self.smultiengine.registerClient()
        return clientID
        
    def xmlrpc_unregisterClient(self, request, clientID):
        """"""
        try:
            self.smultiengine.unregisterClient(clientID)
        except error.InvalidClientID:
            f = failure.Failure()
            return self.packageFailure(f)
        else:
            return True
            
    @packageResult
    def xmlrpc_getPendingResult(self, request, clientID, resultID, block):
        """"""
        return self.smultiengine.getPendingDeferred(clientID, resultID, block)
        
    @packageResult
    def xmlrpc_getAllPendingResults(self, request, clientID):
        """"""    
        return self.smultiengine.getAllPendingDeferreds(clientID)

    @packageResult
    def xmlrpc_flush(self, request, clientID):
        """"""    
        return self.smultiengine.flush(clientID)
コード例 #9
0
class XMLRPCMultiEngineFromMultiEngine(xmlrpc.XMLRPC):
    """Adapt `IMultiEngine` -> `ISynchronousMultiEngine` -> `IXMLRPCMultiEngine`.
    """

    implements(IXMLRPCMultiEngine)

    addSlash = True

    def __init__(self, multiengine):
        xmlrpc.XMLRPC.__init__(self)
        # Adapt the raw multiengine to `ISynchronousMultiEngine` before saving
        # it.  This allow this class to do two adaptation steps.
        self.smultiengine = ISynchronousMultiEngine(multiengine)

    #---------------------------------------------------------------------------
    # Non interface methods
    #---------------------------------------------------------------------------

    def packageFailure(self, f):
        f.cleanFailure()
        return self.packageSuccess(f)

    def packageSuccess(self, obj):
        serial = pickle.dumps(obj, 2)
        return xmlrpc.Binary(serial)

    #---------------------------------------------------------------------------
    # IEngineMultiplexer related methods
    #---------------------------------------------------------------------------

    @packageResult
    def xmlrpc_execute(self, request, clientID, block, targets, lines):
        return self.smultiengine.execute(clientID, block, targets, lines)

    @packageResult
    def xmlrpc_push(self, request, clientID, block, targets, binaryNS):
        try:
            namespace = pickle.loads(binaryNS.data)
        except:
            d = defer.fail(failure.Failure())
        else:
            d = self.smultiengine.push(clientID, block, targets, **namespace)
        return d

    @packageResult
    def xmlrpc_pull(self, request, clientID, block, targets, *keys):
        d = self.smultiengine.pull(clientID, block, targets, *keys)
        return d

    @packageResult
    def xmlrpc_pushFunction(self, request, clientID, block, targets, binaryNS):
        try:
            namespace = pickle.loads(binaryNS.data)
        except:
            d = defer.fail(failure.Failure())
        else:
            namespace = uncanDict(namespace)
            d = self.smultiengine.pushFunction(clientID, block, targets,
                                               **namespace)
        return d

    def _canMultipleKeys(self, result):
        return [canSequence(r) for r in result]

    @packageResult
    def xmlrpc_pullFunction(self, request, clientID, block, targets, *keys):
        d = self.smultiengine.pullFunction(clientID, block, targets, *keys)
        if len(keys) == 1:
            d.addCallback(canSequence)
        elif len(keys) > 1:
            d.addCallback(self._canMultipleKeys)
        return d

    @packageResult
    def xmlrpc_getResult(self, request, clientID, block, targets, i=None):
        if i == 'None':
            i = None
        return self.smultiengine.getResult(clientID, block, targets, i)

    @packageResult
    def xmlrpc_reset(self, request, clientID, block, targets):
        return self.smultiengine.reset(clientID, block, targets)

    @packageResult
    def xmlrpc_keys(self, request, clientID, block, targets):
        return self.smultiengine.keys(clientID, block, targets)

    @packageResult
    def xmlrpc_kill(self, request, clientID, block, targets, controller=False):
        return self.smultiengine.kill(clientID, block, targets, controller)

    @packageResult
    def xmlrpc_clearQueue(self, request, clientID, targets):
        """Clear the queue on targets.
        
        This method always blocks.  This means that it will always waits for
        the queues to be cleared before returning.  This method will never
        return the id of a pending deferred.
        """
        return self.smultiengine.clearQueue(clientID, True, targets)

    @packageResult
    def xmlrpc_queueStatus(self, request, clientID, targets):
        """Get the queue status on targets.
        
        This method always blocks.  This means that it will always return
        the queues status's.  This method will never return the id of a pending 
        deferred.    
        """
        return self.smultiengine.queueStatus(clientID, True, targets)

    @packageResult
    def xmlrpc_setProperties(self, request, clientID, block, targets,
                             binaryNS):
        try:
            ns = pickle.loads(binaryNS.data)
        except:
            d = defer.fail(failure.Failure())
        else:
            d = self.smultiengine.setProperties(clientID, block, targets, **ns)
        return d

    @packageResult
    def xmlrpc_getProperties(self, request, clientID, block, targets, *keys):
        return self.smultiengine.getProperties(clientID, block, targets, *keys)

    @packageResult
    def xmlrpc_hasProperties(self, request, clientID, block, targets, *keys):
        return self.smultiengine.hasProperties(clientID, block, targets, *keys)

    @packageResult
    def xmlrpc_delProperties(self, request, clientID, block, targets, *keys):
        return self.smultiengine.delProperties(clientID, block, targets, *keys)

    @packageResult
    def xmlrpc_clearProperties(self, request, clientID, block, targets, *keys):
        return self.smultiengine.clearProperties(clientID, block, targets,
                                                 *keys)

    #---------------------------------------------------------------------------
    # IMultiEngine related methods
    #---------------------------------------------------------------------------

    def xmlrpc_getIDs(self, request):
        """Get the ids of the registered engines.
        
        This method always blocks.
        """
        return self.smultiengine.getIDs()

    #---------------------------------------------------------------------------
    # Pending Deferred related methods
    #---------------------------------------------------------------------------

    def xmlrpc_registerClient(self, request):
        """"""
        clientID = self.smultiengine.registerClient()
        return clientID

    def xmlrpc_unregisterClient(self, request, clientID):
        """"""
        try:
            self.smultiengine.unregisterClient(clientID)
        except error.InvalidClientID:
            f = failure.Failure()
            return self.packageFailure(f)
        else:
            return True

    @packageResult
    def xmlrpc_getPendingResult(self, request, clientID, resultID, block):
        """"""
        return self.smultiengine.getPendingDeferred(clientID, resultID, block)

    @packageResult
    def xmlrpc_getAllPendingResults(self, request, clientID):
        """"""
        return self.smultiengine.getAllPendingDeferreds(clientID)

    @packageResult
    def xmlrpc_flush(self, request, clientID):
        """"""
        return self.smultiengine.flush(clientID)
コード例 #10
0
class XMLRPCSynchronousMultiEngineFromMultiEngine(xmlrpc.XMLRPC):
    """Adapt `IMultiEngine` -> `ISynchronousMultiEngine` -> `IXMLRPCSynchronousMultiEngine`.
    """
    
    implements(IXMLRPCSynchronousMultiEngine)
    
    addSlash = True
    
    def __init__(self, multiengine):
        xmlrpc.XMLRPC.__init__(self)
        # Adapt the raw multiengine to `ISynchronousMultiEngine` before saving
        # it.  This allow this class to do two adaptation steps.
        log.msg("Adapting: %r"%multiengine)
        self.smultiengine = ISynchronousMultiEngine(multiengine)
        self._deferredIDCallbacks = {}
    
    #---------------------------------------------------------------------------
    # Non interface methods
    #---------------------------------------------------------------------------
    
    def packageFailure(self, f):
        f.cleanFailure()
        return self.packageSuccess(f)
    
    def packageSuccess(self, obj):
        serial = pickle.dumps(obj, 2)
        return xmlrpc.Binary(serial)
    
    #---------------------------------------------------------------------------
    # Things related to PendingDeferredManager
    #---------------------------------------------------------------------------
    
    @packageResult
    def xmlrpc_get_pending_deferred(self, request, deferredID, block):
        d = self.smultiengine.get_pending_deferred(deferredID, block)
        try:
            callback = self._deferredIDCallbacks.pop(deferredID)
        except KeyError:
            callback = None
        if callback is not None:
            d.addCallback(callback[0], *callback[1], **callback[2])
        return d
       
    @packageResult
    def xmlrpc_clear_pending_deferreds(self, request):
        return defer.maybeDeferred(self.smultiengine.clear_pending_deferreds)
    
    def _addDeferredIDCallback(self, did, callback, *args, **kwargs):
        self._deferredIDCallbacks[did] = (callback, args, kwargs)
        return did
        
    #---------------------------------------------------------------------------
    # IEngineMultiplexer related methods
    #---------------------------------------------------------------------------
    
    @packageResult
    def xmlrpc_execute(self, request, lines, targets, block):
        return self.smultiengine.execute(lines, targets=targets, block=block)
    
    @packageResult    
    def xmlrpc_push(self, request, binaryNS, targets, block):
        try:
            namespace = pickle.loads(binaryNS.data)
        except:
            d = defer.fail(failure.Failure())
        else:
            d = self.smultiengine.push(namespace, targets=targets, block=block)
        return d
    
    @packageResult
    def xmlrpc_pull(self, request, keys, targets, block):
        d = self.smultiengine.pull(keys, targets=targets, block=block)
        return d
    
    @packageResult    
    def xmlrpc_push_function(self, request, binaryNS, targets, block):
        try:
            namespace = pickle.loads(binaryNS.data)
        except:
            d = defer.fail(failure.Failure())
        else:
            namespace = uncanDict(namespace)
            d = self.smultiengine.push_function(namespace, targets=targets, block=block)
        return d
    
    def _canMultipleKeys(self, result):
        return [canSequence(r) for r in result]
    
    @packageResult
    def xmlrpc_pull_function(self, request, keys, targets, block):
        def can_functions(r, keys):
            if len(keys)==1 or isinstance(keys, str):
                result = canSequence(r)
            elif len(keys)>1:
                result = [canSequence(s) for s in r]
            return result
        d = self.smultiengine.pull_function(keys, targets=targets, block=block)
        if block:
            d.addCallback(can_functions, keys)
        else:
            d.addCallback(lambda did: self._addDeferredIDCallback(did, can_functions, keys))
        return d
    
    @packageResult    
    def xmlrpc_push_serialized(self, request, binaryNS, targets, block):
        try:
            namespace = pickle.loads(binaryNS.data)
        except:
            d = defer.fail(failure.Failure())
        else:
            d = self.smultiengine.push_serialized(namespace, targets=targets, block=block)
        return d
    
    @packageResult
    def xmlrpc_pull_serialized(self, request, keys, targets, block):
        d = self.smultiengine.pull_serialized(keys, targets=targets, block=block)
        return d
    
    @packageResult
    def xmlrpc_get_result(self, request, i, targets, block):
        if i == 'None':
            i = None
        return self.smultiengine.get_result(i, targets=targets, block=block)
    
    @packageResult
    def xmlrpc_reset(self, request, targets, block):
        return self.smultiengine.reset(targets=targets, block=block)
    
    @packageResult
    def xmlrpc_keys(self, request, targets, block):
        return self.smultiengine.keys(targets=targets, block=block)
    
    @packageResult
    def xmlrpc_kill(self, request, controller, targets, block):
        return self.smultiengine.kill(controller, targets=targets, block=block)
    
    @packageResult
    def xmlrpc_clear_queue(self, request, targets, block):
        return self.smultiengine.clear_queue(targets=targets, block=block)
    
    @packageResult
    def xmlrpc_queue_status(self, request, targets, block):
        return self.smultiengine.queue_status(targets=targets, block=block)
    
    @packageResult
    def xmlrpc_set_properties(self, request, binaryNS, targets, block):
        try:
            ns = pickle.loads(binaryNS.data)
        except:
            d = defer.fail(failure.Failure())
        else:
            d = self.smultiengine.set_properties(ns, targets=targets, block=block)
        return d
    
    @packageResult
    def xmlrpc_get_properties(self, request, keys, targets, block):
        if keys=='None':
            keys=None
        return self.smultiengine.get_properties(keys, targets=targets, block=block)
    
    @packageResult
    def xmlrpc_has_properties(self, request, keys, targets, block):
        return self.smultiengine.has_properties(keys, targets=targets, block=block)
    
    @packageResult
    def xmlrpc_del_properties(self, request, keys, targets, block):
        return self.smultiengine.del_properties(keys, targets=targets, block=block)
    
    @packageResult
    def xmlrpc_clear_properties(self, request, targets, block):
        return self.smultiengine.clear_properties(targets=targets, block=block)
    
    #---------------------------------------------------------------------------
    # IMultiEngine related methods
    #---------------------------------------------------------------------------
    
    def xmlrpc_get_ids(self, request):
        """Get the ids of the registered engines.
        
        This method always blocks.
        """
        return self.smultiengine.get_ids()
コード例 #11
0
 def __init__(self, multiEngine):
     self.multiEngine = ISynchronousMultiEngine(multiEngine)
コード例 #12
0
class PBMultiEngineFromMultiEngine(pb.Root):
    """Perspective Broker interface to controller.
    
    See IPBMultiEngine and IMultiEngine (and its children) for documentation. 
    """

    implements(IPBMultiEngine)

    def __init__(self, multiEngine):
        self.multiEngine = ISynchronousMultiEngine(multiEngine)

    #---------------------------------------------------------------------------
    # Non interface methods
    #---------------------------------------------------------------------------

    def checkReturns(self, rlist):
        for r in rlist:
            if isinstance(r, (Failure, Exception)):
                rlist[rlist.index(r)] = pickle.dumps(r, 2)
        return rlist

    #---------------------------------------------------------------------------
    # IEngineMultiplexer related methods
    #---------------------------------------------------------------------------

    def remote_execute(self, clientID, block, targets, lines):
        if not self.multiEngine.verifyTargets(targets):
            return defer.fail(error.InvalidEngineID(
                repr(targets))).addErrback(packageFailure)
        else:
            return self.multiEngine.execute(clientID, block, targets, lines)

    def remote_push(self, targets, pNamespace):
        if not self.multiEngine.verifyTargets(targets):
            return defer.fail(error.InvalidEngineID(repr(targets)))
        else:
            try:
                namespace = pickle.loads(pNamespace)
            except:
                return defer.fail(failure.Failure()).addErrback(packageFailure)
            else:
                deferredID = self._getNextDeferredID()
                d = self.multiEngine.push(targets, **namespace)
                self.pendingDeferreds[deferredID] = d
                return defer.succeed(deferredID)

    def remote_pull(self, targets, *keys):
        if not self.multiEngine.verifyTargets(targets):
            return defer.fail(error.InvalidEngineID(repr(targets)))
        else:
            deferredID = self._getNextDeferredID()
            d = self.multiEngine.pull(targets, *keys)
            d.addCallback(pickle.dumps, 2)
            d.addCallback(checkMessageSize, repr(keys))
            self.pendingDeferreds[deferredID] = d
            return defer.succeed(deferredID)

    def remote_getResult(self, targets, i=None):
        if not self.multiEngine.verifyTargets(targets):
            return defer.fail(error.InvalidEngineID(repr(targets)))
        else:
            deferredID = self._getNextDeferredID()
            d = self.multiEngine.getResult(targets, i)
            self.pendingDeferreds[deferredID] = d
            return defer.succeed(deferredID)

    def remote_reset(self, targets):
        if not self.multiEngine.verifyTargets(targets):
            return defer.fail(error.InvalidEngineID(repr(targets)))
        else:
            deferredID = self._getNextDeferredID()
            d = self.multiEngine.reset(targets)
            self.pendingDeferreds[deferredID] = d
            return defer.succeed(deferredID)

    def remote_keys(self, targets):
        if not self.multiEngine.verifyTargets(targets):
            return defer.fail(error.InvalidEngineID(repr(targets)))
        else:
            deferredID = self._getNextDeferredID()
            d = self.multiEngine.keys(targets)
            self.pendingDeferreds[deferredID] = d
            return defer.succeed(deferredID)

    def remote_kill(self, targets, controller=False):
        if not self.multiEngine.verifyTargets(targets):
            return defer.fail(error.InvalidEngineID(repr(targets)))
        else:
            deferredID = self._getNextDeferredID()
            d = self.multiEngine.kill(targets, controller)
            self.pendingDeferreds[deferredID] = d
            return defer.succeed(deferredID)

    def remote_pushSerialized(self, targets, pNamespace):
        if not self.multiEngine.verifyTargets(targets):
            return defer.fail(error.InvalidEngineID(repr(targets)))
        else:
            try:
                namespace = pickle.loads(pNamespace)
            except:
                return defer.fail(failure.Failure()).addErrback(packageFailure)
            else:
                deferredID = self._getNextDeferredID()
                d = self.multiEngine.pushSerialized(targets, **namespace)
                self.pendingDeferreds[deferredID] = d
                return defer.succeed(deferredID)

    def remote_pullSerialized(self, targets, *keys):
        if not self.multiEngine.verifyTargets(targets):
            return defer.fail(error.InvalidEngineID(repr(targets)))
        else:
            deferredID = self._getNextDeferredID()
            d = self.multiEngine.pullSerialized(targets, *keys)
            d.addCallback(pickle.dumps, 2)
            d.addCallback(checkMessageSize, repr(keys))
            self.pendingDeferreds[deferredID] = d
            return defer.succeed(deferredID)

    def remote_clearQueue(self, targets):
        if not self.multiEngine.verifyTargets(targets):
            return defer.fail(error.InvalidEngineID(repr(targets)))
        else:
            deferredID = self._getNextDeferredID()
            d = self.multiEngine.clearQueue(targets)
            self.pendingDeferreds[deferredID] = d
            return defer.succeed(deferredID)

    def remote_queueStatus(self, targets):
        if not self.multiEngine.verifyTargets(targets):
            return defer.fail(error.InvalidEngineID(repr(targets)))
        else:
            deferredID = self._getNextDeferredID()
            d = self.multiEngine.queueStatus(targets)
            self.pendingDeferreds[deferredID] = d
            return defer.succeed(deferredID)

    #---------------------------------------------------------------------------
    # IMultiEngine related methods
    #---------------------------------------------------------------------------

    def remote_getIDs(self):
        d = self.multiEngine.getIDs()
        d.addErrback(packageFailure)
        return d

    def remote_verifyTargets(self, targets):
        result = self.multiEngine.verifyTargets(targets)
        return defer.succeed(result)

    #---------------------------------------------------------------------------
    # IEngineCoordinator related methods
    #---------------------------------------------------------------------------

    def remote_scatter(self, targets, key, pseq, style, flatten):
        if not self.multiEngine.verifyTargets(targets):
            return defer.fail(error.InvalidEngineID(repr(targets)))
        else:
            try:
                seq = pickle.loads(pseq)
            except:
                return defer.fail(failure.Failure()).addErrback(packageFailure)
            else:
                deferredID = self._getNextDeferredID()
                d = self.multiEngine.scatter(targets, key, seq, style, flatten)
                self.pendingDeferreds[deferredID] = d
                return defer.succeed(deferredID)

    def remote_gather(self, targets, key, style):
        if not self.multiEngine.verifyTargets(targets):
            return defer.fail(error.InvalidEngineID(repr(targets)))
        else:
            deferredID = self._getNextDeferredID()
            d = self.multiEngine.gather(targets, key, style)
            d.addCallback(pickle.dumps, 2)
            d.addCallback(checkMessageSize, repr(key))
            self.pendingDeferreds[deferredID] = d
            return defer.succeed(deferredID)