예제 #1
0
	def __init__(self, id: str, peer_count: int, server: object):
		# The following three variables need to survive on persistent storage.
		self.voted_for = 'null'
		self.log = Log(id)
		self.term = self.log.get_entry(len(self.log)-1).term

		# volitile variables:
		self.id = id
		self.server = server
		self.peers = [str(x) for x in range(0, peer_count) if x != int(self.id)]
		self.election_state = 'follower'
		self.timer_length = 4
		self.vote_count = 0
		self.reply_status = {}

		self.commitIndex = 0
		self.lastApplied = 0

		self.nextIndex = None
		self.matchIndex = None
		self.reset_next_and_match()

		self.messenger = Messenger(self.id, self, run=True)
		self.election_timer = Election_Timer(self.timer_length, self)
		self.heartbeat = Heartbeat(self.timer_length, self)
예제 #2
0
  def test_build_result3(self, result_mock):
    config = AgentConfig("", "")
    config.set('agent', 'prefix', 'tmp')
    dummy_controller = MagicMock()
    actionQueue = ActionQueue(config, dummy_controller, self.agentToggleLogger)
    result_mock.return_value = {
      'reports': [{'status': 'COMPLETED',
                   'stderr': 'Read from /tmp/errors-3.txt',
                   'stdout': 'Read from /tmp/output-3.txt',
                   'clusterName': u'cc',
                   'roleCommand': u'INSTALL',
                   'serviceName': u'HDFS',
                   'role': u'DATANODE',
                   'actionId': '1-1',
                   'taskId': 3,
                   'exitcode': 777,
                   'reportResult' : False}
      ],
      'componentStatus': []
    }
    heartbeat = Heartbeat(actionQueue, config, self.agentToggleLogger)

    commandResult = {}
    hb = heartbeat.build(commandResult, 10)
    hb['hostname'] = 'hostname'
    hb['timestamp'] = 'timestamp'
    hb['fqdn'] = 'fqdn'
    expected = {'nodeStatus':
                  {'status': 'HEALTHY',
                   'cause': 'NONE'},
                'timestamp': 'timestamp', 'hostname': 'hostname', 'fqdn': 'fqdn',
                'responseId': 10, 'reports': []}
    self.assertEqual.__self__.maxDiff = None
    self.assertEquals(hb, expected)
    self.assertEquals(commandResult, {'commandStatus': 'COMPLETED'})
예제 #3
0
    def __init__(self, db):
        # Call the parent class (Sprite) constructor
        super().__init__()

        alarm_ref = db.collection(u'Users').document(
            'y2wiAwN8e1e52SWtvVD3BNFiWGu2').collection('People').document(
                'Indy').collection('Sensors').document('alarmCheck')
        try:
            alarm = alarm_ref.get()
            val = format(alarm.to_dict()['alarm'])
            print(val)

            if val == 'True':
                print('alarm on')
                Led(0)
                print('alarm off')
                Led(1)
                print('alarm off')
                Buzz(1)
                Heartbeat(db, 100, 113)  # hier de hogere waarden
            else:
                Led(1)
                Buzz(0)
                print('he')
                Heartbeat(db, 61, 99)  # hier de lagere waarden

            time.sleep(1)

        except google.cloud.exceptions.NotFound:
            print(
                u'No AlarmCheck document was found, check your firestore database!'
            )
예제 #4
0
    def __init__(self, id: str):
        self.replica_count = 5
        self.id = id
        self.peers = [
            str(x) for x in range(0, self.replica_count) if x != int(self.id)
        ]
        self.election_state = 'follower'
        self.timer_length = 4
        self.current_term = 0
        self.voted_for = 'Null'
        self.vote_count = 0

        self.messenger = Messenger(self.id, self)
        self.election_timer = Election_Timer(self.timer_length, self)
        self.heartbeat = Heartbeat(self.timer_length, self)
예제 #5
0
 def __init__(self, config, range=30):
     threading.Thread.__init__(self)
     logger.debug('Initializing Controller RPC thread.')
     self.lock = threading.Lock()
     self.safeMode = True
     self.credential = None
     self.config = config
     self.hostname = hostname.hostname()
     server_secured_url = 'https://' + config.get(
         'server', 'hostname') + ':' + config.get('server',
                                                  'secured_url_port')
     self.registerUrl = server_secured_url + '/agent/v1/register/' + self.hostname
     self.unregisterUrl = server_secured_url + '/agent/v1/unregister/' + self.hostname
     self.heartbeatUrl = server_secured_url + '/agent/v1/heartbeat/' + self.hostname
     self.netutil = NetUtil()
     self.responseId = -1
     self.repeatRegistration = False
     self.cachedconnect = None
     self.range = range
     self.hasMappedComponents = True
     self.actionQueue = ActionQueue(self.config)
     self.actionQueue.start()
     self.register = Register(self.config)
     self.unregister = Unregister(self.config)
     self.heartbeat = Heartbeat(self.actionQueue, self.config)
예제 #6
0
def gen(camera, hb, mode):
    if not hb.is_alive():
        hb = Heartbeat(cam)
        hb.start()

    if mode == "Face":
        mode = Camera.FACE
    elif mode == "Motion":
        mode = Camera.MOTION
    else:
        mode = None

    log.debug("Generating a jpeg")
    """Video streaming generator function."""
    while True:
        frame, PoI = cam.get_current_jpeg(mode)  #(Camera.FACE)
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
예제 #7
0
    def test_build_result3(self, result_mock):
        config = AgentConfig("", "")
        config.set('agent', 'prefix', 'tmp')
        dummy_controller = MagicMock()
        actionQueue = ActionQueue(config, dummy_controller,
                                  self.agentToggleLogger)
        result_mock.return_value = {
            'reports': [{
                'status': 'COMPLETED',
                'stderr': 'Read from /tmp/errors-3.txt',
                'stdout': 'Read from /tmp/output-3.txt',
                'clusterName': u'cc',
                'roleCommand': u'INSTALL',
                'serviceName': u'HDFS',
                'role': u'DATANODE',
                'actionId': '1-1',
                'taskId': 3,
                'exitcode': 777,
                'reportResult': False
            }],
            'componentStatus': []
        }
        heartbeat = Heartbeat(actionQueue, config, self.agentToggleLogger)

        commandResult = {}
        hb = heartbeat.build(commandResult, 10)
        hb['hostname'] = 'hostname'
        hb['timestamp'] = 'timestamp'
        hb['fqdn'] = 'fqdn'
        expected = {
            'package': '',
            'nodeStatus': {
                'status': 'HEALTHY',
                'cause': 'NONE'
            },
            'timestamp': 'timestamp',
            'hostname': 'hostname',
            'fqdn': 'fqdn',
            'responseId': 10,
            'reports': []
        }
        self.assertEqual.__self__.maxDiff = None
        self.assertEquals(hb, expected)
        self.assertEquals(commandResult, {'commandStatus': 'COMPLETED'})
예제 #8
0
파일: Core.py 프로젝트: mswiders1/multitalk
 def __init__(self,  __reactor):
     print "Core: swiat jest piekny ;)"
     self.__tcpm = None
     self.__messageStore = MessageInfoStore()
     self.__model = None
     self.__gui = None
     self.__reactor = __reactor
     self.__broadcastStarted = False
     self.heartbeat = Heartbeat(self)
     self.__lookForDead = LoopingCall(self.lookForDeadNodes)
     self.__lookForDeadStarted = False
     return 
예제 #9
0
 def test_build(self):
   config = AgentConfig("", "")
   config.set('agent', 'prefix', 'tmp')
   dummy_controller = MagicMock()
   actionQueue = ActionQueue(config, dummy_controller)
   heartbeat = Heartbeat(actionQueue, config)
   result = heartbeat.build({}, 100)
   print "Heartbeat: " + str(result)
   self.assertEquals(result['hostname'] != '', True,
                     "hostname should not be empty")
   self.assertEquals(result['responseId'], 100)
   self.assertEquals('componentStatus' not in result, True,
                     "Heartbeat should contain componentStatus")
   self.assertEquals(result['reports'] is not None, True,
                     "Heartbeat should contain reports")
   self.assertEquals(result['timestamp'] >= 1353679373880L, True)
   self.assertEquals(len(result['nodeStatus']), 2)
   self.assertEquals(result['nodeStatus']['cause'], "NONE")
   self.assertEquals(result['nodeStatus']['status'], "HEALTHY")
   # result may or may NOT have an agentEnv structure in it
   self.assertEquals((len(result) is 5) or (len(result) is 6), True)
   self.assertEquals(not heartbeat.reports, True,
                     "Heartbeat should not contain task in progress")
