def _forward_first_phase_commit_successful( self,event_uuid,endpoint_uuid,children_event_endpoint_uuids): ''' @param {uuid} event_uuid @param {uuid} endpoint_uuid @param {array} children_event_endpoint_uuids --- Partner endpoint is subscriber of event on this endpoint with uuid event_uuid. Send to partner a message that the first phase of the commit was successful for the endpoint with uuid endpoint_uuid, and that the root can go on to second phase of commit when all endpoints with uuids in children_event_endpoint_uuids have confirmed that they are clear to commit. ''' general_message = GeneralMessage() general_message.message_type = GeneralMessage.PARTNER_FIRST_PHASE_RESULT first_phase_result = general_message.first_phase_result first_phase_result.event_uuid.data = event_uuid first_phase_result.sending_endpoint_uuid.data = endpoint_uuid first_phase_result.successful = True for child_event_uuid in children_event_endpoint_uuids: child_event_uuid_msg = first_phase_result.children_event_endpoint_uuids.add() child_event_uuid_msg.data = child_event_uuid self._conn_obj.write(general_message.SerializeToString(),self)
def _forward_backout_request_partner(self,active_event_uuid): ''' @param {UUID} active_event_uuid --- The uuid of the event we will forward a backout request to our partner for. ''' general_message = GeneralMessage() general_message.message_type = GeneralMessage.PARTNER_BACKOUT_COMMIT_REQUEST general_message.backout_commit_request.event_uuid.data = active_event_uuid self._conn_obj.write(general_message.SerializeToString(),self)
def _forward_complete_commit_request_partner(self,active_event): ''' Active event on this endpoint has completed its commit and it wants you to tell partner endpoint as well to complete its commit. ''' general_message = GeneralMessage() general_message.message_type = GeneralMessage.PARTNER_COMPLETE_COMMIT_REQUEST general_message.complete_commit_request.event_uuid.data = active_event.uuid self._conn_obj.write(general_message.SerializeToString(),self)
def _notify_partner_ready(self): ''' Tell partner endpoint that I have completed my onReady action. ''' general_message = GeneralMessage() general_message.message_type = GeneralMessage.PARTNER_NOTIFY_READY partner_notify_ready = general_message.notify_ready endpoint_uuid = partner_notify_ready.endpoint_uuid endpoint_uuid.data = self._uuid self._conn_obj.write(general_message.SerializeToString(),self)
def _forward_promotion_message(self,uuid,new_priority): ''' Send partner message that event has been promoted ''' general_message = GeneralMessage() general_message.message_type = GeneralMessage.PROMOTION promotion_message = general_message.promotion promotion_message.event_uuid.data = uuid promotion_message.new_priority.data = new_priority self._conn_obj.write(general_message.SerializeToString(),self)
def _send_clock_update(self): ''' Grab timestamp from clock and send it over to partner. ''' current_clock_timestamp = self._clock.get_timestamp() general_message = GeneralMessage() general_message.message_type = GeneralMessage.TIMESTAMP_UPDATE timestamp_updated = general_message.timestamp_updated timestamp_updated.data = current_clock_timestamp self._conn_obj.write(general_message.SerializeToString(),self)
def _forward_commit_request_partner(self,active_event): ''' @param {_ActiveEvent} active_event --- Has the same uuid as the event we will forward a commit to our partner for. ''' # FIXME: may be a way to piggyback commit with final event in # sequence. general_message = GeneralMessage() general_message.message_type = GeneralMessage.PARTNER_COMMIT_REQUEST general_message.commit_request.event_uuid.data = active_event.uuid self._conn_obj.write(general_message.SerializeToString(),self)
def _notify_partner_removed_subscriber( self,event_uuid,removed_subscriber_uuid,host_uuid,resource_uuid): ''' Send a message to partner that a subscriber is no longer holding a lock on a resource to commit it. ''' general_message = GeneralMessage() general_message.message_type = GeneralMessage.PARTNER_REMOVED_SUBSCRIBER removed_subscriber = general_message.removed_subscriber removed_subscriber.event_uuid.data = event_uuid removed_subscriber.removed_subscriber_uuid.data = removed_subscriber_uuid removed_subscriber.host_uuid.data = host_uuid removed_subscriber.resource_uuid.data = resource_uuid self._conn_obj.write(general_message.SerializeToString(),self)
def _notify_partner_peered_before_return( self,event_uuid,reply_with_uuid,active_event): ''' @see waldoActiveEvent.wait_if_modified_peered ''' general_message = GeneralMessage() general_message.message_type = GeneralMessage.PARTNER_NOTIFY_OF_PEERED_MODIFIED notify_of_peered_modified = general_message.notify_of_peered_modified glob_deltas = notify_of_peered_modified.glob_deltas self._global_var_store.generate_deltas( active_event,False,glob_deltas) notify_of_peered_modified.event_uuid.data = event_uuid notify_of_peered_modified.reply_with_uuid.data = reply_with_uuid self._conn_obj.write(general_message.SerializeToString(),self)
def _notify_partner_of_additional_subscriber( self,event_uuid,additional_subscriber_uuid,host_uuid,resource_uuid): ''' Send a message to partner that a subscriber has just started holding a lock on a resource to commit it. ''' general_message = GeneralMessage() general_message.message_type = GeneralMessage.PARTNER_ADDITIONAL_SUBSCRIBER additional_subscriber = general_message.additional_subscriber additional_subscriber.event_uuid.data = event_uuid additional_subscriber.additional_subscriber_uuid.data = additional_subscriber_uuid additional_subscriber.host_uuid.data = host_uuid additional_subscriber.resource_uuid.data = resource_uuid self._conn_obj.write(general_message.SerializeToString(),self)
def _send_heartbeats(self): ''' Periodically sends heartbeats to the partner endpoint to indicate that this endpoint is still alive and reachable. ''' while True: time.sleep(self._send_period) general_message = GeneralMessage() general_message.message_type = GeneralMessage.HEARTBEAT heartbeat_message = general_message.heartbeat heartbeat_message.msg = 'ping' ### FIXME: This should probably be a constant, ### whether or not it needs to be a string is debatable. try: self._sock.write(general_message.SerializeToString(),self) except socket.error as err: self._sock.close() break
def _forward_first_phase_commit_unsuccessful( self,event_uuid,endpoint_uuid): ''' @param {uuid} event_uuid @param {uuid} endpoint_uuid Partner endpoint is subscriber of event on this endpoint with uuid event_uuid. Send to partner a message that the first phase of the commit was unsuccessful on endpoint with uuid endpoint_uuid (and therefore, it and everything along the path should roll back their commits). ''' general_message = GeneralMessage() general_message.message_type = GeneralMessage.PARTNER_FIRST_PHASE_RESULT first_phase_result = general_message.first_phase_result first_phase_result.event_uuid.data = event_uuid first_phase_result.sending_endpoint_uuid.data = endpoint_uuid first_phase_result.successful = False self._conn_obj.write(general_message.SerializeToString(),self)
def _notify_partner_peered_before_return_response( self,event_uuid,reply_to_uuid,invalidated): ''' @see PartnerNotifyOfPeeredModifiedResponse.proto ''' general_message = GeneralMessage() general_message.message_type = GeneralMessage.PARTNER_NOTIFY_OF_PEERED_MODIFIED_RESPONSE notify_of_peered_modified_resp = general_message.notify_of_peered_modified_resp # load event uuid msg_event_uuid = notify_of_peered_modified_resp.event_uuid msg_event_uuid.data = event_uuid # load reply_to_uuid msg_reply_to_uuid = notify_of_peered_modified_resp.reply_to_uuid msg_reply_to_uuid.data = reply_to_uuid # load invalidated notify_of_peered_modified_resp.invalidated = invalidated self._conn_obj.write(general_message.SerializeToString(),self)
def _propagate_back_exception(self,event_uuid,priority,exception): ''' Called by the active event when an exception has occured in the midst of a sequence and it needs to be propagated back towards the root of the active event. Sends a partner_error message to the partner containing the event and endpoint uuids. ''' general_message = GeneralMessage() general_message.message_type = GeneralMessage.PARTNER_ERROR error = general_message.error error.event_uuid.data = event_uuid error.host_uuid.data = self._uuid if isinstance(exception, util.NetworkException): error.type = PartnerError.NETWORK error.trace = exception.trace elif isinstance(exception, util.ApplicationException): error.type = PartnerError.APPLICATION error.trace = exception.trace else: error.trace = traceback.format_exc() error.type = PartnerError.APPLICATION self._conn_obj.write(general_message.SerializeToString(),self)
def _notify_partner_stop(self): general_message = GeneralMessage() general_message.message_type = GeneralMessage.PARTNER_STOP general_message.stop.dummy = False self._conn_obj.write_stop(general_message.SerializeToString(),self)
def _send_partner_message_sequence_block_request( self,block_name,event_uuid,reply_with_uuid,reply_to_uuid, invalidation_listener,sequence_local_store,first_msg): ''' Sends a message using connection object to the partner endpoint requesting it to perform some message sequence action. @param {String or None} block_name --- The name of the sequence block we want to execute on the partner endpoint. (Note: this is how that sequence block is named in the source Waldo file, not how it is translated by the compiler into a function.) It can also be None if this is the final message sequence block's execution. @param {uuid} event_uuid --- The uuid of the requesting event. @param {uuid} reply_with_uuid --- When the partner endpoint responds, it should place reply_with_uuid in its reply_to message field. That way, we can determine which message the partner endpoint was replying to. @param {uuid or None} reply_to_uuid --- If this is the beginning of a sequence of messages, then fill the reply_to field of the message with None (the message is not a reply to anything that we have seen so far). Otherwise, put the reply_with message field of the last message that the partner said as part of this sequence in. @param {_InvalidationListener} invalidation_listener --- The invalidation listener that is requesting the message to be sent. @param {_VariableStore} sequence_local_store --- We convert all changes that we have made to both peered data and sequence local data to maps of deltas so that the partner endpoint can apply the changes. We use the sequence_local_store to get changes that invalidation_listener has made to sequence local data. (For peered data, we can just use self._global_var_store.) @param {bool} first_msg --- If we are sending the first message in a sequence block, then we must force the sequence local data to be transmitted whether or not it was modified. ''' general_message = GeneralMessage() general_message.message_type = GeneralMessage.PARTNER_REQUEST_SEQUENCE_BLOCK request_sequence_block_msg = general_message.request_sequence_block # event uuid request_sequence_block_msg.event_uuid.data = event_uuid # name of block requesting if block_name != None: request_sequence_block_msg.name_of_block_requesting = block_name # reply with uuid reply_with_uuid_msg = request_sequence_block_msg.reply_with_uuid reply_with_uuid_msg.data = reply_with_uuid # reply to uuid if reply_to_uuid != None: reply_to_uuid_msg = request_sequence_block_msg.reply_to_uuid reply_to_uuid_msg.data = reply_to_uuid sequence_local_deltas = sequence_local_store.generate_deltas( invalidation_listener,first_msg,request_sequence_block_msg.sequence_local_var_store_deltas) glob_deltas = self._global_var_store.generate_deltas( invalidation_listener,False,request_sequence_block_msg.peered_var_store_deltas) self._conn_obj.write(general_message.SerializeToString(),self)