def _GetPromiseAndFunctions(): functions = {} def GeneratorFunction(resolve, reject): functions['resolve'] = resolve functions['reject'] = reject p = promise.Promise(GeneratorFunction) return (p, functions['resolve'], functions['reject'])
def testGeneratorFunctionResolveToPromise(self): (p1, resolve, _) = _GetPromiseAndFunctions() p2 = promise.Promise(lambda x, y: x(p1)) self.assertEquals(p2.state, promise.Promise.STATE_PENDING) p2.Then(self._AddToAccumulated) resolve(promise.Promise.Resolve(0)) self.assertEquals(self.accumulated, [0])
def CopyFromDataPipe(data_pipe, deadline): """ Returns a Promise that operates as follows: - If |data_pipe| is successfully read from, the promise resolves with the bytes that were read. - Otherwise, the promise rejects with an exception whose message contains the status from the attempted read. """ class DataPipeCopyHelper(): def __init__(self, data_pipe, deadline, resolve, reject): self.data_pipe = data_pipe self.original_deadline = deadline self.start_time = mojo_system.GetTimeTicksNow() self.resolve = resolve self.reject = reject self.buffer_size = 1024 self.data = bytearray(self.buffer_size) self.index = 0 def _ComputeCurrentDeadline(self): if self.original_deadline == mojo_system.DEADLINE_INDEFINITE: return self.original_deadline elapsed_time = mojo_system.GetTimeTicksNow() - self.start_time return max(0, self.original_deadline - elapsed_time) def CopyFromDataPipeAsync(self, result): while result == mojo_system.RESULT_OK: assert self.index <= len(self.data) if self.index == len(self.data): self.buffer_size *= 2 self.data.extend(itertools.repeat(0, self.buffer_size)) # Careful! Have to construct a memoryview object here as otherwise the # slice operation will create a copy of |data| and hence not write into # |data| as desired. result, read_bytes = self.data_pipe.ReadData( memoryview(self.data)[self.index:]) if read_bytes: self.index += len(read_bytes) del read_bytes if result == mojo_system.RESULT_SHOULD_WAIT: data_pipe.AsyncWait(mojo_system.HANDLE_SIGNAL_READABLE, self._ComputeCurrentDeadline(), self.CopyFromDataPipeAsync) return # Treat a failed precondition as EOF. if result == mojo_system.RESULT_FAILED_PRECONDITION: self.resolve(self.data[:self.index]) return self.reject(DataPipeCopyException("Result: %d" % result)) def GenerationMethod(resolve, reject): helper = DataPipeCopyHelper(data_pipe, deadline, resolve, reject) helper.CopyFromDataPipeAsync(mojo_system.RESULT_OK) return promise.Promise(GenerationMethod)
def _Call(self, *args, **kwargs): def GenerationMethod(resolve, reject): message = _GetMessage(method, flags, None, *args, **kwargs) if method.response_struct: def Accept(message): try: assert message.header.message_type == method.ordinal payload = message.payload response = method.response_struct.Deserialize( serialization.RootDeserializationContext( payload.data, payload.handles)) as_dict = response.AsDict() if len(as_dict) == 1: value = as_dict.values()[0] if not isinstance(value, dict): response = value resolve(response) return True except Exception as e: # Adding traceback similarly to python 3.0 (pep-3134) e.__traceback__ = sys.exc_info()[2] reject(e) return False finally: self._error_handler.RemoveCallback(reject) self._error_handler.AddCallback(reject) if not self._router.AcceptWithResponder( message, messaging.ForwardingMessageReceiver(Accept)): self._error_handler.RemoveCallback(reject) reject( messaging.MessagingException( "Unable to send message.")) else: if (self._router.Accept(message)): resolve(None) else: reject( messaging.MessagingException( "Unable to send message.")) return promise.Promise(GenerationMethod)