예제 #10
0
 def test_build(self):
     config = AgentConfig("", "")
     config.set('agent', 'prefix', 'tmp')
     dummy_controller = MagicMock()
     actionQueue = ActionQueue(config, dummy_controller)
     heartbeat = Heartbeat(actionQueue, config)
     result = heartbeat.build({}, 100)
     print "Heartbeat: " + str(result)
     self.assertEquals(result['hostname'] != '', True,
                       "hostname should not be empty")
     self.assertEquals(result['responseId'], 100)
     self.assertEquals('componentStatus' not in result, True,
                       "Heartbeat should contain componentStatus")
     self.assertEquals(result['reports'] is not None, True,
                       "Heartbeat should contain reports")
     self.assertEquals(result['timestamp'] >= 1353679373880L, True)
     self.assertEquals(len(result['nodeStatus']), 2)
     self.assertEquals(result['nodeStatus']['cause'], "NONE")
     self.assertEquals(result['nodeStatus']['status'], "HEALTHY")
     # result may or may NOT have an agentEnv structure in it
     self.assertEquals((len(result) is 6) or (len(result) is 7), True)
     self.assertEquals(not heartbeat.reports, True,
                       "Heartbeat should not contain task in progress")
예제 #11
0
    def __init__(self, _id: str):
        """
        Constructor for leader election.
        Main class to elect which node becomes leader.

        :param _id: str. Which node this object belongs to.
        """
        self._id = _id
        self.nodes = ['0', '1', '2', '3']
        self.peers = [node for node in self.nodes if node != self._id]

        self.term = 0
        self.election_state = 'follower'
        self.current_leader = ''
        self.timer_length = 3
        self.vote_count = 0
        self.voted_for = 'null'
        self.vote_received_from = {}
        self.reset_votes_received()

        self.m = Messenger(self._id, self)
        self.e = ElectionTimer(self.timer_length, self)
        self.h = Heartbeat(self.timer_length, self)
예제 #12
0
class App:
    """
    Main App class.
    Author: Stanislav Grebennik

    Launches the app, initializes Config, Messenger and Heartbeat classes.
    """
    def __init__(self):
        self.config = Config()
        self.messenger = Messenger(self.config)
        self.heartbeat = Heartbeat(self.config, self.messenger)
        self.heartbeat_seconds = self.config.local_getter("heartbeat_seconds")
        self.logger = self.config.get_logger(name=__name__)

    def main(self):
        print(
            "Chat app. Type '!help' for usage information, '!exit' to exit the app."
        )
        self.logger.info("Chat app is launched")
        self.logger.info(
            f'Listening for connections on {self.config.root_node.sock}...')

        while True:
            rsocks, wsocks, esocks = select.select(self.config.rlist, [],
                                                   self.config.rlist,
                                                   self.heartbeat_seconds)

            if not rsocks and not wsocks:
                self.heartbeat.run_routine()
                continue

            for notified_socket in rsocks:
                if notified_socket == sys.stdin:
                    self.messenger.parse_user_input()

                else:
                    self.messenger.process_incoming_message(notified_socket)
