def _status(termination_kind, code, details): effective_details = b'' if details is None else details if code is None: effective_code = _TERMINATION_KIND_TO_CODE[termination_kind] else: effective_code = code return _intermediary_low.Status(effective_code, effective_details)
def _status(termination_kind, high_code, details): low_details = b'' if details is None else details if high_code is None: low_code = _TERMINATION_KIND_TO_CODE[termination_kind] else: low_code = _constants.HIGH_STATUS_CODE_TO_LOW_STATUS_CODE[high_code] return _intermediary_low.Status(low_code, low_details)
def add_ticket(self, ticket): with self._lock: if self._server is None: return call = ticket.operation_id rpc_state = self._rpc_states.get(call) if rpc_state is None: return if ticket.initial_metadata is not None: _metadatafy(call, ticket.initial_metadata) call.premetadata() rpc_state.premetadataed = True elif not rpc_state.premetadataed: if (ticket.terminal_metadata is not None or ticket.payload is not None or ticket.termination is links.Ticket.Termination.COMPLETION or ticket.code is not None or ticket.message is not None): call.premetadata() rpc_state.premetadataed = True if ticket.allowance is not None: if rpc_state.read is _Read.AWAITING_ALLOWANCE: rpc_state.allowance += ticket.allowance - 1 call.read(call) rpc_state.read = _Read.READING else: rpc_state.allowance += ticket.allowance if ticket.payload is not None: call.write(rpc_state.response_serializer(ticket.payload), call) rpc_state.low_write = _LowWrite.ACTIVE if ticket.terminal_metadata is not None: rpc_state.terminal_metadata = ticket.terminal_metadata if ticket.code is not None: rpc_state.code = ticket.code if ticket.message is not None: rpc_state.message = ticket.message if ticket.termination is links.Ticket.Termination.COMPLETION: rpc_state.high_write = _HighWrite.CLOSED if rpc_state.low_write is _LowWrite.OPEN: if rpc_state.terminal_metadata is not None: _metadatafy(call, rpc_state.terminal_metadata) status = _intermediary_low.Status( _intermediary_low.Code.OK if rpc_state.code is None else rpc_state.code, '' if rpc_state.message is None else rpc_state.message) call.status(status, call) rpc_state.low_write = _LowWrite.CLOSED elif ticket.termination is not None: call.cancel() self._rpc_states.pop(call, None)
def _on_write_event(self, event): call = event.tag rpc_state = self._rpc_states.get(call, None) if rpc_state is None: return if rpc_state.high_write is _HighWrite.CLOSED: if rpc_state.terminal_metadata is not None: _metadatafy(call, rpc_state.terminal_metadata) call.status( _intermediary_low.Status(rpc_state.code, rpc_state.message), call) rpc_state.low_write = _LowWrite.CLOSED else: ticket = links.Ticket(call, rpc_state.sequence_number, None, None, None, None, 1, None, None, None, None, None, None, None) rpc_state.sequence_number += 1 self._relay.add_value(ticket) rpc_state.low_write = _LowWrite.OPEN
def testCancellation(self): method = 'test method' deadline = _FUTURE metadata_tag = object() finish_tag = object() write_tag = object() service_tag = object() read_tag = object() test_data = _BYTE_SEQUENCE_SEQUENCE server_data = [] client_data = [] client_call = _low.Call(self.channel, self.client_completion_queue, method, self.host, deadline) client_call.invoke(self.client_completion_queue, metadata_tag, finish_tag) self.server.service(service_tag) service_accepted = self.server_events.get() server_call = service_accepted.service_acceptance.call server_call.accept(self.server_completion_queue, finish_tag) server_call.premetadata() metadata_accepted = self.client_events.get() self.assertIsNotNone(metadata_accepted) for datum in test_data: client_call.write(datum, write_tag, 0) write_accepted = self.client_events.get() server_call.read(read_tag) read_accepted = self.server_events.get() server_data.append(read_accepted.bytes) server_call.write(read_accepted.bytes, write_tag, 0) write_accepted = self.server_events.get() self.assertIsNotNone(write_accepted) client_call.read(read_tag) read_accepted = self.client_events.get() client_data.append(read_accepted.bytes) client_call.cancel() # cancel() is idempotent. client_call.cancel() client_call.cancel() client_call.cancel() server_call.read(read_tag) server_terminal_event_one = self.server_events.get() server_terminal_event_two = self.server_events.get() if server_terminal_event_one.kind == _low.Event.Kind.READ_ACCEPTED: read_accepted = server_terminal_event_one rpc_accepted = server_terminal_event_two else: read_accepted = server_terminal_event_two rpc_accepted = server_terminal_event_one self.assertIsNotNone(read_accepted) self.assertIsNotNone(rpc_accepted) self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind) self.assertIsNone(read_accepted.bytes) self.assertEqual(_low.Event.Kind.FINISH, rpc_accepted.kind) self.assertEqual(_low.Status(_low.Code.CANCELLED, ''), rpc_accepted.status) finish_event = self.client_events.get() self.assertEqual(_low.Event.Kind.FINISH, finish_event.kind) self.assertEqual(_low.Status(_low.Code.CANCELLED, 'Cancelled'), finish_event.status) self.assertSequenceEqual(test_data, server_data) self.assertSequenceEqual(test_data, client_data)
def _perform_echo_test(self, test_data): method = 'test method' details = 'test details' server_leading_metadata_key = 'my_server_leading_key' server_leading_metadata_value = 'my_server_leading_value' server_trailing_metadata_key = 'my_server_trailing_key' server_trailing_metadata_value = 'my_server_trailing_value' client_metadata_key = 'my_client_key' client_metadata_value = 'my_client_value' server_leading_binary_metadata_key = 'my_server_leading_key-bin' server_leading_binary_metadata_value = b'\0'*2047 server_trailing_binary_metadata_key = 'my_server_trailing_key-bin' server_trailing_binary_metadata_value = b'\0'*2047 client_binary_metadata_key = 'my_client_key-bin' client_binary_metadata_value = b'\0'*2047 deadline = _FUTURE metadata_tag = object() finish_tag = object() write_tag = object() complete_tag = object() service_tag = object() read_tag = object() status_tag = object() server_data = [] client_data = [] client_call = _low.Call(self.channel, self.client_completion_queue, method, self.host, deadline) client_call.add_metadata(client_metadata_key, client_metadata_value) client_call.add_metadata(client_binary_metadata_key, client_binary_metadata_value) client_call.invoke(self.client_completion_queue, metadata_tag, finish_tag) self.server.service(service_tag) service_accepted = self.server_events.get() self.assertIsNotNone(service_accepted) self.assertIs(service_accepted.kind, _low.Event.Kind.SERVICE_ACCEPTED) self.assertIs(service_accepted.tag, service_tag) self.assertEqual(method, service_accepted.service_acceptance.method) self.assertEqual(self.host, service_accepted.service_acceptance.host) self.assertIsNotNone(service_accepted.service_acceptance.call) metadata = dict(service_accepted.metadata) self.assertIn(client_metadata_key, metadata) self.assertEqual(client_metadata_value, metadata[client_metadata_key]) self.assertIn(client_binary_metadata_key, metadata) self.assertEqual(client_binary_metadata_value, metadata[client_binary_metadata_key]) server_call = service_accepted.service_acceptance.call server_call.accept(self.server_completion_queue, finish_tag) server_call.add_metadata(server_leading_metadata_key, server_leading_metadata_value) server_call.add_metadata(server_leading_binary_metadata_key, server_leading_binary_metadata_value) server_call.premetadata() metadata_accepted = self.client_events.get() self.assertIsNotNone(metadata_accepted) self.assertEqual(_low.Event.Kind.METADATA_ACCEPTED, metadata_accepted.kind) self.assertEqual(metadata_tag, metadata_accepted.tag) metadata = dict(metadata_accepted.metadata) self.assertIn(server_leading_metadata_key, metadata) self.assertEqual(server_leading_metadata_value, metadata[server_leading_metadata_key]) self.assertIn(server_leading_binary_metadata_key, metadata) self.assertEqual(server_leading_binary_metadata_value, metadata[server_leading_binary_metadata_key]) for datum in test_data: client_call.write(datum, write_tag, _low.WriteFlags.WRITE_NO_COMPRESS) write_accepted = self.client_events.get() self.assertIsNotNone(write_accepted) self.assertIs(write_accepted.kind, _low.Event.Kind.WRITE_ACCEPTED) self.assertIs(write_accepted.tag, write_tag) self.assertIs(write_accepted.write_accepted, True) server_call.read(read_tag) read_accepted = self.server_events.get() self.assertIsNotNone(read_accepted) self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind) self.assertEqual(read_tag, read_accepted.tag) self.assertIsNotNone(read_accepted.bytes) server_data.append(read_accepted.bytes) server_call.write(read_accepted.bytes, write_tag, 0) write_accepted = self.server_events.get() self.assertIsNotNone(write_accepted) self.assertEqual(_low.Event.Kind.WRITE_ACCEPTED, write_accepted.kind) self.assertEqual(write_tag, write_accepted.tag) self.assertTrue(write_accepted.write_accepted) client_call.read(read_tag) read_accepted = self.client_events.get() self.assertIsNotNone(read_accepted) self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind) self.assertEqual(read_tag, read_accepted.tag) self.assertIsNotNone(read_accepted.bytes) client_data.append(read_accepted.bytes) client_call.complete(complete_tag) complete_accepted = self.client_events.get() self.assertIsNotNone(complete_accepted) self.assertIs(complete_accepted.kind, _low.Event.Kind.COMPLETE_ACCEPTED) self.assertIs(complete_accepted.tag, complete_tag) self.assertIs(complete_accepted.complete_accepted, True) server_call.read(read_tag) read_accepted = self.server_events.get() self.assertIsNotNone(read_accepted) self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind) self.assertEqual(read_tag, read_accepted.tag) self.assertIsNone(read_accepted.bytes) server_call.add_metadata(server_trailing_metadata_key, server_trailing_metadata_value) server_call.add_metadata(server_trailing_binary_metadata_key, server_trailing_binary_metadata_value) server_call.status(_low.Status(_low.Code.OK, details), status_tag) server_terminal_event_one = self.server_events.get() server_terminal_event_two = self.server_events.get() if server_terminal_event_one.kind == _low.Event.Kind.COMPLETE_ACCEPTED: status_accepted = server_terminal_event_one rpc_accepted = server_terminal_event_two else: status_accepted = server_terminal_event_two rpc_accepted = server_terminal_event_one self.assertIsNotNone(status_accepted) self.assertIsNotNone(rpc_accepted) self.assertEqual(_low.Event.Kind.COMPLETE_ACCEPTED, status_accepted.kind) self.assertEqual(status_tag, status_accepted.tag) self.assertTrue(status_accepted.complete_accepted) self.assertEqual(_low.Event.Kind.FINISH, rpc_accepted.kind) self.assertEqual(finish_tag, rpc_accepted.tag) self.assertEqual(_low.Status(_low.Code.OK, ''), rpc_accepted.status) client_call.read(read_tag) client_terminal_event_one = self.client_events.get() client_terminal_event_two = self.client_events.get() if client_terminal_event_one.kind == _low.Event.Kind.READ_ACCEPTED: read_accepted = client_terminal_event_one finish_accepted = client_terminal_event_two else: read_accepted = client_terminal_event_two finish_accepted = client_terminal_event_one self.assertIsNotNone(read_accepted) self.assertIsNotNone(finish_accepted) self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind) self.assertEqual(read_tag, read_accepted.tag) self.assertIsNone(read_accepted.bytes) self.assertEqual(_low.Event.Kind.FINISH, finish_accepted.kind) self.assertEqual(finish_tag, finish_accepted.tag) self.assertEqual(_low.Status(_low.Code.OK, details), finish_accepted.status) metadata = dict(finish_accepted.metadata) self.assertIn(server_trailing_metadata_key, metadata) self.assertEqual(server_trailing_metadata_value, metadata[server_trailing_metadata_key]) self.assertIn(server_trailing_binary_metadata_key, metadata) self.assertEqual(server_trailing_binary_metadata_value, metadata[server_trailing_binary_metadata_key]) self.assertSetEqual(set(key for key, _ in finish_accepted.metadata), set((server_trailing_metadata_key, server_trailing_binary_metadata_key,))) self.assertSequenceEqual(test_data, server_data) self.assertSequenceEqual(test_data, client_data)
def add_ticket(self, ticket): with self._lock: if self._server is None: return call = ticket.operation_id rpc_state = self._rpc_states.get(call) if rpc_state is None: return if ticket.initial_metadata is not None: _metadatafy(call, ticket.initial_metadata) call.premetadata() rpc_state.premetadataed = True elif not rpc_state.premetadataed: if (ticket.terminal_metadata is not None or ticket.payload is not None or ticket.termination is not None or ticket.code is not None or ticket.message is not None): call.premetadata() rpc_state.premetadataed = True if ticket.allowance is not None: if rpc_state.early_read is None: rpc_state.allowance += ticket.allowance else: payload = rpc_state.request_deserializer( rpc_state.early_read) rpc_state.allowance += ticket.allowance - 1 rpc_state.early_read = None if rpc_state.read is _Read.READING: call.read(call) termination = None else: termination = links.Ticket.Termination.COMPLETION early_read_ticket = links.Ticket(call, rpc_state.sequence_number, None, None, None, None, None, None, payload, None, None, None, termination, None) rpc_state.sequence_number += 1 self._relay.add_value(early_read_ticket) if ticket.payload is not None: call.write(rpc_state.response_serializer(ticket.payload), call) rpc_state.low_write = _LowWrite.ACTIVE if ticket.terminal_metadata is not None: rpc_state.terminal_metadata = ticket.terminal_metadata if ticket.code is not None: rpc_state.code = ticket.code if ticket.message is not None: rpc_state.message = ticket.message if ticket.termination is links.Ticket.Termination.COMPLETION: rpc_state.high_write = _HighWrite.CLOSED if rpc_state.low_write is _LowWrite.OPEN: if rpc_state.terminal_metadata is not None: _metadatafy(call, rpc_state.terminal_metadata) status = _intermediary_low.Status( _intermediary_low.Code.OK if rpc_state.code is None else rpc_state.code, '' if rpc_state.message is None else rpc_state.message) call.status(status, call) rpc_state.low_write = _LowWrite.CLOSED elif ticket.termination is not None: call.cancel() self._rpc_states.pop(call, None)
def _status(call, rpc_state): call.status(_low.Status(_low.Code.OK, ''), call) rpc_state.write.low = _LowWrite.CLOSED