Exemplo n.º 1
0
Arquivo: proposer.py Projeto: irff/uas
class Proposer(object):
    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)

    def attach_sender_id(self, message, sender_id):
        message = {'sender_id': sender_id, 'message': message}

        return json.dumps(message)

    def callback(self, ch, method, properties, body):
        print('Callback called! body={}'.format(body))
        pass

    # Proposer mengirim pesan PREPARE ke semua acceptor
    def publish_prepare(self, message):
        for acceptor in self.acceptors:
            routing_key = 'PREPARE_{}'.format(acceptor)
            self.publisher.publish(ex_name=EX_PAXOS,
                                   routing_key=routing_key,
                                   message=self.attach_sender_id(
                                       message, self.proposer_id),
                                   type=DIRECT)

    # Proposer consume pesan PROMISE dari acceptor yang menerima PREPARE
    # Hitung apakah promise didapat dari mayoritas acceptor
    # Apabila IYA, kirim CONFIRM ke acceptor
    def consume_promise(self):
        pass
Exemplo n.º 2
0
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
        )
Exemplo n.º 3
0
# initialize the logger so we see what happens
logger_path = Path(app_config.log.path)
logger = Logger(path = logger_path / Path(__file__).stem, level = int(app_config.log.level))

# intialize the Rabbit MQ connection
params = pika.ConnectionParameters(host='localhost')
publisher = Publisher(params)

current_stamp = int(datetime.datetime.now(tz = datetime.timezone.utc).timestamp()) * 1000
#current_stamp = int(datetime.datetime(2020, 11, 20, 19, 20, 00, tzinfo = datetime.timezone.utc).timestamp() * 1000)

# send the Rabbit MQ message
logger.debug('Sending check orders message.')
publisher.publish({
    'stamp': current_stamp,
    'lookahead': int(app_config.orders.lookahead)
})
logger.debug('Sent check orders message.')

if __name__ == '__main__':
    chroot = Path(__file__).absolute().parent
    state_file_name = Path(__file__).stem + '.state'
    state_file_path = chroot / state_file_name
    state_no = 0

    # get the current state
    try:
        with open(state_file_path, 'r') as fp:
            state_no = int(fp.read().strip())
    except IOError:
        pass
Exemplo n.º 4
0
from config import app_config  # pylint: disable=import-error
from logger import Logger  # pylint: disable=import-error
from pathlib import Path
from rabbitmq import Publisher  # pylint: disable=import-error

# initialize the logger so we see what happens
logger_path = Path(app_config.log.path)
logger = Logger(path=logger_path / Path(__file__).stem,
                level=int(app_config.log.level))

# intialize the Rabbit MQ connection
params = pika.ConnectionParameters(host='localhost')
publisher = Publisher(params)
publisher['queue'] = 'orders'
publisher['routing_key'] = 'orders.make'
logger.debug(
    'Initialized the Rabbit MQ connection: queue = {queue} / routing key = {routing_key}.'
    .format(queue=publisher['queue'], routing_key=publisher['routing_key']))

current_stamp = int(
    datetime.datetime.now(tz=datetime.timezone.utc).timestamp()) * 1000
#current_stamp = int(datetime.datetime(2020, 11, 20, 19, 20, 00, tzinfo = datetime.timezone.utc).timestamp() * 1000)

# send the Rabbit MQ message
logger.debug('Sending check orders message.')
publisher.publish({
    'stamp': current_stamp,
    'lookahead': int(app_config.orders.lookahead)
})
logger.debug('Sent check orders message.')
Exemplo n.º 5
0
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)