예제 #13
0
class ConsensusModule:
	''' Constructor. Takes id of node (str) and number of peers (int) as

	:param peer_count: int. number of peers in cluster. 

	PERSISTENT STORAGE:

	:var .term: int.       monotonic counter for cluster term. init at 0
	:var .voted_for:       string. records who this node voted for in election.
	:var .log:			   list. contains the replicated log. 

	VOLITILE STATE ON ALL SERVERS

	:var .id:              string. Takes id from list '0', '1', '2', '3', '4'
	:var .peers:           list of peer IDs in cluster.
	:var .election_state:  string. 'leader' 'candidate' or 'follower'
	:var .timer_length:    float. duration of election timer in seconds (default: .15)
	:var .vote_count:      int. Store number of votes received. Majority -> leader
	:var .reply_status:	   track which peers have replied to vote or append requests.
	
	:var .commitIndex: 	   int. index of highest log entry known to be committed.
	:var .lastApplied:     int. index of highest log entry applied to state machine. 

	VOLITILE STATE ON LEADER (reinit after election):

	:var .nextIndex: 	   int. As leader: index of next log entry to send to each server
	:var .matchIndex:      int. As leader: index of highest log entry known to be relicated on each server
	
	HELPER CLASSES:

	:var .messenger:       Messenger. takes care of all messaging between nodes
	:var .election_timer:  ElectionTimer. Timer thread to start election
	:var .heartbeat:       Heartbeat. Timer thread to send hearbeats when leader. 
	'''

	def __init__(self, id: str, peer_count: int, server: object):
		# The following three variables need to survive on persistent storage.
		self.voted_for = 'null'
		self.log = Log(id)
		self.term = self.log.get_entry(len(self.log)-1).term

		# volitile variables:
		self.id = id
		self.server = server
		self.peers = [str(x) for x in range(0, peer_count) if x != int(self.id)]
		self.election_state = 'follower'
		self.timer_length = 4
		self.vote_count = 0
		self.reply_status = {}

		self.commitIndex = 0
		self.lastApplied = 0

		self.nextIndex = None
		self.matchIndex = None
		self.reset_next_and_match()

		self.messenger = Messenger(self.id, self, run=True)
		self.election_timer = Election_Timer(self.timer_length, self)
		self.heartbeat = Heartbeat(self.timer_length, self)


	def set_follower(self, term: int):
		''' Set the consensus module election state to 'follower', reset variables.
		:param term: int, included for when an incoming term is discovered greater than own. 
		'''
		self.election_state = 'follower'
		self.term = term  # update term to newly discovered term
		self.vote_count = 0  # followers do not have votes, reset to 0
		self.voted_for = 'null'  # a new follwer has yet to vote for another peer
		self.election_timer.restart_timer()  # reset election countdown
		self.heartbeat.stop_timer()  # stop the heartbeat, only leaders send them
		self.server.turn_off_leader_queue()
		#print('\n', self.id, ' Set state to follower, setting term to: ', self.term)

	def set_leader(self):
		'''Set the consensus module election state to 'leader', change timers '''
		#print('\n', self.id, ' Set state to leader')
		self.election_state = 'leader'
		self.election_timer.stop_timer()  # pause the election timer, leader will remain leader
		self.reset_next_and_match()
		self.send_heartbeat()  # immediately send heartbeat to peers
		self.heartbeat.restart_timer()  # continue sending heartbeat on interval
		self.server.turn_on_leader_queue()

	def reset_next_and_match(self):
			#print("lenght of log: ", len(self.log))
			self.nextIndex = dict.fromkeys(self.peers, len(self.log))
			#print('nextIndex initialized to length of current log :', self.nextIndex)
			self.matchIndex = dict.fromkeys(self.peers, 0)

	def start_election(self):  # this is equivalent to "set_candidate()"
		'''Set election state to 'candidate', vote for self, and request votes
		for leadership
		'''
		#if self.election_state != 'candidate':
			# print('\n', self.id, ' set state to candidate')
		self.heartbeat.stop_timer()
		self.election_state = 'candidate'
		self.term+= 1 # starting an election increments the term
		self.voted_for = self.id # vote for self
		self.vote_count = 1 # count of self vote
		#self.heartbeat.restart_timer() # use heartbeat to re-send vote request at interval
		for peer in self.peers: #set reply status to track who responds to votes
			self.reply_status[peer] = False
		self.request_votes() # request votes of all other 
		

	def request_votes(self):
		'''Make a vote request message and send to all peers. Used by candidate '''
		request = self.make_message('request votes')
		for peer, replied in self.reply_status.items(): # only send requests to those not replied already
			if not replied:
				self.messenger.send(request, peer)
				#print(self.id, ' Requesting Vote from: ', peer, ' Term: ', self.term)
		
	def send_heartbeat(self):
		'''Make a heartbeat message and send it to all peers. Used by leader'''	
		if self.election_state == 'leader':
			for peer in self.peers:  # send to peers
				entries_string = self.log.get_entries_string(self.nextIndex[peer])
				if not entries_string:
					entries_string = 'heartbeat'
				heartbeat = self.make_message('heartbeat', entries=entries_string, destination=peer)
				#print('Append entries: ', heartbeat)
				self.messenger.send(heartbeat, peer)

	def handle_incoming_message(self, message: dict):
		message_type = message['messageType']
		incoming_term = int(message['term'])
		if (incoming_term > self.term):
			self.set_follower(incoming_term)
			#print(self.id, ' greater term detected, setting state to follower.')
		# print(
		# 	'\n**** Message Received: {}\n'.format(message), " self term: ", 
		# 	self.term, " self state: ", self.election_state
		# 	)
		if message_type == 'AppendEntriesRPC':
			self.receive_append_entry_request(message)
		elif message_type == 'AppendReply':
			self.receive_append_entry_reply(message)
		elif message_type == 'RequestVotesRPC':
			self.receive_vote_request(message)
		elif message_type == 'VoteReply':
			self.receive_vote_reply(message)
			

	def receive_append_entry_request(self, message: dict):
		'''
		This method processes append entry requests. Outcomes: For every appendRPC
		reset the election timer. If a higher term is discovered, revert to
		follower. Append any new entries to the log. If incoming log entry
		conflicts with existing entry at same index, delete existing entry and 
		all that follow. Set commit index to be min(leaderCommit, index of last 
		new entry). 
		
		more details to follow later'''
		self.election_timer.duration = self.timer_length/4
		leader = message['leaderID']
		incoming_term = int(message['term'])
		#print("****HEREHEREHRER ***", message['entries'])
		entries = self.log.parse_entries_to_list(message['entries'])

		leaderCommit = int(message['leaderCommit'])
		prevLogIndex = int(message['prevLogIndex'])
		prevLogTerm = int(message['prevLogTerm'])
		prevLogCommand = message['prevLogCommand']
		# special scenario for converting to follower: 
		if incoming_term == self.term and self.election_state == 'candidate':
			self.set_follower(incoming_term)
			#print(self.id, ' leader of greater or equal term detected as candidate, setting state to follower.')
		
		# reset election timer
		#print('\n', self.id, ' received append entry request from ', leader, ': \n',  message)
		if (self.election_state == 'follower'):
			self.election_timer.restart_timer()

		success, match = self.process_AppendRPC(
			entries=entries, 
			leaderCommit=leaderCommit, 
			prevLogIndex=prevLogIndex, 
			prevLogTerm=prevLogTerm,
			prevLogCommand=prevLogCommand
			)
		#print(success, match, '=================================')
		reply = self.make_message('reply to append request', success=success)
		self.messenger.send(reply, leader)
			
		#print('\n', self.id, ' replied to append request')

	def process_AppendRPC(self, entries: list, leaderCommit: int, prevLogIndex: int,
								prevLogTerm: int, prevLogCommand: str)-> (bool, int):
		# if logs are inconsistent or out of term, reply false
		# if (not self.log.idx_exist(prevLogIndex) ):
		# 	print("no log entry at prev log index")
		# elif (self.log.get_entry(prevLogIndex).term != prevLogTerm):
		# 	print("previous log entry not same term as incoming")
		# elif (self.log.get_entry(prevLogIndex).command != prevLogCommand):
		# 	print("command at prev log index does not match incoming")

		#reply false if log doesn’t contain an entry at prevLogIndex whose 
		# term matches prevLogTerm (§5.3)
		if ((not self.log.idx_exist(prevLogIndex))
			or (self.log.get_entry(prevLogIndex).term != prevLogTerm)):
			#or (self.log.get_entry(prevLogIndex).command != prevLogCommand)): 
			return False, 0
		# otherwise, check if outdated entry exists in initial append spot. 
		# if so, delete that entry and all following
		else:
			if self.log.idx_exist(prevLogIndex+1):
				self.log.rollback(prevLogIndex+1)
			# Append the new entries to the log
			for entry in entries:
				self.log.append_to_end(entry)
			#update the commit index of this server, equal to leader or last applied
			# whichever is smaller
			if leaderCommit > self.commitIndex:
				self.commitIndex = min(leaderCommit, len(self.log)-1)
			# return True and tell leader index of last applied to update match
			return True, len(self.log)-1



	def receive_append_entry_reply(self, message: dict):
		'''
		This method processes replies from followers. If successful, update nextIndex
		and matchIndex for follower. If failed, decrement nextIndex for follower
		and try again. 
		'''
	
		incoming_term = int(message['term'])
		if incoming_term > self.term:
			self.set_follower(incoming_term)  # set state to follower
			#print(self.id, ' greater term/leader detected, setting state to follower.')

		follower = message['senderID']
		success = bool(message['success'])
		incoming_match = int(message['match'])
		# only do the following if we are currently leader. 
		if self.election_state == 'leader':
			if success: # follower is up to date
				self.matchIndex[follower] = incoming_match
				self.nextIndex[follower] = incoming_match + 1
			else: # follower is not up to date, decrement index for next time
				if self.nextIndex[follower] > 1: # next index should never be less than 1
					self.nextIndex[follower] -= 1

			#############################
			# Commit available entries: #
			#############################
			N = self.commitIndex + 1
			if self.log.idx_exist(N): # if an entry exists to commit
				# print('log entry to be committed exists')
				# collect the number of peers that have replicated entry N
				match_count = 0
				for peer in self.peers: 
					if self.matchIndex[peer] >= N:
						match_count += 1 
				#print("match count: ", match_count, " log term: ", self.log.get_entry(N).term)
				# If there exists an N such that N > commitIndex, a majority of 
				# matchIndex[i] ≥ N, and log[N].term == currentTerm:
				# set commitIndex = N (§5.3, §5.4).
				if (self.log.get_entry(N).term == self.term 
						and match_count + 1 > math.floor(len(self.peers) / 2)):
					# if that entry is the correct term, and if a majority of 
					# servers have replicated that entry, commit that entry. 
					#print("increment commit index")
					self.commitIndex = N

		#print('\n', self.id, ' received append entries reply :', message)

	def receive_vote_request(self, message: dict):
		'''
		this method processes RequestVoteRPCs. If the incomingTerm < self.term, 
		reply false. If self.votedFor is 'null' or equal to requesting candidate, 
		*and* the candidate's log is at least as up to date as self, grant vote. 
		'''
		candidate = message['candidateID']
		incoming_term = int(message['term'])
		#print('\n', self.id, ' received vote request from ', candidate, ': \n')

		if incoming_term > self.term:  # as always, check for greater term, set to follower if true
			self.set_follower(incoming_term)  # set state to follower
			#print(self.id, ' greater term detected, setting state to follower.')

		# TODO: if candidate log shorter than self, reply false

		if self.voted_for == 'null':  # && candidate log is at least as up to date as self:
			# at least as up to date is defined as: 
			# term of incoming last log entry is equal or greater than self. 
			# if equal term, index of incoming last log entry is equal or greater than self. 
			self.voted_for = candidate
			#print('\n', self.id, ' voted for ', self.voted_for)

		voteGranted = False
		if self.voted_for == candidate:
			voteGranted = True

		reply = self.make_message('reply to vote request', voteGranted= voteGranted)
		self.messenger.send(reply, candidate)
		
		#print('\n', self.id, ' replied ', reply['voteGranted'], ' to ', candidate, ' request for votes')

	def receive_vote_reply(self, message: dict):

		vote_granted = message['voteGranted']  # store value of vote received
		sender = message['senderID']
		incoming_term = int(message['term'])
		#print(self.id, ' received vote reply: ', vote_granted, ' from ', sender)

		if self.election_state == 'candidate' and incoming_term == self.term:
			if not self.reply_status[sender]:
				self.reply_status[sender] = True  # mark sender as having replied
				if vote_granted == 'True':
					self.vote_count += 1
					#print('\n', self.id, ' vote count = ', self.vote_count)
				#print('votes needed: ', math.floor(len(self.peers) / 2) + 1)
				if self.vote_count > math.floor(len(self.peers) / 2):
					self.set_leader()
					#print('\n', self.id, ' majority votes acquired')

	def make_message(self, message_type: str, voteGranted:bool = False, 
	success: bool = False, entries: str = '[]', destination = '') -> dict:
		'''
		options: 'heartbeat', 'reply to append request', 'request votes', 
		'reply to vote request'. returns a dictionary
		Include destination with reply to vote request. 
		'''
		if message_type == 'heartbeat':
			prevLogIndex = self.nextIndex[destination]-1
			#print("make heartbeat. NextIndex: ", self.nextIndex[destination])
			prevLog = self.log.get_entry(prevLogIndex)
			message = {
				'messageType': 	'AppendEntriesRPC',
				'leaderID': 	self.id,
				'term': 		str(self.term),
				'entries'		:	entries,
				'prevLogIndex' : str(prevLogIndex), 
				'prevLogTerm' : str(prevLog.term),
				'prevLogCommand': str(prevLog.command),
				'leaderCommit' : str(self.commitIndex),
				'nextIndex' : str(self.nextIndex[destination])
			}
		elif message_type == 'reply to append request':
			message = {
				'messageType':	'AppendReply',
				'senderID':		self.id,
				'term':			str(self.term),
				'match':		str(len(self.log)-1), #return index of last appended entry if true
				'success' : 	str(success)
			}
		elif message_type == 'request votes':
			message = {
				'messageType':	'RequestVotesRPC',
				'term':			str(self.term),
				'candidateID':	self.id
				#'lastLogIndex': {'value': self.lastLogIndex},
				#'lastLogTerm': {'value': self.lastLogTerm}
			}
		elif message_type == 'reply to vote request':
			message = {
				'messageType': 	'VoteReply',
				'senderID':		self.id,
				'term':			str(self.term),
				'voteGranted':	str(voteGranted)
			}
		else:
			print('you f****d up')
		return message

	def add_client_command_to_log(self, command: str):
		self.log.append_to_end(LogEntry(self.term, command))

	def get_command(self, idx)-> dict:
		command_str = self.log.get_entry(idx).command
		command = ast.literal_eval(command_str)
		return command
	
	def simulation_print(self):
		node = f"Node:\t\t{self.id}\n"
		term = f"Term:\t\t{str(self.term)}\n"
		commitIndex = f"Commit Index:\t{str(self.commitIndex)}\n"
		electionState = f"Election State:\t{self.election_state}\n"
		votedFor = f"Voted For:\t{self.voted_for}\n"
		voteCount = f"Vote Count:\t{str(self.vote_count)}\n"

		
		loglen = len(self.log)
		display_width = 13
		log_height = 7
		log_contents = ''
		if self.election_state != 'leader':
			log_contents += f'\nLog Contents: (Most Recent {log_height:d} Logs)\n'
			log_contents += '--------'*8 +'\n'
			log_contents += "Index\tTerm\tCommand\n"
			log_contents += '--------'*8 +'\n'
			if loglen <= log_height:
				for x in range(0, loglen):
					log_contents += str(x) +'\t' + str(self.log.get_entry(x)) + '\n'
			else:
				for x in range(loglen-log_height, loglen):
					log_contents += str(x) +'\t' + str(self.log.get_entry(x)) + '\n'

		header1 = ''
		header2 = ''
		peerStatusHeader = ''
		peerStatus = ''
		peerStatus2 = ''
		if self.election_state == 'leader':
			level1 = False
			level2 = False
			for peer in self.peers:
				if self.matchIndex[peer]<= display_width-1:
					level1 = True
				else: 
					level2 = True
			if level1:
				header1 = '----------' + '--------'*display_width +'\n'+"Index: "
				for x in range(0, display_width + 1): 
					header1 += '\t ' + str(x)
				header1 += '\n' + '----------' + '--------'*display_width+'\n'
			if level2:
				#if loglen > display_width:
				header2 = '----------' + '--------'*display_width +'\n'+"Index: "
				for x in range(display_width, 2*display_width+1): 
					header2 += '\t ' + str(x)
				header2 += '\n' + '----------' + '--------'*display_width+'\n'
			
			peerStatusHeader = '\nFollower Match * and Next ^ Indices:\n'

			for peer in self.peers:
				match = self.matchIndex[peer]
				next = self.nextIndex[peer]
				if match <= display_width-1:
					peerStatus += 'Node ' + peer + ':'
					mtab = '\t'*(match+1)
					ntab=''
					ntab2=''
					rtrn=''
					if next <= display_width:
						ntab = '\t'*(next - match) + ' ^\n'
					else:
						rtrn += '\n'
						peerStatus2+= 'Node ' + peer + ':'
						ntab2 = '\t'*(next+1 - display_width) + ' ^\n'
						peerStatus2 += ntab2
					peerStatus += mtab + ' *' + rtrn  + ntab 
				else:
					peerStatus2 += 'Node ' + peer + ':'
					mtab = '\t'*(match+1 - display_width)
					ntab = '\t'*(next - match) + ' ^\n'
					peerStatus2 += mtab + ' *' + ntab 

		status = (node + term + commitIndex + electionState+  
				 log_contents + peerStatusHeader + header1 + peerStatus + header2 + peerStatus2)
		
		file = open(f"../files/status{self.id}.txt", 'w')
		file.write(status)
		file.close()
