class Client(ImprovedAgent): def __init__(self, aid, servers): super().__init__(aid) self.req = FipaRequestProtocol(self) self.servers = servers def on_start(self): super().on_start() self.make_request() def one_request(self, receiver): message = ACLMessage() message.add_receiver(receiver) while True: try: response = yield from self.req.send_request(message) except FipaMessageHandler as h: response = h.message except FipaProtocolComplete: break return response @AgentSession.session def make_request(self): r1, r2 = yield from AgentSession.gather( *(self.one_request(s) for s in self.servers) ) display_message(self.aid.name, f"Final response 1: [{r1.performative}] {r1.content}") display_message(self.aid.name, f"Final response 2: [{r2.performative}] {r2.content}")
class Sender(ImprovedAgent): def __init__(self, aid, recipients_aid): super(Sender, self).__init__(aid=aid) self.request_behavior = FipaRequestProtocol(self, is_initiator=True) self.call_later(15.0, lambda: self.on_time(recipients_aid)) def on_time(self, recipients_aid): @self.request_behavior.synchronize def async_request(receiver): # Message to send message = ACLMessage() message.set_content('Would you do me a favor?') message.add_receiver(receiver) self.request_behavior.send_request(message) while True: try: response_message = yield message content = response_message.content display_message(self.aid.name, f'I received INFORM: {content} from {response_message.sender.name}') except FipaAgreeHandler as e: response_message = e.message content = response_message.content display_message(self.aid.name, f'I received AGREE: {content} from {response_message.sender.name}') except FipaProtocolComplete as e: display_message(self.aid.name, f'I received all messages from {receiver.name}!') break for receiver in recipients_aid: async_request(receiver)
class Recipient(ImprovedAgent): def __init__(self, aid, calculator_aid, debug=False): super(Recipient, self).__init__(aid, debug) self.calculator_aid = calculator_aid self.inform_behavior = FipaRequestProtocol(self, is_initiator=False) self.inform_behavior.set_request_handler(self.on_request) self.consult_behavior = FipaRequestProtocol(self, is_initiator=True) def on_request(self, message): content = message.content display_message( self.aid.name, f'I received REQUEST: {content} from {message.sender.name}') reply_agree = message.create_reply() reply_agree.set_content('OK, I`ll do it, wait for me!') self.inform_behavior.send_agree(reply_agree) def do_long_job(): # Massive calculations part I display_message(self.aid.name, f'Doing long job') time.sleep(1.5) question = f'{randint(1, 50)}+{randint(100, 150)}' return question @AgentSession.session def do_long_job_callback(question): request_calc = ACLMessage() request_calc.set_content(question) request_calc.add_receiver(self.calculator_aid) while True: try: response_calc = yield from self.consult_behavior.send_request( request_calc) display_message( self.aid.name, f'I received INFORM: {response_calc.content} from {response_calc.sender.name}' ) except FipaProtocolComplete: break def more_long_job(): # Massive calculations part II display_message(self.aid.name, f'Doing second long job') time.sleep(1.25) return response_calc.content def more_long_job_callback(result): # There is still a reference to the incoming request display_message(self.aid.name, f'Calling callback') reply_inform = message.create_reply() reply_inform.set_content(f'The result is: {result}') self.inform_behavior.send_inform(reply_inform) print('END OF PROTOCOL') # Another blocking method in other thread, this time using callback defer_to_thread(more_long_job, more_long_job_callback) # Blocking method, must be called from another thread defer_to_thread(do_long_job, do_long_job_callback)