def echo_case(self, echo_msg): """ (ECHOMessage,) -> None An execution when receiving an echo message. """ #TODO: assume that we won't receive an echo if we didn't initiate an explorer # get variables from a message invoke_id = echo_msg.get_id() sender_name = echo_msg.get_sender_name() logging.debug( "From {0} with invoke id {1}, received an echo message".format( sender_name, invoke_id)) # get the aggregator from a collection aggregator = self.aggregator_collections[invoke_id] # perform aggregate aggregator.results = self.executor.aggregate( aggregator.results, echo_msg.get_data(), aggregator.limit, aggregator.aggregation_function_list) # N := N-{from} aggregator.remove_neighbor(sender_name) # if N = zero_set if len(aggregator.neighbors) == 0: # return an echo message to parent return_msg = ECHOMessage(ECHOMessage.MSG_TYPE_ECHO, invoke_id, NAME, aggregator.results) # return self.senders[aggregator.parent].send(return_msg.serialize()) #clean up self.aggregator_collections[invoke_id] = None del aggregator
def invoke_case(self, invoke_msg): """ (ECHOMessage,) -> None An execution when receiving an invoke message. """ #TODO: assume that we won't invoke the same ID * # get variables from a message invoke_id = invoke_msg.get_id() parent = invoke_msg.get_sender_name() # create an aggregator object aggregator = EchoAggregator(NEIGHBOR_LIST, parent) # save it for future reference self.aggregator_collections[invoke_id] = aggregator #if N != zero_set if len(aggregator.neighbors) != 0: #change an invoke message to an explorer message exp_msg = invoke_msg exp_msg.msg_type = ECHOMessage.MSG_TYPE_EXP exp_msg.sender = NAME # send explorer messages for host in aggregator.neighbors: self.senders[host].send(exp_msg.serialize()) # A.initiate() # get the query object query = invoke_msg.get_data() # add more information to echo aggregator aggregator.limit = query.parameters['limit'] aggregator.aggregation_function_list = query.aggregation_function_list # execute the result results = self.executor.execute(query) # store local results aggregator.results = results else: # A.initiate() # get the query object query = invoke_msg.get_data() # add more information to echo aggregator aggregator.limit = query.parameters['limit'] aggregator.aggregation_function_list = query.aggregation_function_list # execute the result results = self.executor.execute(query) # create a return message return_msg = ECHOMessage(ECHOMessage.MSG_TYPE_RETURN, invoke_id, NAME, results) # return self.senders[parent].send(return_msg.serialize()) # clean up self.aggregator_collections[invoke_id] = None del aggregator
def exp_case(self, exp_msg): """ (ECHOMessage,) -> None An execution when receiving an explorer message. """ # get variables from a message invoke_id = exp_msg.get_id() sender_name = exp_msg.get_sender_name() logging.debug( "From {0} with invoke id {1}, received an explorer message".format( sender_name, invoke_id)) # create a socket to parent if not exist if sender_name not in self.senders: self.senders[sender_name] = self.context.socket(zmq.PUSH) self.senders[sender_name].connect("tcp://{0}:{1}".format( sender_name, DISPATCHER_PORT)) # get a aggregator object from the collection. if not exist, create it try: aggregator = self.aggregator_collections[invoke_id] except KeyError: aggregator = EchoAggregator(NEIGHBOR_LIST, sender_name) # N := N-{from} aggregator.remove_neighbor(sender_name) # if not visited if invoke_id not in self.aggregator_collections: # save it for future reference self.aggregator_collections[invoke_id] = aggregator # create local result, and store it locally # A.initiate() # get a query object query = exp_msg.get_data() # add more information to echo aggregator aggregator.limit = query.parameters['limit'] aggregator.aggregation_function_list = query.aggregation_function_list # if there are neighbors if len(aggregator.neighbors) != 0: # change a sender name of a explorer message exp_msg.sender = NAME # broadcast explorer messages for host in aggregator.neighbors: self.senders[host].send(exp_msg.serialize()) # execute results = self.executor.execute(query) # store the result aggregator.results = results # if it is a leaf else: # execute results = self.executor.execute(query) # create a return message echo_msg = ECHOMessage(ECHOMessage.MSG_TYPE_ECHO, invoke_id, NAME, results) # send to parent self.senders[aggregator.parent].send(echo_msg.serialize()) #clean up self.aggregator_collections[invoke_id] = None del aggregator # visited and N = zero_set else: if len(aggregator.neighbors) == 0: # return an echo message to parent echo_msg = ECHOMessage(ECHOMessage.MSG_TYPE_ECHO, invoke_id, NAME, aggregator.results) # return self.senders[aggregator.parent].send(echo_msg.serialize()) #clean up self.aggregator_collections[invoke_id] = None del aggregator