예제 #14
0
 def __init__(self):
     self.config = Config()
     self.messenger = Messenger(self.config)
     self.heartbeat = Heartbeat(self.config, self.messenger)
     self.heartbeat_seconds = self.config.local_getter("heartbeat_seconds")
     self.logger = self.config.get_logger(name=__name__)
예제 #15
0
  def test_build_long_result(self, result_mock):
    config = AgentConfig("", "")
    config.set('agent', 'prefix', 'tmp')
    dummy_controller = MagicMock()
    actionQueue = ActionQueue(config, dummy_controller)
    result_mock.return_value = {
      'reports': [{'status': 'IN_PROGRESS',
                   'stderr': 'Read from /tmp/errors-3.txt',
                   'stdout': 'Read from /tmp/output-3.txt',
                   'clusterName': u'cc',
                   'roleCommand': u'INSTALL',
                   'serviceName': u'HDFS',
                   'role': u'DATANODE',
                   'actionId': '1-1',
                   'taskId': 3,
                   'exitcode': 777},

                  {'status': 'COMPLETED',
                   'stderr': 'stderr',
                   'stdout': 'out',
                   'clusterName': 'clusterName',
                   'roleCommand': 'UPGRADE',
                   'serviceName': 'serviceName',
                   'role': 'role',
                   'actionId': 17,
                   'taskId': 'taskId',
                   'exitcode': 0},

                  {'status': 'FAILED',
                   'stderr': 'stderr',
                   'stdout': 'out',
                   'clusterName': u'cc',
                   'roleCommand': u'INSTALL',
                   'serviceName': u'HDFS',
                   'role': u'DATANODE',
                   'actionId': '1-1',
                   'taskId': 3,
                   'exitcode': 13},

                  {'status': 'COMPLETED',
                   'stderr': 'stderr',
                   'stdout': 'out',
                   'clusterName': u'cc',
                   'configurationTags': {'global': {'tag': 'v1'}},
                   'roleCommand': u'INSTALL',
                   'serviceName': u'HDFS',
                   'role': u'DATANODE',
                   'actionId': '1-1',
                   'taskId': 3,
                   'exitcode': 0}

      ],
      'componentStatus': [
        {'status': 'HEALTHY', 'componentName': 'DATANODE', 'reportResult' : True},
        {'status': 'UNHEALTHY', 'componentName': 'NAMENODE', 'reportResult' : True},
        {'status': 'UNHEALTHY', 'componentName': 'HBASE_MASTER', 'reportResult' : False},
      ],
    }
    heartbeat = Heartbeat(actionQueue, config)
    hb = heartbeat.build({}, 10)
    hb['hostname'] = 'hostname'
    hb['timestamp'] = 'timestamp'
    hb['fqdn'] = 'fqdn'
    expected = {'nodeStatus':
                  {'status': 'HEALTHY',
                   'cause': 'NONE'},
                'timestamp': 'timestamp', 'hostname': 'hostname', 'fqdn': 'fqdn',
                'responseId': 10, 'reports': [
      {'status': 'IN_PROGRESS', 'roleCommand': u'INSTALL',
       'serviceName': u'HDFS', 'role': u'DATANODE', 'actionId': '1-1',
       'stderr': 'Read from /tmp/errors-3.txt',
       'stdout': 'Read from /tmp/output-3.txt', 'clusterName': u'cc',
       'taskId': 3, 'exitcode': 777},
      {'status': 'COMPLETED', 'roleCommand': 'UPGRADE',
       'serviceName': 'serviceName', 'role': 'role', 'actionId': 17,
       'stderr': 'stderr', 'stdout': 'out', 'clusterName': 'clusterName',
       'taskId': 'taskId', 'exitcode': 0},
      {'status': 'FAILED', 'roleCommand': u'INSTALL', 'serviceName': u'HDFS',
       'role': u'DATANODE', 'actionId': '1-1', 'stderr': 'stderr',
       'stdout': 'out', 'clusterName': u'cc', 'taskId': 3, 'exitcode': 13},
      {'status': 'COMPLETED', 'stdout': 'out',
       'configurationTags': {'global': {'tag': 'v1'}}, 'taskId': 3,
       'exitcode': 0, 'roleCommand': u'INSTALL', 'clusterName': u'cc',
       'serviceName': u'HDFS', 'role': u'DATANODE', 'actionId': '1-1',
       'stderr': 'stderr'}],  'componentStatus': [
      {'status': 'HEALTHY', 'componentName': 'DATANODE'},
      {'status': 'UNHEALTHY', 'componentName': 'NAMENODE'}]}
    self.assertEquals(hb, expected)
