def sequence_block(self,active_event=None,context=None): ''' The first time that this function is called, it has neither an active_event, nor a context. We create them. ''' # keep track of whether this is the first message sent in a # sequence so that we know whether or not we must force # updating all the new sequence local data. _first_msg = False if active_event == None: # create active event active_event = self._act_event_map.create_root_event() # create context context = waldoExecutingEvent._ExecutingEventContext( self._global_var_store, # not using sequence local store waldoVariableStore._VariableStore(self._host_uuid)) _first_msg = True # Send messages back and forth to each other to decrement # peered local data seq_local_num. Keep doing so until # numero is negative. peered_var = context.global_store.get_var_if_exists( self.peered_number_var_name) if peered_var.get_val(active_event) > 0: # keep sending messages until less than 0. peered_var.write_val(active_event,peered_var.get_val(active_event) - 1) # store each value as go through in array so that can # check at the end that did in fact get sequential # decrement of values. global array_of_values array_of_values.append(peered_var.get_val(active_event)) threadsafe_queue = Queue.Queue() active_event.issue_partner_sequence_block_call( context,'sequence_block',threadsafe_queue,_first_msg) seq_msg_call_res = threadsafe_queue.get() context.set_to_reply_with(seq_msg_call_res.reply_with_msg_field) # apply changes to sequence variables. (There shouldn't # be any, but it's worth getting in practice.) Note: that # the system has already applied deltas for global data. context.sequence_local_store.incorporate_deltas( active_event,seq_msg_call_res.sequence_local_var_store_deltas) # send more messages to_exec_next = seq_msg_call_res.to_exec_next_name_msg_field to_exec = getattr(self,to_exec_next) to_exec(active_event,context) # so that root can commit return active_event
def new_event_and_write(self,var_name,var_val): active_event = self._act_event_map.create_root_event() # create context context = waldoExecutingEvent._ExecutingEventContext( self._global_var_store, # not using sequence local store waldoVariableStore._VariableStore(self._host_uuid)) var = context.global_store.get_var_if_exists(var_name) var.write_val(active_event,var_val) return active_event
def evt_r1(self,endpoint_a): active_event = self._act_event_map.create_root_event() # create context context = waldoExecutingEvent._ExecutingEventContext( self._global_var_store, # not using sequence local store waldoVariableStore._VariableStore(self._host_uuid)) threadsafe_queue = Queue.Queue() active_event.issue_endpoint_object_call( endpoint_a,'update_alpha_and_send_message', threadsafe_queue) endpoint_call_res = threadsafe_queue.get() return active_event
def write_numero(self): active_event = self._act_event_map.create_root_event() # create context context = waldoExecutingEvent._ExecutingEventContext( self._global_var_store, # not using sequence local store waldoVariableStore._VariableStore(self._host_uuid)) var = context.global_store.get_var_if_exists( self.peered_number_var_name) var_value = var.get_val(active_event) var.write_val(active_event,var_value + 1) var_value = var.get_val(active_event) active_event.request_commit() queue_elem = active_event.event_complete_queue.get() return var_value
def __init__(self,conn_obj=None,host_uuid = None): if conn_obj is None: conn_obj = _WaldoSingleSideConnectionObject() if host_uuid == None: host_uuid = generate_uuid() glob_var_store = _VariableStore(host_uuid) self.end_global_number_var_name = 'numero' glob_var_store.add_var( self.end_global_number_var_name, LockedNumberVariable(host_uuid,False,100)) _Endpoint.__init__( self,Waldo._waldo_classes, host_uuid,conn_obj,glob_var_store)
def endpoint_func(self,active_event,context,other_endpoint): ''' The first time that this function is called, it has neither an active_event, nor a context. We need to explicitly pass in None for them. ''' if active_event == None: # create active event active_event = self._act_event_map.create_root_event() # create context context = waldoExecutingEvent._ExecutingEventContext( self._global_var_store, # not using sequence local store waldoVariableStore._VariableStore(self._host_uuid)) # Execute endpoint call back and forth. Keep doing so until # numero is negative. endpoint_var = context.global_store.get_var_if_exists( self.endpoint_number_var_name) if endpoint_var.get_val(active_event) > 0: # keep sending messages until less than 0. endpoint_var.write_val(active_event,endpoint_var.get_val(active_event) - 1) # store each value as go through in array so that can # check at the end that did in fact get sequential # decrement of values. global array_of_values array_of_values.append(endpoint_var.get_val(active_event)) threadsafe_queue = Queue.Queue() active_event.issue_endpoint_object_call( other_endpoint,'endpoint_func', threadsafe_queue,self) endpoint_call_res = threadsafe_queue.get() # so that root can commit return active_event
def new_event_and_read_numero(self): ''' Create a new event that reads the value of the peered number 'numero.' ''' active_event = self._act_event_map.create_root_event() # create context context = waldoExecutingEvent._ExecutingEventContext( self._global_var_store, # not using sequence local store waldoVariableStore._VariableStore(self._host_uuid)) peered_var = context.global_store.get_var_if_exists( self.peered_number_var_name) var_value = peered_var.get_val(active_event) # warning just assuming that commit goes through instead of # retrying the event. active_event.request_commit() queue_elem = active_event.event_complete_queue.get() return var_value
def __init__(self,conn_obj,host_uuid = None): # all dummy endpoints will have the same _VariableStore # Peered Number numero = 100; # Peered Text some_str = 'test'; # Peered List (elements: Text) text_list; if host_uuid == None: host_uuid = util.generate_uuid() glob_var_store = waldoVariableStore._VariableStore(host_uuid) self.peered_number_var_name = 'numero' glob_var_store.add_var( self.peered_number_var_name, wVariables.WaldoNumVariable( self.peered_number_var_name,host_uuid, True,100)) self.peered_str_var_name = 'some_str' glob_var_store.add_var( self.peered_str_var_name, wVariables.WaldoTextVariable( self.peered_str_var_name,host_uuid, True,'test')) self.peered_list_var_name = 'text_list' glob_var_store.add_var( self.peered_list_var_name, wVariables.WaldoTextVariable( self.peered_list_var_name,host_uuid,True)) self.peered_map_var_name = 'some map' glob_var_store.add_var( self.peered_map_var_name, wVariables.WaldoMapVariable('some map',host_uuid,True)) waldoEndpoint._Endpoint.__init__( self,Waldo._waldo_classes, host_uuid,conn_obj,glob_var_store)
def evt_r2(self,endpoint_b): active_event = self._act_event_map.create_root_event() # create context context = waldoExecutingEvent._ExecutingEventContext( self._global_var_store, # not using sequence local store waldoVariableStore._VariableStore(self._host_uuid)) # first, call method on b threadsafe_queue = Queue.Queue() active_event.issue_endpoint_object_call( endpoint_b,'update_beta', threadsafe_queue) endpoint_call_res = threadsafe_queue.get() # call method on c, which calls method on a threadsafe_queue = Queue.Queue() active_event.issue_partner_sequence_block_call( context,'receive_message_for_a',threadsafe_queue,True) msg_call_res = threadsafe_queue.get() return active_event
def handle_first_sequence_msg_from_partner( self,msg,name_of_block_to_exec_next): ''' ASSUMES ALREADY WITHIN LOCK @param {PartnerMessageRequestSequenceBlock.proto} msg --- @param {string} name_of_block_to_exec_next --- the name of the sequence block to execute next. @returns {Executing event} means that the other side has generated a first message create a new context to execute that message and do so in a new thread. ''' ### FIGURE OUT WHAT TO EXECUTE NEXT #### DEBUG if name_of_block_to_exec_next == None: util.logger_assert( 'Error in _ActiveEvent. Should not receive the ' + 'beginning of a sequence message without some ' + 'instruction for what to do next.') #### END DEBUG block_to_exec_internal_name = util.partner_endpoint_msg_call_func_name( name_of_block_to_exec_next) #### MAYBE DEBUG # ("maybe" because we also may want to throw a Waldo error # for this instead of just asserting out.) if not hasattr( self.event_parent.local_endpoint,block_to_exec_internal_name): util.logger_assert( 'Error in _ActiveEvent. Received a request to ' + 'perform an unknown sequence step.') #### END MAYBE DEBUG to_exec = getattr(self.event_parent.local_endpoint,block_to_exec_internal_name) ### SET UP CONTEXT FOR EXECUTING seq_local_var_store = waldoVariableStore._VariableStore( self.event_parent.local_endpoint._host_uuid) # FIXME: eventually, want to remove pickle-ing here seq_local_var_store.incorporate_deltas( self,msg.sequence_local_var_store_deltas) evt_ctx = _ExecutingEventContext( # already incorporated deltas for global_var_store # above. self.event_parent.local_endpoint._global_var_store, seq_local_var_store) evt_ctx.set_to_reply_with(msg.reply_with_uuid.data) # used to actually start execution of context thread at end # of loop. must start event outside of locks. That way, # if the exec event leads to and endpoint call, etc., we # don't block waiting on its return. exec_event = _ExecutingEvent( to_exec,self,evt_ctx, None # using None here means that we do not need to # bother with waiting for modified peered-s to # update. ) return exec_event
def sequence_block(self,active_event=None,context=None): ''' The first time that this function is called, it has neither an active_event, nor a context. We create them. ''' seq_local_num_name = 'seq_local_num' # keep track of whether this is the first message sent in a # sequence so that we know whether or not we must force # updating all the new sequence local data. _first_msg = False if active_event == None: # create active event active_event = self._act_event_map.create_root_event() # create context seq_local_store = waldoVariableStore._VariableStore(self._host_uuid) seq_local_store.add_var( seq_local_num_name, wVariables.WaldoNumVariable( seq_local_num_name,self._host_uuid,True,100)) context = waldoExecutingEvent._ExecutingEventContext( self._global_var_store,seq_local_store) _first_msg = True # Send messages back and forth to each other to decrement # sequence local data seq_local_num. Keep doing so until # seq_local_num is negative. local_var = context.sequence_local_store.get_var_if_exists(seq_local_num_name) if local_var.get_val(active_event) > 0: # keep sending messages until less than 0. local_var.write_val(active_event,local_var.get_val(active_event) - 1) # store each value as go through in array so that can # check at the end that did in fact get sequential # decrement of values. global array_of_values array_of_values.append(local_var.get_val(active_event)) threadsafe_queue = Queue.Queue() active_event.issue_partner_sequence_block_call( context,'sequence_block',threadsafe_queue,_first_msg) seq_msg_call_res = threadsafe_queue.get() context.set_to_reply_with(seq_msg_call_res.reply_with_msg_field) # apply changes to sequence local data. (global changes, # which aren't applicable in this example, have already # been applied.) context.sequence_local_store.incorporate_deltas( active_event,seq_msg_call_res.sequence_local_var_store_deltas) # send more messages to_exec_next = seq_msg_call_res.to_exec_next_name_msg_field to_exec = getattr(self,to_exec_next) to_exec(active_event,context) else: # at this point, should initiate the commit of data. # print '\nComplete!!!\n' pass
def create_context(endpoint): seq_local_store = _VariableStore(endpoint._host_uuid) return _ExecutingEventContext( endpoint._global_var_store, seq_local_store)