class Learner(object): def __init__(self): self.publisher = Publisher(queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST) self.consumer = Consumer(queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST) def callback(self, ch, method, properties, body): print('Callback called! body={}'.format(body)) pass def learn_callback(self, ch, method, properties, body): print('LEARN Callback called! body={}'.format(body)) def consume_learn(self): routing_key = 'LEARN' self.consumer.consume(ex_name=EX_PAXOS, routing_key=routing_key, type=DIRECT, callback=self.learn_callback)
def __init__(self): self.publisher = Publisher(queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST) self.consumer = Consumer(queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST)
def __init__(self): self.publisher = Publisher(queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST) self.consumer = Consumer(queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST) # daftar Node ID, jangan lupa menambahkan ke sini jika menjalankan node baru self.nodes = [1, 2, 3]
def get_consumer(self): from rabbitmq import Consumer consumer = Consumer( broker_url=self.broker_url, queue_name=self.queue_name, durable=self.durable, tasks=self.get_tasks(), auto_ack=self.auto_ack, inactivity_timeout=1, ) return consumer
def __init__(self, node_id): self.node_id = node_id self.publisher = Publisher( queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST ) self.consumer_write = Consumer( queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST ) self.consumer_broadcast = Consumer( queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST ) self.consumer_read = Consumer( queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST ) self.db = TinyDB('db.json') self.DB = Query() consume_write_thread = threading.Thread( target=self.consume_write ) consume_write_thread.start() consume_broadcast_thread = threading.Thread( target=self.consume_broadcast ) consume_broadcast_thread.start() consume_read_thread = threading.Thread( target=self.consume_read ) consume_read_thread.start()
def __init__(self, proposer_id): self.proposer_id = proposer_id self.publisher = Publisher(queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST) self.consumer = Consumer(queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST) # daftar Acceptor ID self.acceptors = [1, 2] self.number_of_acceptors = len(self.acceptors)
class Node(object): def __init__(self, node_id): self.node_id = node_id self.publisher = Publisher( queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST ) self.consumer_write = Consumer( queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST ) self.consumer_broadcast = Consumer( queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST ) self.consumer_read = Consumer( queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST ) self.db = TinyDB('db.json') self.DB = Query() consume_write_thread = threading.Thread( target=self.consume_write ) consume_write_thread.start() consume_broadcast_thread = threading.Thread( target=self.consume_broadcast ) consume_broadcast_thread.start() consume_read_thread = threading.Thread( target=self.consume_read ) consume_read_thread.start() def attach_sender_id(self, message): message = { 'sender_id': self.node_id, 'message': message } return json.dumps(message) def callback(self, ch, method, properties, body): print('Callback called! body={}'.format(body)) pass def read_db(self): try: result = self.db.get(self.DB.node_id == self.node_id) if result is not None: print('Node {} contains message: {}'.format(self.node_id, result)) else: print('Node {} empty.'.format(self.node_id)) except Exception as e: print('Error reading from DB. {}'.format(e.message)) def update_db(self, message): try: result = self.db.get(self.DB.node_id == self.node_id) if result is not None: self.db.update({ 'message': message }, self.DB.node_id == self.node_id) print("DB updated: {}".format(message)) else: self.db.insert({ 'message': message, 'node_id': self.node_id }) print("DB inserted: {}".format(message)) except Exception as e: print('Error writing to DB. {}'.format(e.message)) def consume_write_callback(self, ch, method, properties, body): print('WRITE Callback called! body={}'.format(body)) self.update_db(message=body) self.publish_ack(body) def consume_broadcast_callback(self, ch, method, properties, body): print('BROADCAST Callback called! body={}'.format(body)) self.update_db(message=body) def consume_read_callback(self, ch, method, properties, body): print('READ Callback called! body={}'.format(body)) self.read_db() # Lakukan consume WRITE_[NODE_ID] # Apabila menerima, langsung menulis message di DB # Lalu publish response ACK_RELAY def consume_write(self): routing_key = 'WRITE_{}'.format(self.node_id) self.consumer_write.consume( ex_name=EX_WRITE, routing_key=routing_key, type=DIRECT, callback=self.consume_write_callback ) # Lakukan Consume BROADCAST_[NODE_ID] # Apabila menerima, langsung tulis message di DB def consume_broadcast(self): routing_key = 'BROADCAST_{}'.format(self.node_id) self.consumer_broadcast.consume( ex_name=EX_WRITE, routing_key=routing_key, type=DIRECT, callback=self.consume_broadcast_callback ) # Lakukan Consume READ # Apabila menerima, langsung baca di DB dan outputkan ke terminal def consume_read(self): routing_key = 'READ' self.consumer_read.consume( ex_name=EX_READ, routing_key=routing_key, type=FANOUT, callback=self.consume_read_callback ) # Publish ACK_RELAY ke node relay bila selesai menerima input WRITE dan selesai menuliskan ke DB def publish_ack(self, message): routing_key = 'ACK_RELAY' self.publisher.publish( ex_name=EX_WRITE, routing_key=routing_key, message=self.attach_sender_id(message), type=DIRECT )
class Relay(object): def __init__(self): self.publisher = Publisher(queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST) self.consumer = Consumer(queue_url=QUEUE_URL, queue_port=QUEUE_PORT, username=USERNAME, password=PASSWORD, virtual_host=VHOST) # daftar Node ID, jangan lupa menambahkan ke sini jika menjalankan node baru self.nodes = [1, 2, 3] def consume(self): consume_ack_thread = threading.Thread(target=self.consume_ack) consume_ack_thread.start() def callback(self, ch, method, properties, body): print('Callback called! body={}'.format(body)) pass # Relay menerima pesan ACK dari suatu node dan mem-broadcast ke node-node lain def consume_ack_callback(self, ch, method, properties, body): print('ACK Callback called! body={}'.format(body)) body = json.loads(body) sender_id = body['sender_id'] message = body['message'] self.broadcast(message, sender_id) # Relay menunggu adanya pesan ACK dari suatu node untuk dibroadcast ke node-node lain def consume_ack(self): routing_key = 'ACK_RELAY' self.consumer.consume(ex_name=EX_WRITE, routing_key=routing_key, type=DIRECT, callback=self.consume_ack_callback) # Relay mengirimkan pesan WRITE dengan tipe DIRECT ke suatu node def publish_write(self, message, receiver_node): routing_key = 'WRITE_{}'.format(receiver_node) self.publisher.publish(ex_name=EX_WRITE, routing_key=routing_key, message=message, type=DIRECT) # Fungsi Publish broadcast ke suatu node, tapi delay secara random antara 1-5 detik def publish_broadcast(self, message, receiver_node): def broadcast_sleep(): rand_seconds = random.randrange(1000, 5000) / 1000 time.sleep(rand_seconds) routing_key = 'BROADCAST_{}'.format(receiver_node) self.publisher.publish(ex_name=EX_WRITE, routing_key=routing_key, message=message, type=DIRECT) broadcast_thread = threading.Thread(target=broadcast_sleep) broadcast_thread.start() # Untuk setiap node selain SOURCE_NODE, publish broadcast def broadcast(self, message, source_node): for node in self.nodes: if str(node) != source_node: self.publish_broadcast(message=message, receiver_node=node) # Publish READ secara fanout ke semua node def publish_read(self): routing_key = 'READ' message = 'read' self.publisher.publish(ex_name=EX_READ, routing_key=routing_key, message=message, type=FANOUT)