예제 #16
0
파일: Controller.py 프로젝트: sreev/ambari
 def start(self):
   self.actionQueue = ActionQueue(self.config)
   self.actionQueue.start()
   self.heartbeat = Heartbeat(self.actionQueue)
예제 #17
0
파일: Controller.py 프로젝트: sreev/ambari
class Controller(threading.Thread):

  def __init__(self, config):
    threading.Thread.__init__(self)
    logger.debug('Initializing Controller RPC thread.')
    self.lock = threading.Lock()
    self.safeMode = True
    self.credential = None
    self.config = config
    #Disabled security until we have fix for AMBARI-157
    #if(config.get('controller', 'user')!=None and config.get('controller', 'password')!=None):
    #  self.credential = { 'user' : config.get('controller', 'user'),
    #                      'password' : config.get('controller', 'password')
    #  }
    self.url = config.get('controller', 'url') + '/agent/controller/heartbeat/' + socket.gethostname()

  def start(self):
    self.actionQueue = ActionQueue(self.config)
    self.actionQueue.start()
    self.heartbeat = Heartbeat(self.actionQueue)

  def __del__(self):
    logger.info("Controller connection disconnected.")

  def run(self):
    id='-1'
    if self.credential!=None:
      auth_handler = urllib2.HTTPBasicAuthHandler()
      auth_handler.add_password(realm="Controller",
                                uri=self.url,
                                user=self.credential['user'],
                                passwd=self.credential['password'])
      opener = urllib2.build_opener(auth_handler)
      urllib2.install_opener(opener)
    retry=False
    firstTime=True
    while True:
      try:
        if retry==False:
          data = json.dumps(self.heartbeat.build(id))
          logger.debug(data)
        req = urllib2.Request(self.url, data, {'Content-Type': 'application/json'})
        f = urllib2.urlopen(req)
        response = f.read()
        f.close()
        data = json.loads(response)
        id=int(data['responseId'])
        self.actionQueue.put(data)
        if retry==True or firstTime==True:
          logger.info("Controller connection established")
          firstTime=False
        retry=False
      except Exception, err:
        retry=True
        if "code" in err:
          logger.error(err.code)
        else:
          logger.error("Unable to connect to: "+self.url,exc_info=True)
      if self.actionQueue.isIdle():
        time.sleep(30)
      else:
        time.sleep(1)
예제 #18
0
 def test_build_long_result(self, result_mock):
     config = AgentConfig("", "")
     config.set('agent', 'prefix', 'tmp')
     dummy_controller = MagicMock()
     actionQueue = ActionQueue(config, dummy_controller,
                               self.agentToggleLogger)
     result_mock.return_value = {
         'reports': [{
             'status': 'IN_PROGRESS',
             'stderr': 'Read from /tmp/errors-3.txt',
             'stdout': 'Read from /tmp/output-3.txt',
             'clusterName': u'cc',
             'roleCommand': u'INSTALL',
             'serviceName': u'HDFS',
             'role': u'DATANODE',
             'actionId': '1-1',
             'taskId': 3,
             'exitcode': 777,
             'reportResult': True
         }, {
             'status': 'COMPLETED',
             'stderr': 'stderr',
             'stdout': 'out',
             'clusterName': 'clusterName',
             'roleCommand': 'UPGRADE',
             'serviceName': 'serviceName',
             'role': 'role',
             'actionId': 17,
             'taskId': 'taskId',
             'exitcode': 0,
             'reportResult': True
         }, {
             'status': 'FAILED',
             'stderr': 'stderr',
             'stdout': 'out',
             'clusterName': u'cc',
             'roleCommand': u'INSTALL',
             'serviceName': u'HDFS',
             'role': u'DATANODE',
             'actionId': '1-1',
             'taskId': 3,
             'exitcode': 13,
             'reportResult': True
         }, {
             'status': 'COMPLETED',
             'stderr': 'stderr',
             'stdout': 'out',
             'clusterName': u'cc',
             'configurationTags': {
                 'global': {
                     'tag': 'v1'
                 }
             },
             'roleCommand': u'INSTALL',
             'serviceName': u'HDFS',
             'role': u'DATANODE',
             'actionId': '1-1',
             'taskId': 3,
             'exitcode': 0,
             'reportResult': True
         }, {
             'status': 'COMPLETED',
             'stderr': 'stderr',
             'stdout': 'out',
             'clusterName': u'cc',
             'configurationTags': {
                 'global': {
                     'tag': 'v1'
                 }
             },
             'roleCommand': u'INSTALL',
             'serviceName': u'HDFS',
             'role': u'DATANODE',
             'actionId': '1-1',
             'taskId': 3,
             'exitcode': 0,
             'reportResult': False
         }],
         'componentStatus': [
             {
                 'status': 'HEALTHY',
                 'componentName': 'DATANODE',
                 'reportResult': True
             },
             {
                 'status': 'UNHEALTHY',
                 'componentName': 'NAMENODE',
                 'reportResult': True
             },
             {
                 'status': 'UNHEALTHY',
                 'componentName': 'HBASE_MASTER',
                 'reportResult': False
             },
         ],
     }
     heartbeat = Heartbeat(actionQueue, config, self.agentToggleLogger)
     # State.STARTED results in agentState to be set to 4 (enum order)
     hb = heartbeat.build({}, 10)
     hb['hostname'] = 'hostname'
     hb['timestamp'] = 'timestamp'
     hb['fqdn'] = 'fqdn'
     expected = {
         'nodeStatus': {
             'status': 'HEALTHY',
             'cause': 'NONE'
         },
         'timestamp':
         'timestamp',
         'hostname':
         'hostname',
         'fqdn':
         'fqdn',
         'responseId':
         10,
         'reports': [{
             'status': 'IN_PROGRESS',
             'roleCommand': u'INSTALL',
             'serviceName': u'HDFS',
             'role': u'DATANODE',
             'actionId': '1-1',
             'stderr': 'Read from /tmp/errors-3.txt',
             'stdout': 'Read from /tmp/output-3.txt',
             'clusterName': u'cc',
             'taskId': 3,
             'exitcode': 777
         }, {
             'status': 'COMPLETED',
             'roleCommand': 'UPGRADE',
             'serviceName': 'serviceName',
             'role': 'role',
             'actionId': 17,
             'stderr': 'stderr',
             'stdout': 'out',
             'clusterName': 'clusterName',
             'taskId': 'taskId',
             'exitcode': 0
         }, {
             'status': 'FAILED',
             'roleCommand': u'INSTALL',
             'serviceName': u'HDFS',
             'role': u'DATANODE',
             'actionId': '1-1',
             'stderr': 'stderr',
             'stdout': 'out',
             'clusterName': u'cc',
             'taskId': 3,
             'exitcode': 13
         }, {
             'status': 'COMPLETED',
             'stdout': 'out',
             'configurationTags': {
                 'global': {
                     'tag': 'v1'
                 }
             },
             'taskId': 3,
             'exitcode': 0,
             'roleCommand': u'INSTALL',
             'clusterName': u'cc',
             'serviceName': u'HDFS',
             'role': u'DATANODE',
             'actionId': '1-1',
             'stderr': 'stderr'
         }],
         'componentStatus': [{
             'status': 'HEALTHY',
             'componentName': 'DATANODE'
         }, {
             'status': 'UNHEALTHY',
             'componentName': 'NAMENODE'
         }]
     }
     self.assertEqual.__self__.maxDiff = None
     self.assertEquals(hb, expected)
