Initial implementation of an event_handler

This commit is contained in:
Rodolphe Marques 2017-03-28 16:05:44 +02:00 committed by vrde
parent b90766f2c5
commit 0cbf144ddf
No known key found for this signature in database
GPG Key ID: 6581C7C39B3D397D
4 changed files with 81 additions and 6 deletions

33
bigchaindb/events.py Normal file
View File

@ -0,0 +1,33 @@
from enum import Enum
from multiprocessing import Queue
class EventTypes(Enum):
BLOCK_VALID = 1
BLOCK_INVALID = 2
class Event(object):
def __init__(self, event_type, event_data):
self.type = event_type
self.data = event_data
class EventHandler(object):
def __init__(self, events_queue):
self.events_queue = events_queue
def put_event(self, event, timeout=None):
# TODO: handle timeouts
self.events_queue.put(event, timeout=None)
def get_event(self, timeout=None):
# TODO: handle timeouts
return self.events_queue.get(timeout=None)
def setup_events_queue():
# TODO: set bounds to the queue
return Queue()

View File

@ -13,6 +13,7 @@ from bigchaindb import backend
from bigchaindb.backend.changefeed import ChangeFeed from bigchaindb.backend.changefeed import ChangeFeed
from bigchaindb.models import Block from bigchaindb.models import Block
from bigchaindb import Bigchain from bigchaindb import Bigchain
from bigchaindb.events import EventHandler, Event, EventTypes
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -22,8 +23,9 @@ logger_results = logging.getLogger('pipeline.election.results')
class Election: class Election:
"""Election class.""" """Election class."""
def __init__(self): def __init__(self, events_queue):
self.bigchain = Bigchain() self.bigchain = Bigchain()
self.event_handler = EventHandler(events_queue)
def check_for_quorum(self, next_vote): def check_for_quorum(self, next_vote):
""" """
@ -42,6 +44,7 @@ class Election:
next_block = self.bigchain.get_block(block_id) next_block = self.bigchain.get_block(block_id)
result = self.bigchain.block_election(next_block) result = self.bigchain.block_election(next_block)
self.handle_block_events(result, block_id)
if result['status'] == self.bigchain.BLOCK_INVALID: if result['status'] == self.bigchain.BLOCK_INVALID:
return Block.from_dict(next_block) return Block.from_dict(next_block)
@ -67,9 +70,20 @@ class Election:
self.bigchain.write_transaction(tx) self.bigchain.write_transaction(tx)
return invalid_block return invalid_block
def handle_block_events(self, result, block_id):
if result['status'] == self.bigchain.BLOCK_UNDECIDED:
return
elif result['status'] == self.bigchain.BLOCK_INVALID:
event_type = EventTypes.BLOCK_INVALID
elif result['status'] == self.bigchain.BLOCK_VALID:
event_type = EventTypes.BLOCK_VALID
def create_pipeline(): event = Event(event_type, {'block_id': block_id})
election = Election() self.event_handler.put_event(event)
def create_pipeline(events_queue):
election = Election(events_queue)
election_pipeline = Pipeline([ election_pipeline = Pipeline([
Node(election.check_for_quorum), Node(election.check_for_quorum),
@ -84,8 +98,8 @@ def get_changefeed():
return backend.get_changefeed(connection, 'votes', ChangeFeed.INSERT) return backend.get_changefeed(connection, 'votes', ChangeFeed.INSERT)
def start(): def start(events_queue):
pipeline = create_pipeline() pipeline = create_pipeline(events_queue)
pipeline.setup(indata=get_changefeed()) pipeline.setup(indata=get_changefeed())
pipeline.start() pipeline.start()
return pipeline return pipeline

View File

@ -0,0 +1,14 @@
import multiprocessing as mp
from bigchaindb.events import EventHandler
def consume_events(events_queue):
event_handler = EventHandler(events_queue)
while True:
event = event_handler.get_event()
print('Event type: {} Event data: {}'.format(event.type, event.data))
def events_consumer(events_queue):
return mp.Process(target=consume_events, args=(events_queue,))

View File

@ -3,6 +3,8 @@ import multiprocessing as mp
import bigchaindb import bigchaindb
from bigchaindb.pipelines import vote, block, election, stale from bigchaindb.pipelines import vote, block, election, stale
from bigchaindb.pipelines.events_consumer_example import events_consumer
from bigchaindb.events import setup_events_queue
from bigchaindb.web import server from bigchaindb.web import server
@ -25,6 +27,13 @@ BANNER = """
def start(): def start():
logger.info('Initializing BigchainDB...') logger.info('Initializing BigchainDB...')
# Create the events queue
# The events queue needs to be initialized once and shared between
# processes. This seems the best way to do it
# At this point only the election processs and the event consumer require
# this queue.
events_queue = setup_events_queue()
# start the processes # start the processes
logger.info('Starting block') logger.info('Starting block')
block.start() block.start()
@ -36,12 +45,17 @@ def start():
stale.start() stale.start()
logger.info('Starting election') logger.info('Starting election')
election.start() election.start(events_queue)
# start the web api # start the web api
app_server = server.create_server(bigchaindb.config['server']) app_server = server.create_server(bigchaindb.config['server'])
p_webapi = mp.Process(name='webapi', target=app_server.run) p_webapi = mp.Process(name='webapi', target=app_server.run)
p_webapi.start() p_webapi.start()
# start the example events consumer
logger.info('Starting the events consumer example')
p_events_consumer = events_consumer(events_queue)
p_events_consumer.start()
# start message # start message
logger.info(BANNER.format(bigchaindb.config['server']['bind'])) logger.info(BANNER.format(bigchaindb.config['server']['bind']))