def test_nn(self): # Module-level function ns, fn = self.info.setCall(blockingTask).nn() self.assertEqual(ns, None) self.assertEqual(util.p2o(fn), blockingTask) # Method, pickled stuff = util.TestStuff() ns, fn = self.info.setCall(stuff.accumulate).nn() self.assertIsInstance(util.p2o(ns), util.TestStuff) self.assertEqual(fn, 'accumulate') # Method by fqn string ns, fn = self.info.setCall("util.testFunction").nn() self.assertEqual(ns, None) self.assertEqual(fn, "util.testFunction")
def gotResponse(response): if response['isValid']: value = response['value'] if response['isRaw']: return True, value return True, p2o(value) return False, None
def assembleChunkedResult(self, ID): pickleString = "" while True: isValid, value = yield self._handleNext(ID) if isValid: pickleString += value else: break defer.returnValue(p2o(pickleString))
def runTask(self, methodName, args, kw): """ This method is called to call the method specified by I{methodName} of my subclass running on the remote interpreter, with the supplied list I{args} of arguments and dict of keywords I{kw}, which may be empty. """ if not hasattr(self, 'wr'): self.wr = WireRunner() self.info = Info() # The method must be a named attribute of my subclass # instance. No funny business with special '__foo__' type # methods, either. func = None if methodName.startswith('_') \ else getattr(self, methodName, None) args = p2o(args, []) kw = p2o(kw, {}) if callable(func): return self.wr.call(func, *args, **kw) # Wasn't a legit method call text = self.info.setCall(methodName, args, kw).aboutCall() return {'status': 'e', 'result': "Couldn't run call '{}'".format(text)}
def test_call_iterator(self): N1, N2 = 20, 10 yield self.wr.call(self.tm.setStuff, N1, N2) response = yield self.wr.call(self.tm.getStuff) stuff = p2o(response['result']) self.assertEqual(len(stuff), N1) response = yield self.wr.call(self.tm.stufferator) self.assertEqual(response['status'], 'i') ID = response['result'] self.assertIn(ID, self.wr.iterators) self.assertEqual(type(self.wr.iterators[ID]), type(self.tm.stufferator())) for k in xrange(N1 + 1): response = yield self.wr.getNext(ID) chunk = response['value'] if k < N1: self.assertTrue(response['isValid']) self.assertTrue(response['isRaw']) self.assertEqual(chunk, stuff[k]) else: self.assertFalse(response['isValid'])
def test_call_chunked(self): N1, N2 = 10, 100000 response = yield self.wr.call(self.tm.setStuff, N1, N2) self.assertIsInstance(response, dict) response = yield self.wr.call(self.tm.getStuff) self.assertIsInstance(response, dict) self.assertEqual(response['status'], 'c') ID = response['result'] self.assertIsInstance(ID, str) chunks = [] while True: response = yield self.wr.getNext(ID) if response['isValid']: self.assertTrue(response['isRaw']) chunks.append(response['value']) else: break stuff = p2o("".join(chunks)) self.tm.setStuff(N1, N2) expectedStuff = self.tm.getStuff() self.assertEqual(stuff, expectedStuff)
def run(self, task): """ Sends the task callable, args, kw to the process and returns a deferred to the eventual result. """ def result(value): self.tasks.remove(task) task.callback((status, value)) self.tasks.append(task) doNext = task.callTuple[2].pop('doNext', False) yield self.dLock.acquire(doNext) self.dLock.release() yield self.ds.acquire() # Run the task via AMP, but only if it's connected #----------------------------------------------------------- if not self.ap.transport.connected: response = {'status': 'd', 'result': None} else: kw = {} consumer = task.callTuple[2].pop('consumer', None) for k, value in enumerate(task.callTuple): name = RunTask.arguments[k][0] kw[name] = value if isinstance(value, str) else o2p(value) if self.raw: kw.setdefault('raw', True) if self.thread: kw.setdefault('thread', True) # The heart of the matter try: response = yield self.ap.callRemote(RunTask, **kw) except: response = {'status': 'd', 'result': None} #----------------------------------------------------------- # One less task running now self.ds.release() # Process the response. No lock problems even if that # involves further remote calls, i.e., GetNext status = response['status'] x = response['result'] if status == 'i': # What we get from the subordinate is an ID to an iterator # it is holding onto, but we need to give the task an # iterationProducer that hooks up to it. pf = iteration.Prefetcherator(x) ok = yield pf.setup(self.next, x) if ok: returnThis = iteration.Deferator(pf) if consumer: returnThis = iteration.IterationProducer( returnThis, consumer) else: # The subordinate returned an iterator, but it's not # one I could prefetch from. Probably empty. returnThis = [] result(returnThis) elif status == 'c': # Chunked result, which will take a while dResult = yield self.assembleChunkedResult(x) result(dResult) elif status == 'r': result(p2o(x)) elif status == 'n': result(None) elif status in ('e', 'd'): result(x) self.resign() else: raise ValueError("Unknown status {}".format(status))
def gotResponse(response): self.assertEqual(response['status'], 'r') resultList.append(float(p2o(response['result'])))