예제 #19
0
        mode = Camera.FACE
    elif mode == "Motion":
        mode = Camera.MOTION
    else:
        mode = None

    log.debug("Generating a jpeg")
    """Video streaming generator function."""
    while True:
        frame, PoI = cam.get_current_jpeg(mode)  #(Camera.FACE)
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')


@app.route('/video_feed/<mode>')
def video_feed(mode):
    """Video streaming route. Put this in the src attribute of an img tag."""
    return Response(gen(cam, heartbeat, mode),
                    mimetype='multipart/x-mixed-replace; boundary=frame')


if __name__ == '__main__':
    if os.environ.get("WERKZEUG_RUN_MAIN") == "true":
        log.info("Initializing threads before first request.")
        global cam
        global heartbeat
        cam = Camera()
        heartbeat = Heartbeat(cam)

    app.run(host='0.0.0.0', debug=True, threaded=True)
예제 #20
0
 def start(self):
     self.actionQueue = ActionQueue(self.config)
     self.actionQueue.start()
     self.register = Register()
     self.heartbeat = Heartbeat(self.actionQueue)
     pass
예제 #21
0
def Search(location, access_token, api_endpoint, response):
    
    locString = str(location[0]) + ', ' + str(location[1])
    print locString
    LocationSetter.set_location(locString)
    origin = LatLng.from_degrees(LocationSetter.FLOAT_LAT, LocationSetter.FLOAT_LONG)
    pokeEntry =[]

    
    original_lat = LocationSetter.FLOAT_LAT
    original_long = LocationSetter.FLOAT_LONG
    parent = CellId.from_lat_lng(LatLng.from_degrees(LocationSetter.FLOAT_LAT, LocationSetter.FLOAT_LONG)).parent(15)

    h = Heartbeat.heartbeat(api_endpoint, access_token, response)
    hs = [h]
    seen = set([])
    for child in parent.children():
        latlng = LatLng.from_point(Cell(child).get_center())
        LocationSetter.set_location_coords(latlng.lat().degrees, latlng.lng().degrees, 0)
        hs.append(Heartbeat.heartbeat(api_endpoint, access_token, response))
    LocationSetter.set_location_coords(original_lat, original_long, 0)

    visible = []

    for hh in hs:
        for cell in hh.cells:
            for wild in cell.WildPokemon:
                hash = wild.SpawnPointId + ':' + str(wild.pokemon.PokemonId)
                if (hash not in seen):
                    visible.append(wild)
                    seen.add(hash)

    print('')
    for cell in h.cells:
        if cell.NearbyPokemon:
            print cell.NearbyPokemon
            other = LatLng.from_point(Cell(CellId(cell.S2CellId)).get_center())
            diff = other - origin
            # print(diff)
            difflat = diff.lat().degrees
            difflng = diff.lng().degrees
            direction = (('N' if difflat >= 0 else 'S') if abs(difflat) > 1e-4 else '')  + (('E' if difflng >= 0 else 'W') if abs(difflng) > 1e-4 else '')
            print("Within one step of %s (%sm %s from you):" % (other, int(origin.get_distance(other).radians * 6366468.241830914), direction))
            for poke in cell.NearbyPokemon:
                print('    (%s) %s' % (poke.PokedexNumber, pokemons[poke.PokedexNumber - 1]['Name']))

    print('') 
    for poke in visible:
        other = LatLng.from_degrees(poke.Latitude, poke.Longitude)
        diff = other - origin
        # print(diff)
        difflat = diff.lat().degrees
        difflng = diff.lng().degrees
        direction = (('N' if difflat >= 0 else 'S') if abs(difflat) > 1e-4 else '')  + (('E' if difflng >= 0 else 'W') if abs(difflng) > 1e-4 else '')
        print("(%s) %s is visible at (%s, %s) for %s seconds (%sm %s from you)" % (poke.pokemon.PokemonId, pokemons[poke.pokemon.PokemonId - 1]['Name'], poke.Latitude, poke.Longitude, poke.TimeTillHiddenMs / 1000, int(origin.get_distance(other).radians * 6366468.241830914), direction))
         
        pokeDict = {'pokeID': poke.pokemon.PokemonId, 
                    'hashID': str(poke.SpawnPointId) + ':' +str(poke.pokemon.PokemonId),
                    'pokeName': pokemons[poke.pokemon.PokemonId - 1]['Name'].encode('ascii','ignore'), 
                    'long':poke.Longitude, 
                    'lat': poke.Latitude,
                    'timeLeft':poke.TimeTillHiddenMs}
        pokeEntry.append(pokeDict)


    print('')
    #walk = Heartbeat.getNeighbors()
    #next = LatLng.from_point(Cell(CellId(walk[2])).get_center())
    ##if raw_input('The next cell is located at %s. Keep scanning? [Y/n]' % next) in {'n', 'N'}:
    ##    break
    #LocationSetter.set_location_coords(next.lat().degrees, next.lng().degrees, 0)

    return pokeEntry
예제 #22
0
class Replica:

    #   Initialize:
    #################################################################
    def __init__(self, id: str):
        self.replica_count = 5
        self.id = id
        self.peers = [
            str(x) for x in range(0, self.replica_count) if x != int(self.id)
        ]
        self.election_state = 'follower'
        self.timer_length = 4
        self.current_term = 0
        self.voted_for = 'Null'
        self.vote_count = 0

        self.messenger = Messenger(self.id, self)
        self.election_timer = Election_Timer(self.timer_length, self)
        self.heartbeat = Heartbeat(self.timer_length, self)

# Change Replica State:
#################################################################

    def set_state_to_follower(self, term: int):
        print('\n', self.id, ' Set state to follower')
        self.election_state = 'follower'
        self.current_term = term
        self.election_timer.restart_timer()
        self.vote_count = 0
        self.voted_for = 'Null'
        self.heartbeat.stop_timer()

    def set_state_to_leader(self):
        print('\n', self.id, ' Set state to leader')
        self.election_state = 'leader'
        self.election_timer.stop_timer()
        self.vote_count = 0
        self.voted_for = 'Null'
        self.heartbeat.restart_timer()

    def set_state_to_candidate(self):
        self.current_term += 1
        self.voted_for = self.id
        if self.election_state != 'candidate':
            print('\n', self.id, ' set state to candidate')
            self.election_state = 'candidate'
            self.vote_count = 1
            self.heartbeat.stop_timer()

# Process incoming messages:
#################################################################

    def handle_incoming_message(self, message: dict):
        message_type = message['messageType']
        print(
            '\n********* You Have Passed A message Back to replica: {} *****\n'
            .format(message_type))
        if message_type == 'AppendEntriesRPC':
            self.receive_append_entries_request(message)
        elif message_type == 'AppendReply':
            self.receive_append_entries_reply(message)
        elif message_type == 'RequestVotesRPC':
            self.receive_vote_request(message)
        elif message_type == 'VoteReply':
            self.receive_vote_reply(message)

    def receive_append_entries_request(self, message: dict):
        leader = message['leaderID']
        incoming_term = int(message['term'])
        print('\n', self.id, ' received append entry request from ', leader,
              ': \n', message)

        if incoming_term >= self.current_term:
            print('\n', self.id,
                  ' greater term detected, reverting to follower')
            self.set_state_to_follower(incoming_term)
            reply = self.make_message('reply to append request')
            self.messenger.send(reply, leader)
            print('\n', self.id, ' replied to append request')
        else:
            print('\n', self.id, ' incoming term less than current, no reply')

    def receive_vote_request(self, message: dict):
        candidate = message['candidateID']
        incoming_term = int(message['term'])
        print('\n', self.id, ' received vote request from ', candidate, ': \n',
              message)

        if incoming_term > self.current_term:
            self.set_state_to_follower(incoming_term)
            print('\n', self.id,
                  ' greater term detected, reverting to follower')

        if self.voted_for == 'Null':
            self.voted_for = candidate
            print('\n', self.id, ' voted for ', self.voted_for)

        reply = self.make_message('reply to vote request', candidate)
        self.messenger.send(reply, candidate)
        print('\n', self.id, ' replied to ', candidate, ' request for votes')

    def receive_append_entries_reply(self, message: dict):
        print('\n', self.id, ' received append entries reply :', message)

    def receive_vote_reply(self, message: dict):
        vote_granted = message['voteGranted']
        print('\n', self.id, ' received vote reply :', message)
        if self.election_state == 'candidate':
            if vote_granted == 'True':
                self.vote_count += 1
                print('\n', self.id, ' vote count = ', self.vote_count)
            if self.vote_count > math.floor(self.replica_count / 2):
                self.set_state_to_leader()
                print('\n', self.id, ' majority votes acquired')


