Add ability to propogate result of vote and making a vote.

This commit is contained in:
Michael Pivato
2019-03-01 15:44:58 +10:30
parent 0b04588161
commit ede1ec4500
3 changed files with 30 additions and 35 deletions

View File

@@ -1,33 +1,19 @@
import json import json
from DecisionSystem.messages import ConnectSwarm, SubmitVote, Message, deserialise, RequestVote from DecisionSystem.messages import ConnectSwarm, SubmitVote, Message, deserialise, RequestVote, ClientVoteRequest, VoteResult
from multiprocessing import Pool from multiprocessing import Pool
from messenger import Messenger from messenger import Messenger
class BallotVoter: class BallotVoter:
def __init__(self, on_vote, messenger: Messenger): def __init__(self, on_vote, handle_agreement, messenger: Messenger):
# Load config file
cfg = None
with open('config.json') as json_config:
cfg = json.load(json_config)
self._cfg = cfg
self.messenger = messenger self.messenger = messenger
self.messenger.add_message_callback(self.on_message) self.messenger.add_message_callback(self.on_message)
self.messenger.add_connect(self.on_connect) self.messenger.add_connect(self.on_connect)
self.on_vote = on_vote self.on_vote = on_vote
self.handle_agreement = handle_agreement
def on_connect(self, rc): def on_connect(self, rc):
print("Connected with result code " + str(rc)) print("Connected with result code " + str(rc))
# Should subscribes be handled by the messenger?
#self.client.subscribe('swarm1/voters', qos=1)
# Need to set a will as well to broadcast on unexpected disconnection, so commander
# knows it is no longer part of the set of voters.
# Leaving this until core centralised system is working.
#will_message = {"type": "UDisconnect"}
# Tell commander we are now connected. # Tell commander we are now connected.
self.send_connect() self.send_connect()
@@ -41,12 +27,8 @@ class BallotVoter:
self.submit_vote() self.submit_vote()
elif messageD.type == "listening": elif messageD.type == "listening":
self.send_connect() self.send_connect()
elif messageD.type == "disconnectedcommander": elif messageD.type == VoteResult.type:
# Elect new leader... self.handle_agreement(messageD.data["vote"])
# Might just use raft's method for electing a leader,
# by doing a random timeout then choosing itself as the candidate,
# and collects who is part of the swarm. This may need to be another class...
pass
def submit_vote(self): def submit_vote(self):
v = self.on_vote() v = self.on_vote()
@@ -59,15 +41,11 @@ class BallotVoter:
self.messenger.broadcast_message(self.messenger.swarm, vote.serialise()) self.messenger.broadcast_message(self.messenger.swarm, vote.serialise())
print('published vote') print('published vote')
def submit_vote_multicore(self):
'''
Uses multiple processes to work on multiple frames at the same time
to take an average for this voter, or if it could not find a hand
in one frame but can in another.
'''
pass
def send_connect(self): def send_connect(self):
# Send a connected message to let any commanders know that # Send a connected message to let any commanders know that
# it is available. # it is available.
self.messenger.broadcast_message(self.messenger.swarm, ConnectSwarm(self.messenger.id).serialise()) self.messenger.broadcast_message(self.messenger.swarm, ConnectSwarm(self.messenger.id).serialise())
def request_vote(self):
"""Sends a request to the leader to start collecting votes."""
self.messenger.broadcast_message(self.messenger.swarm, ClientVoteRequest(self.messenger.id).serialise())

View File

@@ -1,5 +1,5 @@
import time import time
from DecisionSystem.messages import Message, CommanderWill, RequestVote, GetSwarmParticipants, deserialise from DecisionSystem.messages import Message, CommanderWill, RequestVote, GetSwarmParticipants, deserialise, ClientVoteRequest, VoteResult
import json import json
import numpy as np import numpy as np
@@ -62,6 +62,7 @@ class Commander:
print("published message") print("published message")
time.sleep(self.timeout) time.sleep(self.timeout)
self._taking_votes = False self._taking_votes = False
# TODO: Work out how to broadcast votes back to the swarm, maybe using raft?
return self.make_decision() return self.make_decision()
def on_message(self, message): def on_message(self, message):
@@ -90,6 +91,9 @@ class Commander:
# Only add vote to list if the client has not already voted. # Only add vote to list if the client has not already voted.
if messageD.sender not in self._votes: if messageD.sender not in self._votes:
self._votes[messageD.sender] = int(messageD.data["vote"]) self._votes[messageD.sender] = int(messageD.data["vote"])
elif messageD.type == ClientVoteRequest().type:
# received a request to get votes/consensus.
self.get_votes()
elif messageD.type == "disconnected": elif messageD.type == "disconnected":
print("Voter disconnected :(") print("Voter disconnected :(")
@@ -110,3 +114,6 @@ class Commander:
def on_disconnect(self, rc): def on_disconnect(self, rc):
pass pass
def propogate_result(self, result):
self._messenger.broadcast_message(self._messenger.swarm, )

View File

@@ -89,3 +89,13 @@ class SubmitVote(Message):
class GetSwarmParticipants(Message): class GetSwarmParticipants(Message):
_type = "listening" _type = "listening"
class VoteResult(Message):
_type = "voteresult"
def __init__(self, vote, sender='', data={}):
super().__init__(sender=sender, data=data)
self._data["vote"] = vote
class ClientVoteRequest(Message):
_type = "clientvoterequest"