def _ProcessIncomingData(self): """Process the received data.""" while True: if not self._expected_size: # this is a new msg raw_header = self._GrabData(4) if not raw_header: # not enough data yet return header = struct.unpack('=L', raw_header)[0] version, size = self._DecodeHeader(header) if version != self.PROTOCOL_VERSION: ola_logger.warning('Protocol mismatch: %d != %d', version, self.PROTOCOL_VERSION) self._skip_message = True self._expected_size = size data = self._GrabData(self._expected_size) if not data: # not enough data yet return if not self._skip_message: self._HandleNewMessage(data) self._expected_size = 0 self._skip_message = 0
def CallMethod(self, method, controller, request, response_pb, done): """Call a method. Don't use this directly, use the Stub object. Args: method: The MethodDescriptor to call controller: An RpcController object request: The request message response: The response class done: A closure to call once complete. """ message = Rpc_pb2.RpcMessage() message.type = Rpc_pb2.REQUEST message.id = self._sequence message.name = method.name message.buffer = request.SerializeToString() self._SendMessage(message) self._sequence += 1 if message.id in self._outstanding_responses: # fail any outstanding response with the same id, not the best approach # but it'll do for now. ola_logger.warning('Response %d already pending, failing now', message.id) response = self._outstanding_responses[message.id] response.controller.SetFailed('Duplicate request found') self._InvokeCallback(response) response = OutstandingResponse(message.id, controller, done, response_pb) self._outstanding_responses[message.id] = response
def _HandleNotImplemented(self, message): """Handle a Not Implemented message. Args: message: The RpcMessage object. """ ola_logger.warning('Received a non-implemented response') response = self._outstanding_responses.get(message.id, None) if response: response.controller.SetFailed('Not Implemented') self._InvokeCallback(response)
def _HandleNewMessage(self, data): """Handle a new Message. Args: data: A chunk of data representing a RpcMessage """ message = Rpc_pb2.RpcMessage() message.ParseFromString(data) if message.type in self.MESSAGE_HANDLERS: self.MESSAGE_HANDLERS[message.type](self, message) else: ola_logger.warning('Not sure of message type %d', message.type())
def _SendMessage(self, message): """Send an RpcMessage. Args: message: An RpcMessage object. Returns: True if the send succeeded, False otherwise. """ data = message.SerializeToString() # combine into one buffer to send so we avoid sending two packets data = self._EncodeHeader(len(data)) + data sent_bytes = self._socket.send(data) if sent_bytes != len(data): ola_logger.warning('Failed to send full datagram') return False return True
def _SendMessage(self, message): """Send an RpcMessage. Args: message: An RpcMessage object. Returns: True if the send succeeded, False otherwise. """ data = message.SerializeToString() # combine into one buffer to send so we avoid sending two packets data = self._EncodeHeader(len(data)) + data # this log is useful for building mock regression tests if self._log_msgs: logging.debug("send->" + str(binascii.hexlify(data))) sent_bytes = self._socket.send(data) if sent_bytes != len(data): ola_logger.warning('Failed to send full datagram') return False return True
def _HandleRequest(self, message): """Handle a Request message. Args: message: The RpcMessage object. """ if not self._service: ola_logger.warning('No service registered') return descriptor = self._service.GetDescriptor() method = descriptor.FindMethodByName(message.name) if not method: ola_logger.warning('Failed to get method descriptor for %s', message.name) self._SendNotImplemented(message.id) return request_pb = self._service.GetRequestClass(method)() request_pb.ParseFromString(message.buffer) controller = SimpleRpcController() request = OutstandingRequest(message.id, controller) if message.id in self._outstanding_requests: ola_logger.warning('Duplicate request for %d', message.id) self._SendRequestFailed(message.id) self._outstanding_requests[message.id] = request self._service.CallMethod(method, request.controller, request_pb, lambda x: self.RequestComplete(request, x))