# Helper Functions
#################################################################

    def make_message(self, message_type: str, destination: str = '') -> dict:
        '''
		options: 'heartbeat', 'reply to append request', 'request votes', 
		'reply to vote request'. Include destination with reply to vote request. 
		'''
        if message_type == 'heartbeat':
            message = {
                'messageType': 'AppendEntriesRPC',
                'leaderID': self.id,
                'term': str(self.current_term)
                #'prevLogIndex' : 'self.prevLogIndex',
                #'prevLogTerm' : 'self.prevLogTerm',
                #'leaderCommit' : 'self.commitIndex'
            }
        elif message_type == 'reply to append request':
            message = {
                'messageType': 'AppendReply',
                'term': str(self.current_term),
                #'success' : {'value': 'True'}
            }
        elif message_type == 'request votes':
            message = {
                'messageType': 'RequestVotesRPC',
                'term': str(self.current_term),
                'candidateID': self.id
                #'lastLogIndex': {'value': self.lastLogIndex},
                #'lastLogTerm': {'value': self.lastLogTerm}
            }
        elif message_type == 'reply to vote request':
            voteGranted = 'False'
            if self.voted_for == destination:
                voteGranted = 'True'
            message = {
                'messageType': 'VoteReply',
                'term': str(self.current_term),
                'voteGranted': voteGranted
            }
        else:
            message = {'messageType': 'blank'}

        return message

    def send_heartbeat(self):
        heartbeat = self.make_message('heartbeat')
        for peer in self.peers:
            self.messenger.send(heartbeat, peer)

    def request_votes(self):
        request = self.make_message('request votes')
        for peer in self.peers:
            self.messenger.send(request, peer)

    def start_election(self):
        self.set_state_to_candidate()
        print('\n', self.id, " started an election")
        self.request_votes()
예제 #23
0
class LeaderElection:
    def __init__(self, _id: str):
        """
        Constructor for leader election.
        Main class to elect which node becomes leader.

        :param _id: str. Which node this object belongs to.
        """
        self._id = _id
        self.nodes = ['0', '1', '2', '3']
        self.peers = [node for node in self.nodes if node != self._id]

        self.term = 0
        self.election_state = 'follower'
        self.current_leader = ''
        self.timer_length = 3
        self.vote_count = 0
        self.voted_for = 'null'
        self.vote_received_from = {}
        self.reset_votes_received()

        self.m = Messenger(self._id, self)
        self.e = ElectionTimer(self.timer_length, self)
        self.h = Heartbeat(self.timer_length, self)

    def reset_votes_received(self):
        """
        Reset leader election so no node had any votes.
        :return:
        """
        for peer in self.peers:
            self.vote_received_from[peer] = False

    def set_follower(self, term: int):
        """
        Set election state and all attributes to follower.

        :param term: int. What term is the election in?
        :return:
        """
        self.term = term
        self.election_state = 'follower'
        self.vote_count = 0
        self.voted_for = 'null'
        self.reset_votes_received()
        self.h.stop_timer()

    def set_leader(self):
        """
        Set election state and all attributes to leader.

        :return:
        """
        self.election_state = 'leader'
        self.e.stop_timer()
        self.send_heartbeat()
        self.h.restart_timer()

    def release_leadership(self):
        """
        Force node to stop being leader.

        :return:
        """
        self.h.stop_timer()
        self.set_follower(self.term)
        self.send_to_peers('release', 'empty')

    def request_leadership(self):
        """
        Set node to candidate status, notifying followers of its intentions.

        :return:
        """
        self.term += 1
        self.election_state = 'candidate'
        self.voted_for = self._id
        self.vote_count = 1
        self.send_to_peers(type='request_votes', contents=self._id)
        # if timer elapses during request for leadership, set to follower

    def send_to_peers(self, type: str, contents: str):
        """
        Send message to all other nodes.

        :param type: str. What is the message type
        :param contents: str. What the message contains
        :return:
        """
        msg = {'type': type, 'contents': contents, 'term': str(self.term)}
        for peer in self.peers:
            self.m.send(msg, peer)

    def send_heartbeat(self, contents: str = 'empty'):
        """
        Send a heartbeat to check liveness of nodes.

        :param contents:
        :return:
        """
        if self.election_state == 'leader':
            msg = {'type': 'heartbeat', 'contents': contents, 'term': str(self.term)}
            for peer in self.peers:
                self.m.send(msg, peer)

    def handle_incoming_message(self, message: dict):
        """
        Method necessary when initializing Messenger thread to process messages from queue.

        :param message: The incoming message dictionary: type and contents
        :return:
        """
        incoming_term = int(message['term'])
        if incoming_term > self.term and self.election_state != 'leader':
            self.set_follower(incoming_term)
        message_type = message['type']
        if message_type == 'heartbeat':
            self.receive_heartbeat(message)
        elif message_type == 'request_votes':
            self.receive_vote_request(message)
        elif message_type == 'vote_reply':
            self.receive_vote_reply(message)
        elif message_type == 'release':
            # sent by leader to release all "voted for" and reset state to followers
            self.set_follower(incoming_term)
        elif message_type == 'leader_exists' and self.election_state == 'candidate':
            self.set_follower(incoming_term)

    def receive_heartbeat(self, message: dict):
        """
        Upon receiving heartbeat, change timers.

        :param message:
        :return:
        """
        incoming_term = int(message['term'])
        if self.election_state == 'candidate':
            self.set_follower(incoming_term)
        elif self.election_state == 'follower':
            self.e.restart_timer()

    def receive_vote_request(self, message: dict):
        """
        Actions to undertake when a follower receives a vote request from a candidate.

        :param message:
        :return:
        """
        candidate = message['contents']
        if self.election_state != 'leader':
            vote_granted = 'False'
            if self.voted_for == 'null':
                self.voted_for = candidate
            if self.voted_for == candidate:
                vote_granted = 'True'
            self.m.send({'type': 'vote_reply', 'contents': vote_granted, 'term': str(self.term), 'sender': self._id},
                        candidate)
        else:
            self.m.send({'type': 'leader_exists', 'contents': 'none', 'term': str(self.term)}, candidate)

    def receive_vote_reply(self, message: dict):
        """
        Actions to take when you receive a vote as a candidate. If you receive majority of votes, you become leader.

        :param message:
        :return:
        """
        vote_granted = message['contents']
        incoming_term = int(message['term'])
        sender = message['sender']
        if self.election_state == 'candidate' and incoming_term == self.term:
            self.vote_received_from[sender] = True
            response_from_all = True
            if vote_granted == 'True':
                self.vote_count += 1
            for k, v in self.vote_received_from.items():
                if not v:
                    response_from_all = False
            if self.vote_count > math.floor(len(self.peers)/2) and response_from_all:
                self.set_leader()
