|
|
@ -27,7 +27,7 @@ |
|
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
|
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
|
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
|
|
|
|
|
|
|
|
|
|
"""State and behavior for packet transmission during an operation.""" |
|
|
|
"""State and behavior for ticket transmission during an operation.""" |
|
|
|
|
|
|
|
|
|
|
|
import abc |
|
|
|
import abc |
|
|
|
|
|
|
|
|
|
|
@ -46,53 +46,53 @@ _BACK_TO_FRONT_NO_TRANSMISSION_OUTCOMES = ( |
|
|
|
interfaces.Outcome.SERVICED_FAILURE, |
|
|
|
interfaces.Outcome.SERVICED_FAILURE, |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
_ABORTION_OUTCOME_TO_FRONT_TO_BACK_PACKET_KIND = { |
|
|
|
_ABORTION_OUTCOME_TO_FRONT_TO_BACK_TICKET_KIND = { |
|
|
|
interfaces.Outcome.CANCELLED: |
|
|
|
interfaces.Outcome.CANCELLED: |
|
|
|
interfaces.FrontToBackPacket.Kind.CANCELLATION, |
|
|
|
interfaces.FrontToBackTicket.Kind.CANCELLATION, |
|
|
|
interfaces.Outcome.EXPIRED: |
|
|
|
interfaces.Outcome.EXPIRED: |
|
|
|
interfaces.FrontToBackPacket.Kind.EXPIRATION, |
|
|
|
interfaces.FrontToBackTicket.Kind.EXPIRATION, |
|
|
|
interfaces.Outcome.RECEPTION_FAILURE: |
|
|
|
interfaces.Outcome.RECEPTION_FAILURE: |
|
|
|
interfaces.FrontToBackPacket.Kind.RECEPTION_FAILURE, |
|
|
|
interfaces.FrontToBackTicket.Kind.RECEPTION_FAILURE, |
|
|
|
interfaces.Outcome.TRANSMISSION_FAILURE: |
|
|
|
interfaces.Outcome.TRANSMISSION_FAILURE: |
|
|
|
interfaces.FrontToBackPacket.Kind.TRANSMISSION_FAILURE, |
|
|
|
interfaces.FrontToBackTicket.Kind.TRANSMISSION_FAILURE, |
|
|
|
interfaces.Outcome.SERVICED_FAILURE: |
|
|
|
interfaces.Outcome.SERVICED_FAILURE: |
|
|
|
interfaces.FrontToBackPacket.Kind.SERVICED_FAILURE, |
|
|
|
interfaces.FrontToBackTicket.Kind.SERVICED_FAILURE, |
|
|
|
interfaces.Outcome.SERVICER_FAILURE: |
|
|
|
interfaces.Outcome.SERVICER_FAILURE: |
|
|
|
interfaces.FrontToBackPacket.Kind.SERVICER_FAILURE, |
|
|
|
interfaces.FrontToBackTicket.Kind.SERVICER_FAILURE, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_ABORTION_OUTCOME_TO_BACK_TO_FRONT_PACKET_KIND = { |
|
|
|
_ABORTION_OUTCOME_TO_BACK_TO_FRONT_TICKET_KIND = { |
|
|
|
interfaces.Outcome.CANCELLED: |
|
|
|
interfaces.Outcome.CANCELLED: |
|
|
|
interfaces.BackToFrontPacket.Kind.CANCELLATION, |
|
|
|
interfaces.BackToFrontTicket.Kind.CANCELLATION, |
|
|
|
interfaces.Outcome.EXPIRED: |
|
|
|
interfaces.Outcome.EXPIRED: |
|
|
|
interfaces.BackToFrontPacket.Kind.EXPIRATION, |
|
|
|
interfaces.BackToFrontTicket.Kind.EXPIRATION, |
|
|
|
interfaces.Outcome.RECEPTION_FAILURE: |
|
|
|
interfaces.Outcome.RECEPTION_FAILURE: |
|
|
|
interfaces.BackToFrontPacket.Kind.RECEPTION_FAILURE, |
|
|
|
interfaces.BackToFrontTicket.Kind.RECEPTION_FAILURE, |
|
|
|
interfaces.Outcome.TRANSMISSION_FAILURE: |
|
|
|
interfaces.Outcome.TRANSMISSION_FAILURE: |
|
|
|
interfaces.BackToFrontPacket.Kind.TRANSMISSION_FAILURE, |
|
|
|
interfaces.BackToFrontTicket.Kind.TRANSMISSION_FAILURE, |
|
|
|
interfaces.Outcome.SERVICED_FAILURE: |
|
|
|
interfaces.Outcome.SERVICED_FAILURE: |
|
|
|
interfaces.BackToFrontPacket.Kind.SERVICED_FAILURE, |
|
|
|
interfaces.BackToFrontTicket.Kind.SERVICED_FAILURE, |
|
|
|
interfaces.Outcome.SERVICER_FAILURE: |
|
|
|
interfaces.Outcome.SERVICER_FAILURE: |
|
|
|
interfaces.BackToFrontPacket.Kind.SERVICER_FAILURE, |
|
|
|
interfaces.BackToFrontTicket.Kind.SERVICER_FAILURE, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class _Packetizer(object): |
|
|
|
class _Ticketizer(object): |
|
|
|
"""Common specification of different packet-creating behavior.""" |
|
|
|
"""Common specification of different ticket-creating behavior.""" |
|
|
|
__metaclass__ = abc.ABCMeta |
|
|
|
__metaclass__ = abc.ABCMeta |
|
|
|
|
|
|
|
|
|
|
|
@abc.abstractmethod |
|
|
|
@abc.abstractmethod |
|
|
|
def packetize(self, operation_id, sequence_number, payload, complete): |
|
|
|
def ticketize(self, operation_id, sequence_number, payload, complete): |
|
|
|
"""Creates a packet indicating ordinary operation progress. |
|
|
|
"""Creates a ticket indicating ordinary operation progress. |
|
|
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
Args: |
|
|
|
operation_id: The operation ID for the current operation. |
|
|
|
operation_id: The operation ID for the current operation. |
|
|
|
sequence_number: A sequence number for the packet. |
|
|
|
sequence_number: A sequence number for the ticket. |
|
|
|
payload: A customer payload object. May be None if sequence_number is |
|
|
|
payload: A customer payload object. May be None if sequence_number is |
|
|
|
zero or complete is true. |
|
|
|
zero or complete is true. |
|
|
|
complete: A boolean indicating whether or not the packet should describe |
|
|
|
complete: A boolean indicating whether or not the ticket should describe |
|
|
|
itself as (but for a later indication of operation abortion) the last |
|
|
|
itself as (but for a later indication of operation abortion) the last |
|
|
|
packet to be sent. |
|
|
|
ticket to be sent. |
|
|
|
|
|
|
|
|
|
|
|
Returns: |
|
|
|
Returns: |
|
|
|
An object of an appropriate type suitable for transmission to the other |
|
|
|
An object of an appropriate type suitable for transmission to the other |
|
|
@ -101,12 +101,12 @@ class _Packetizer(object): |
|
|
|
raise NotImplementedError() |
|
|
|
raise NotImplementedError() |
|
|
|
|
|
|
|
|
|
|
|
@abc.abstractmethod |
|
|
|
@abc.abstractmethod |
|
|
|
def packetize_abortion(self, operation_id, sequence_number, outcome): |
|
|
|
def ticketize_abortion(self, operation_id, sequence_number, outcome): |
|
|
|
"""Creates a packet indicating that the operation is aborted. |
|
|
|
"""Creates a ticket indicating that the operation is aborted. |
|
|
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
Args: |
|
|
|
operation_id: The operation ID for the current operation. |
|
|
|
operation_id: The operation ID for the current operation. |
|
|
|
sequence_number: A sequence number for the packet. |
|
|
|
sequence_number: A sequence number for the ticket. |
|
|
|
outcome: An interfaces.Outcome value describing the operation abortion. |
|
|
|
outcome: An interfaces.Outcome value describing the operation abortion. |
|
|
|
|
|
|
|
|
|
|
|
Returns: |
|
|
|
Returns: |
|
|
@ -117,8 +117,8 @@ class _Packetizer(object): |
|
|
|
raise NotImplementedError() |
|
|
|
raise NotImplementedError() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class _FrontPacketizer(_Packetizer): |
|
|
|
class _FrontTicketizer(_Ticketizer): |
|
|
|
"""Front-side packet-creating behavior.""" |
|
|
|
"""Front-side ticket-creating behavior.""" |
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, name, subscription_kind, trace_id, timeout): |
|
|
|
def __init__(self, name, subscription_kind, trace_id, timeout): |
|
|
|
"""Constructor. |
|
|
|
"""Constructor. |
|
|
@ -126,7 +126,7 @@ class _FrontPacketizer(_Packetizer): |
|
|
|
Args: |
|
|
|
Args: |
|
|
|
name: The name of the operation. |
|
|
|
name: The name of the operation. |
|
|
|
subscription_kind: An interfaces.ServicedSubscription.Kind value |
|
|
|
subscription_kind: An interfaces.ServicedSubscription.Kind value |
|
|
|
describing the interest the front has in packets sent from the back. |
|
|
|
describing the interest the front has in tickets sent from the back. |
|
|
|
trace_id: A uuid.UUID identifying a set of related operations to which |
|
|
|
trace_id: A uuid.UUID identifying a set of related operations to which |
|
|
|
this operation belongs. |
|
|
|
this operation belongs. |
|
|
|
timeout: A length of time in seconds to allow for the entire operation. |
|
|
|
timeout: A length of time in seconds to allow for the entire operation. |
|
|
@ -136,54 +136,54 @@ class _FrontPacketizer(_Packetizer): |
|
|
|
self._trace_id = trace_id |
|
|
|
self._trace_id = trace_id |
|
|
|
self._timeout = timeout |
|
|
|
self._timeout = timeout |
|
|
|
|
|
|
|
|
|
|
|
def packetize(self, operation_id, sequence_number, payload, complete): |
|
|
|
def ticketize(self, operation_id, sequence_number, payload, complete): |
|
|
|
"""See _Packetizer.packetize for specification.""" |
|
|
|
"""See _Ticketizer.ticketize for specification.""" |
|
|
|
if sequence_number: |
|
|
|
if sequence_number: |
|
|
|
if complete: |
|
|
|
if complete: |
|
|
|
kind = interfaces.FrontToBackPacket.Kind.COMPLETION |
|
|
|
kind = interfaces.FrontToBackTicket.Kind.COMPLETION |
|
|
|
else: |
|
|
|
else: |
|
|
|
kind = interfaces.FrontToBackPacket.Kind.CONTINUATION |
|
|
|
kind = interfaces.FrontToBackTicket.Kind.CONTINUATION |
|
|
|
return interfaces.FrontToBackPacket( |
|
|
|
return interfaces.FrontToBackTicket( |
|
|
|
operation_id, sequence_number, kind, self._name, |
|
|
|
operation_id, sequence_number, kind, self._name, |
|
|
|
self._subscription_kind, self._trace_id, payload, self._timeout) |
|
|
|
self._subscription_kind, self._trace_id, payload, self._timeout) |
|
|
|
else: |
|
|
|
else: |
|
|
|
if complete: |
|
|
|
if complete: |
|
|
|
kind = interfaces.FrontToBackPacket.Kind.ENTIRE |
|
|
|
kind = interfaces.FrontToBackTicket.Kind.ENTIRE |
|
|
|
else: |
|
|
|
else: |
|
|
|
kind = interfaces.FrontToBackPacket.Kind.COMMENCEMENT |
|
|
|
kind = interfaces.FrontToBackTicket.Kind.COMMENCEMENT |
|
|
|
return interfaces.FrontToBackPacket( |
|
|
|
return interfaces.FrontToBackTicket( |
|
|
|
operation_id, 0, kind, self._name, self._subscription_kind, |
|
|
|
operation_id, 0, kind, self._name, self._subscription_kind, |
|
|
|
self._trace_id, payload, self._timeout) |
|
|
|
self._trace_id, payload, self._timeout) |
|
|
|
|
|
|
|
|
|
|
|
def packetize_abortion(self, operation_id, sequence_number, outcome): |
|
|
|
def ticketize_abortion(self, operation_id, sequence_number, outcome): |
|
|
|
"""See _Packetizer.packetize_abortion for specification.""" |
|
|
|
"""See _Ticketizer.ticketize_abortion for specification.""" |
|
|
|
if outcome in _FRONT_TO_BACK_NO_TRANSMISSION_OUTCOMES: |
|
|
|
if outcome in _FRONT_TO_BACK_NO_TRANSMISSION_OUTCOMES: |
|
|
|
return None |
|
|
|
return None |
|
|
|
else: |
|
|
|
else: |
|
|
|
kind = _ABORTION_OUTCOME_TO_FRONT_TO_BACK_PACKET_KIND[outcome] |
|
|
|
kind = _ABORTION_OUTCOME_TO_FRONT_TO_BACK_TICKET_KIND[outcome] |
|
|
|
return interfaces.FrontToBackPacket( |
|
|
|
return interfaces.FrontToBackTicket( |
|
|
|
operation_id, sequence_number, kind, None, None, None, None, None) |
|
|
|
operation_id, sequence_number, kind, None, None, None, None, None) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class _BackPacketizer(_Packetizer): |
|
|
|
class _BackTicketizer(_Ticketizer): |
|
|
|
"""Back-side packet-creating behavior.""" |
|
|
|
"""Back-side ticket-creating behavior.""" |
|
|
|
|
|
|
|
|
|
|
|
def packetize(self, operation_id, sequence_number, payload, complete): |
|
|
|
def ticketize(self, operation_id, sequence_number, payload, complete): |
|
|
|
"""See _Packetizer.packetize for specification.""" |
|
|
|
"""See _Ticketizer.ticketize for specification.""" |
|
|
|
if complete: |
|
|
|
if complete: |
|
|
|
kind = interfaces.BackToFrontPacket.Kind.COMPLETION |
|
|
|
kind = interfaces.BackToFrontTicket.Kind.COMPLETION |
|
|
|
else: |
|
|
|
else: |
|
|
|
kind = interfaces.BackToFrontPacket.Kind.CONTINUATION |
|
|
|
kind = interfaces.BackToFrontTicket.Kind.CONTINUATION |
|
|
|
return interfaces.BackToFrontPacket( |
|
|
|
return interfaces.BackToFrontTicket( |
|
|
|
operation_id, sequence_number, kind, payload) |
|
|
|
operation_id, sequence_number, kind, payload) |
|
|
|
|
|
|
|
|
|
|
|
def packetize_abortion(self, operation_id, sequence_number, outcome): |
|
|
|
def ticketize_abortion(self, operation_id, sequence_number, outcome): |
|
|
|
"""See _Packetizer.packetize_abortion for specification.""" |
|
|
|
"""See _Ticketizer.ticketize_abortion for specification.""" |
|
|
|
if outcome in _BACK_TO_FRONT_NO_TRANSMISSION_OUTCOMES: |
|
|
|
if outcome in _BACK_TO_FRONT_NO_TRANSMISSION_OUTCOMES: |
|
|
|
return None |
|
|
|
return None |
|
|
|
else: |
|
|
|
else: |
|
|
|
kind = _ABORTION_OUTCOME_TO_BACK_TO_FRONT_PACKET_KIND[outcome] |
|
|
|
kind = _ABORTION_OUTCOME_TO_BACK_TO_FRONT_TICKET_KIND[outcome] |
|
|
|
return interfaces.BackToFrontPacket( |
|
|
|
return interfaces.BackToFrontTicket( |
|
|
|
operation_id, sequence_number, kind, None) |
|
|
|
operation_id, sequence_number, kind, None) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -220,21 +220,21 @@ class _EmptyTransmissionManager(TransmissionManager): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class _TransmittingTransmissionManager(TransmissionManager): |
|
|
|
class _TransmittingTransmissionManager(TransmissionManager): |
|
|
|
"""A TransmissionManager implementation that sends packets.""" |
|
|
|
"""A TransmissionManager implementation that sends tickets.""" |
|
|
|
|
|
|
|
|
|
|
|
def __init__( |
|
|
|
def __init__( |
|
|
|
self, lock, pool, callback, operation_id, packetizer, |
|
|
|
self, lock, pool, callback, operation_id, ticketizer, |
|
|
|
termination_manager): |
|
|
|
termination_manager): |
|
|
|
"""Constructor. |
|
|
|
"""Constructor. |
|
|
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
Args: |
|
|
|
lock: The operation-servicing-wide lock object. |
|
|
|
lock: The operation-servicing-wide lock object. |
|
|
|
pool: A thread pool in which the work of transmitting packets will be |
|
|
|
pool: A thread pool in which the work of transmitting tickets will be |
|
|
|
performed. |
|
|
|
performed. |
|
|
|
callback: A callable that accepts packets and sends them to the other side |
|
|
|
callback: A callable that accepts tickets and sends them to the other side |
|
|
|
of the operation. |
|
|
|
of the operation. |
|
|
|
operation_id: The operation's ID. |
|
|
|
operation_id: The operation's ID. |
|
|
|
packetizer: A _Packetizer for packet creation. |
|
|
|
ticketizer: A _Ticketizer for ticket creation. |
|
|
|
termination_manager: The _interfaces.TerminationManager associated with |
|
|
|
termination_manager: The _interfaces.TerminationManager associated with |
|
|
|
this operation. |
|
|
|
this operation. |
|
|
|
""" |
|
|
|
""" |
|
|
@ -242,7 +242,7 @@ class _TransmittingTransmissionManager(TransmissionManager): |
|
|
|
self._pool = pool |
|
|
|
self._pool = pool |
|
|
|
self._callback = callback |
|
|
|
self._callback = callback |
|
|
|
self._operation_id = operation_id |
|
|
|
self._operation_id = operation_id |
|
|
|
self._packetizer = packetizer |
|
|
|
self._ticketizer = ticketizer |
|
|
|
self._termination_manager = termination_manager |
|
|
|
self._termination_manager = termination_manager |
|
|
|
self._ingestion_manager = None |
|
|
|
self._ingestion_manager = None |
|
|
|
self._expiration_manager = None |
|
|
|
self._expiration_manager = None |
|
|
@ -259,8 +259,8 @@ class _TransmittingTransmissionManager(TransmissionManager): |
|
|
|
self._ingestion_manager = ingestion_manager |
|
|
|
self._ingestion_manager = ingestion_manager |
|
|
|
self._expiration_manager = expiration_manager |
|
|
|
self._expiration_manager = expiration_manager |
|
|
|
|
|
|
|
|
|
|
|
def _lead_packet(self, emission, complete): |
|
|
|
def _lead_ticket(self, emission, complete): |
|
|
|
"""Creates a packet suitable for leading off the transmission loop. |
|
|
|
"""Creates a ticket suitable for leading off the transmission loop. |
|
|
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
Args: |
|
|
|
emission: A customer payload object to be sent to the other side of the |
|
|
|
emission: A customer payload object to be sent to the other side of the |
|
|
@ -269,37 +269,37 @@ class _TransmittingTransmissionManager(TransmissionManager): |
|
|
|
the passed object. |
|
|
|
the passed object. |
|
|
|
|
|
|
|
|
|
|
|
Returns: |
|
|
|
Returns: |
|
|
|
A packet with which to lead off the transmission loop. |
|
|
|
A ticket with which to lead off the transmission loop. |
|
|
|
""" |
|
|
|
""" |
|
|
|
sequence_number = self._lowest_unused_sequence_number |
|
|
|
sequence_number = self._lowest_unused_sequence_number |
|
|
|
self._lowest_unused_sequence_number += 1 |
|
|
|
self._lowest_unused_sequence_number += 1 |
|
|
|
return self._packetizer.packetize( |
|
|
|
return self._ticketizer.ticketize( |
|
|
|
self._operation_id, sequence_number, emission, complete) |
|
|
|
self._operation_id, sequence_number, emission, complete) |
|
|
|
|
|
|
|
|
|
|
|
def _abortive_response_packet(self, outcome): |
|
|
|
def _abortive_response_ticket(self, outcome): |
|
|
|
"""Creates a packet indicating operation abortion. |
|
|
|
"""Creates a ticket indicating operation abortion. |
|
|
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
Args: |
|
|
|
outcome: An interfaces.Outcome value describing operation abortion. |
|
|
|
outcome: An interfaces.Outcome value describing operation abortion. |
|
|
|
|
|
|
|
|
|
|
|
Returns: |
|
|
|
Returns: |
|
|
|
A packet indicating operation abortion. |
|
|
|
A ticket indicating operation abortion. |
|
|
|
""" |
|
|
|
""" |
|
|
|
packet = self._packetizer.packetize_abortion( |
|
|
|
ticket = self._ticketizer.ticketize_abortion( |
|
|
|
self._operation_id, self._lowest_unused_sequence_number, outcome) |
|
|
|
self._operation_id, self._lowest_unused_sequence_number, outcome) |
|
|
|
if packet is None: |
|
|
|
if ticket is None: |
|
|
|
return None |
|
|
|
return None |
|
|
|
else: |
|
|
|
else: |
|
|
|
self._lowest_unused_sequence_number += 1 |
|
|
|
self._lowest_unused_sequence_number += 1 |
|
|
|
return packet |
|
|
|
return ticket |
|
|
|
|
|
|
|
|
|
|
|
def _next_packet(self): |
|
|
|
def _next_ticket(self): |
|
|
|
"""Creates the next packet to be sent to the other side of the operation. |
|
|
|
"""Creates the next ticket to be sent to the other side of the operation. |
|
|
|
|
|
|
|
|
|
|
|
Returns: |
|
|
|
Returns: |
|
|
|
A (completed, packet) tuple comprised of a boolean indicating whether or |
|
|
|
A (completed, ticket) tuple comprised of a boolean indicating whether or |
|
|
|
not the sequence of packets has completed normally and a packet to send |
|
|
|
not the sequence of tickets has completed normally and a ticket to send |
|
|
|
to the other side if the sequence of packets hasn't completed. The tuple |
|
|
|
to the other side if the sequence of tickets hasn't completed. The tuple |
|
|
|
will never have both a True first element and a non-None second element. |
|
|
|
will never have both a True first element and a non-None second element. |
|
|
|
""" |
|
|
|
""" |
|
|
|
if self._emissions is None: |
|
|
|
if self._emissions is None: |
|
|
@ -310,29 +310,29 @@ class _TransmittingTransmissionManager(TransmissionManager): |
|
|
|
complete = self._emission_complete and not self._emissions |
|
|
|
complete = self._emission_complete and not self._emissions |
|
|
|
sequence_number = self._lowest_unused_sequence_number |
|
|
|
sequence_number = self._lowest_unused_sequence_number |
|
|
|
self._lowest_unused_sequence_number += 1 |
|
|
|
self._lowest_unused_sequence_number += 1 |
|
|
|
return complete, self._packetizer.packetize( |
|
|
|
return complete, self._ticketizer.ticketize( |
|
|
|
self._operation_id, sequence_number, payload, complete) |
|
|
|
self._operation_id, sequence_number, payload, complete) |
|
|
|
else: |
|
|
|
else: |
|
|
|
return self._emission_complete, None |
|
|
|
return self._emission_complete, None |
|
|
|
else: |
|
|
|
else: |
|
|
|
packet = self._abortive_response_packet(self._outcome) |
|
|
|
ticket = self._abortive_response_ticket(self._outcome) |
|
|
|
self._emissions = None |
|
|
|
self._emissions = None |
|
|
|
return False, None if packet is None else packet |
|
|
|
return False, None if ticket is None else ticket |
|
|
|
|
|
|
|
|
|
|
|
def _transmit(self, packet): |
|
|
|
def _transmit(self, ticket): |
|
|
|
"""Commences the transmission loop sending packets. |
|
|
|
"""Commences the transmission loop sending tickets. |
|
|
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
Args: |
|
|
|
packet: A packet to be sent to the other side of the operation. |
|
|
|
ticket: A ticket to be sent to the other side of the operation. |
|
|
|
""" |
|
|
|
""" |
|
|
|
def transmit(packet): |
|
|
|
def transmit(ticket): |
|
|
|
while True: |
|
|
|
while True: |
|
|
|
transmission_outcome = callable_util.call_logging_exceptions( |
|
|
|
transmission_outcome = callable_util.call_logging_exceptions( |
|
|
|
self._callback, _TRANSMISSION_EXCEPTION_LOG_MESSAGE, packet) |
|
|
|
self._callback, _TRANSMISSION_EXCEPTION_LOG_MESSAGE, ticket) |
|
|
|
if transmission_outcome.exception is None: |
|
|
|
if transmission_outcome.exception is None: |
|
|
|
with self._lock: |
|
|
|
with self._lock: |
|
|
|
complete, packet = self._next_packet() |
|
|
|
complete, ticket = self._next_ticket() |
|
|
|
if packet is None: |
|
|
|
if ticket is None: |
|
|
|
if complete: |
|
|
|
if complete: |
|
|
|
self._termination_manager.transmission_complete() |
|
|
|
self._termination_manager.transmission_complete() |
|
|
|
self._transmitting = False |
|
|
|
self._transmitting = False |
|
|
@ -348,7 +348,7 @@ class _TransmittingTransmissionManager(TransmissionManager): |
|
|
|
return |
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
self._pool.submit(callable_util.with_exceptions_logged( |
|
|
|
self._pool.submit(callable_util.with_exceptions_logged( |
|
|
|
transmit, _constants.INTERNAL_ERROR_LOG_MESSAGE), packet) |
|
|
|
transmit, _constants.INTERNAL_ERROR_LOG_MESSAGE), ticket) |
|
|
|
self._transmitting = True |
|
|
|
self._transmitting = True |
|
|
|
|
|
|
|
|
|
|
|
def inmit(self, emission, complete): |
|
|
|
def inmit(self, emission, complete): |
|
|
@ -358,17 +358,17 @@ class _TransmittingTransmissionManager(TransmissionManager): |
|
|
|
if self._transmitting: |
|
|
|
if self._transmitting: |
|
|
|
self._emissions.append(emission) |
|
|
|
self._emissions.append(emission) |
|
|
|
else: |
|
|
|
else: |
|
|
|
self._transmit(self._lead_packet(emission, complete)) |
|
|
|
self._transmit(self._lead_ticket(emission, complete)) |
|
|
|
|
|
|
|
|
|
|
|
def abort(self, outcome): |
|
|
|
def abort(self, outcome): |
|
|
|
"""See _interfaces.TransmissionManager.abort for specification.""" |
|
|
|
"""See _interfaces.TransmissionManager.abort for specification.""" |
|
|
|
if self._emissions is not None and self._outcome is None: |
|
|
|
if self._emissions is not None and self._outcome is None: |
|
|
|
self._outcome = outcome |
|
|
|
self._outcome = outcome |
|
|
|
if not self._transmitting: |
|
|
|
if not self._transmitting: |
|
|
|
packet = self._abortive_response_packet(outcome) |
|
|
|
ticket = self._abortive_response_ticket(outcome) |
|
|
|
self._emissions = None |
|
|
|
self._emissions = None |
|
|
|
if packet is not None: |
|
|
|
if ticket is not None: |
|
|
|
self._transmit(packet) |
|
|
|
self._transmit(ticket) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def front_transmission_manager( |
|
|
|
def front_transmission_manager( |
|
|
@ -378,14 +378,14 @@ def front_transmission_manager( |
|
|
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
Args: |
|
|
|
lock: The operation-servicing-wide lock object. |
|
|
|
lock: The operation-servicing-wide lock object. |
|
|
|
pool: A thread pool in which the work of transmitting packets will be |
|
|
|
pool: A thread pool in which the work of transmitting tickets will be |
|
|
|
performed. |
|
|
|
performed. |
|
|
|
callback: A callable that accepts packets and sends them to the other side |
|
|
|
callback: A callable that accepts tickets and sends them to the other side |
|
|
|
of the operation. |
|
|
|
of the operation. |
|
|
|
operation_id: The operation's ID. |
|
|
|
operation_id: The operation's ID. |
|
|
|
name: The name of the operation. |
|
|
|
name: The name of the operation. |
|
|
|
subscription_kind: An interfaces.ServicedSubscription.Kind value |
|
|
|
subscription_kind: An interfaces.ServicedSubscription.Kind value |
|
|
|
describing the interest the front has in packets sent from the back. |
|
|
|
describing the interest the front has in tickets sent from the back. |
|
|
|
trace_id: A uuid.UUID identifying a set of related operations to which |
|
|
|
trace_id: A uuid.UUID identifying a set of related operations to which |
|
|
|
this operation belongs. |
|
|
|
this operation belongs. |
|
|
|
timeout: A length of time in seconds to allow for the entire operation. |
|
|
|
timeout: A length of time in seconds to allow for the entire operation. |
|
|
@ -396,7 +396,7 @@ def front_transmission_manager( |
|
|
|
A TransmissionManager appropriate for front-side use. |
|
|
|
A TransmissionManager appropriate for front-side use. |
|
|
|
""" |
|
|
|
""" |
|
|
|
return _TransmittingTransmissionManager( |
|
|
|
return _TransmittingTransmissionManager( |
|
|
|
lock, pool, callback, operation_id, _FrontPacketizer( |
|
|
|
lock, pool, callback, operation_id, _FrontTicketizer( |
|
|
|
name, subscription_kind, trace_id, timeout), |
|
|
|
name, subscription_kind, trace_id, timeout), |
|
|
|
termination_manager) |
|
|
|
termination_manager) |
|
|
|
|
|
|
|
|
|
|
@ -408,15 +408,15 @@ def back_transmission_manager( |
|
|
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
Args: |
|
|
|
lock: The operation-servicing-wide lock object. |
|
|
|
lock: The operation-servicing-wide lock object. |
|
|
|
pool: A thread pool in which the work of transmitting packets will be |
|
|
|
pool: A thread pool in which the work of transmitting tickets will be |
|
|
|
performed. |
|
|
|
performed. |
|
|
|
callback: A callable that accepts packets and sends them to the other side |
|
|
|
callback: A callable that accepts tickets and sends them to the other side |
|
|
|
of the operation. |
|
|
|
of the operation. |
|
|
|
operation_id: The operation's ID. |
|
|
|
operation_id: The operation's ID. |
|
|
|
termination_manager: The _interfaces.TerminationManager associated with |
|
|
|
termination_manager: The _interfaces.TerminationManager associated with |
|
|
|
this operation. |
|
|
|
this operation. |
|
|
|
subscription_kind: An interfaces.ServicedSubscription.Kind value |
|
|
|
subscription_kind: An interfaces.ServicedSubscription.Kind value |
|
|
|
describing the interest the front has in packets sent from the back. |
|
|
|
describing the interest the front has in tickets sent from the back. |
|
|
|
|
|
|
|
|
|
|
|
Returns: |
|
|
|
Returns: |
|
|
|
A TransmissionManager appropriate for back-side use. |
|
|
|
A TransmissionManager appropriate for back-side use. |
|
|
@ -425,5 +425,5 @@ def back_transmission_manager( |
|
|
|
return _EmptyTransmissionManager() |
|
|
|
return _EmptyTransmissionManager() |
|
|
|
else: |
|
|
|
else: |
|
|
|
return _TransmittingTransmissionManager( |
|
|
|
return _TransmittingTransmissionManager( |
|
|
|
lock, pool, callback, operation_id, _BackPacketizer(), |
|
|
|
lock, pool, callback, operation_id, _BackTicketizer(), |
|
|
|
termination_manager) |
|
|
|
termination_manager) |
|
|
|