예제 #24
0
파일: Core.py 프로젝트: mswiders1/multitalk
class Core:
    def __init__(self,  __reactor):
        print "Core: swiat jest piekny ;)"
        self.__tcpm = None
        self.__messageStore = MessageInfoStore()
        self.__model = None
        self.__gui = None
        self.__reactor = __reactor
        self.__broadcastStarted = False
        self.heartbeat = Heartbeat(self)
        self.__lookForDead = LoopingCall(self.lookForDeadNodes)
        self.__lookForDeadStarted = False
        return 
    
    def userInsertedNetworkAddr(self,  addr):
        print "Core: uzytkownik chce polaczyc sie z %s" % addr
        self.__model.setPreferredNodesAddr(addr)
        
    def handleUserInsertedNick(self,  nick):
            #Logowanie uzytkownika
            self.__model.setNick(nick)
            print ("Core: logowanie z nickiem %s" % nick)
            self.__model.setMyId(Hash.generateUserId(nick))
            try:
                print "Core: tworze serwer TCP"
                self.tcpFactory = TCPServer.startTCPServer(self.__reactor)
                netAddr = self.__model.getPreferredNodesAddr()
                if netAddr:
                    print "Core: tworze klienta tcp do polaczenia do %s" % netAddr
                    TCPClient.startReversedTCPConnection(self.__reactor,  netAddr)
                else:
                    print "Core: tworze klienta broadcast"
                    self.broadcastSender = BroadcastSender.startSender(self.__reactor)
            except socket.error as err:
                print("Core: nie można uruchomić zerwer TCP lub wyslac rozgloszenia")
                traceback.print_exc()
                sys.exit()
    
    def handleHeartbeatTimePassed(self):
        print "Core: wysylam heartbeat(%s)" % time.strftime("%H:%S") 
        for connection in self.__tcpm.getMappedConnections():
            connection.sendLivMsg()
            
    def handleLivMessage(self,  msg):
        uid = msg['UID']
        self.__model.markNodeIsAlive(uid)
        self.__doMsgForward(msg)

    def lookForDeadNodes(self):
        self.__model.lookForDeadNodes()

    def sendMessage(self,  uid,  msg):
        if not msg:
            return
        if uid:
            print "Core: wysyłam wiadomość '%s' do %s" % (msg,  uid)
            self.__gui.messageReceived(self.__model.getMyId(), self.__model.getNick(), uid,  msg)
        else:
            print "Core: wysyłam wiadomość '%s' do wszystkich" % msg
            self.__gui.messageReceived(self.__model.getMyId(), self.__model.getNick(),  "",  msg)
        
        msg = MessageParser.getFullMsgMsg(uid,  msg)
        for connection in self.__tcpm.getMappedConnections():
            #ale lipa - musze z tego poziomu tworzyc pakiet do wyslania    
            connection.sendPacket(msg)
        
    def handleMsgMessage(self,  msg):
        print "Core: przesylam wiadomosc MSG do analizujy "
        if self.__model.updateLogicalTimeUsingMsgAndSendToGui(msg):
            for connection in self.__tcpm.getMappedConnections():
                connection.sendPacket(msg) 
    
    def userNameByUid(self,  uid):
        return self.__model.getNickByUID(uid)
        
    def isThisMyUid(self,  uid):
        return uid == self.__model.getMyId()
    
    def setDelayPerNode(self,  uid,  delayInSec):
        print "Core: ustawiam opóźnienie %d sekund dla klienta %s" % (delayInSec,  uid)
        connection = self.__tcpm.getConnectionToNode(uid)
        if connection:
            connection.delay = delayInSec
            
    def handleHiiMessage(self,  msg,  connection):
        print "Core: analiza wiadomosci Hii"
        for nodeFromVector in msg['VECTOR']:
            print "Core: dodaje wezel z wiadomosci hi: '%s'" % nodeFromVector
            self.__model.addNode(nodeFromVector['UID'],  nodeFromVector['USERNAME'],  nodeFromVector['IP_ADDRESS'])
        print "Core: mapuje wezel %s na polaczenie %s" % (msg['UID'],  connection)
        if not self.__tcpm.mapNodeToConnection(msg['UID'],  connection):
            print "Core: zamykam polaczenie bo już mam takie polaczenie"
            connection.transport.loseConnection()
            return
        if self.__model.getPreferredNodesAddr():
            #uzytkownik podal z palca adres wiec w opoiedzi na HII wysylamy LOG
            self.__doLog()
        for uid in self.__model.getListOfNodes():
            if not uid in self.__tcpm.getNodesWithConnections():
                TCPClient.startReversedTCPConnection(self.__reactor,  self.__model.getIPByUID(uid))
                
            
    def __doLog(self):
        self.__model.addMeToListOfNodes()
        self.__sendLogMsgToAll()
        #self.heartbeat.start()
        #self.__broadcastStarted = True
    
    def __doNewNetwork(self):
        self.__model.setIamFirstNode()
        self.heartbeat.start()
        self.__broadcastStarted = True
    
    def handleLogMessage(self,  msg,  connection):
        print "Core: analiza wiadomosci Log"
        uid = msg['UID']
        if uid == self.__model.getMyId():
            print "Core: otrzymano wlasny LOG msg"
            return True
        if self.__model.logNewUser(msg['UID'],  msg['USERNAME'], msg['IP_ADDRESS']):
            directConnection = False
            if not self.__tcpm.isConnectionMapped(connection):
                # wiadomosc otrzymano za posrednictwem niezmapowanego polaczenias
                directConnection = True
                self.__tcpm.mapNodeToConnection(msg['UID'],  connection) # TODO : co w przypadku gdy connection sluzylo jako proxy dla tej wiadomoscis
            else:
                print "Core: polaczenie jest juz zmapowane wiec pakiet byl forwardowany"
            connection.sendMtxMsg()
            print "Core: przesłałem MTX"
            if directConnection:
                self.__doMsgForward(msg)
            return True
        else:
            return False

    def __doMsgForward(self,  msg):
        if self.__messageStore.isToForward(msg):
            print "Core: przekazuje wiadomosci do innych"
            for connection in self.__tcpm.getMappedConnections():
                connection.sendPacket(msg) 
        else:
            print "Core: nie przekazuje wiadomosci "
        pass

    def handleMtxMessage(self,  msg):
        print "Core: analiza wiadomosci MTX"
        self.__model.addMatrix(msg['MAC'],  msg['VEC'])

    def handleGetMessage(self,  msg,  connection):
        print "Core: obsluga wiad. GET"
        uid = msg['UID']
        time = msg['MSG_ID']
        msgToSend = self.__model.getMsgBySenderAndTime(uid,  time)
        if msgToSend:
            connection.sendPacket(msgToSend)

    def handleOutMessage(self,  msg):
        print "Core: ktos sie żegna z nami :("
        uid = msg["UID"]
        self.__model.removeNode(uid)
        self.__doMsgForward(msg)

    def closeApp(self):
        print "Core: zamykam applikacje"
        self.__sendOutMsgToAll()
        if self.__lookForDeadStarted:
            self.__lookForDead.stop()
        if self.__broadcastStarted:
            self.heartbeat.stop()
        return True
        
    def __sendOutMsgToAll(self):
        for connection in self.__tcpm.getMappedConnections():
            connection.sendOutMsgAndCloseConnection()
        
    def __handleBroadcastEnd(self):
        #Koniec przeszukiwania
        print "Core: koniec przeszukiwanie sieci"
        if self.__model.isIamAlone():
            print "Core: jestem sam :("
            self.__doNewNetwork()
        else:
            print "Core: znalezniono wezly - rozpoczynam logowanie"
            self.__doLog()
        #Wlączamy server broadcast aby otrzymywav informacje o koniecznosci podlaczenia
        print "Core: uruchamiam broadcast receiver"
        self.broadcastReceiver = BroadcastReceiver.startReceiver(self.__reactor)
        
        
    def __sendLogMsgToAll(self):
        for connection in self.__tcpm.getMappedConnections():
            connection.sendLogMsg()
        self.__lookForDead.start(10)
        
    def broadcastProgress(self,  progress):
        self.__gui.setBroadcastProgress(progress)
        if progress == 100:
            self.__handleBroadcastEnd()
                
    def handleReceivedBroadcastPacket(self,  fromIP):
        print "Core: ktos chce abysmy podlaczyli sie do niego"
        if self.__tcpm.isNotConnectingToIp(fromIP):
            print "Core: nie mam do niego polaczenie wiec tworze je %s" % fromIP
            TCPClient.startTCPConnection(self.__reactor,  fromIP)
    
    def setGui(self,  gui):
        self.__gui = gui

    def setModel(self,  model):
        self.__model = model
        
    def setTcpManager(self,  manager):
        self.__tcpm = manager