Esempio n. 1
0
	def run(self):
		i = 1	# TODO pick i more intelligently?
		b = self.nextballot(0)	# TODO same?
		v = None
		self._rpcclient.set_timeout(self._timeout)

		begin, retryphase1 = 1, 2
		state = begin

		while True:
			if state == begin:
				v = self._queue.get()
			elif state == retryphase1:
				state = begin

			# Phase 1:
			resps = self._rpcclient.prepare(i, b)

			# We can only send our 'v' for acceptance if we have not already crossed
			# the Rubicon: if any other v *possibly* has quorum, we can't submit.
			# Each resp in resps is a ("promise", i, b, V, VB).
			maj, res_val = _majority(len(self._peers), [resp[3:5] for resp in resps])

			if not maj:
				state = retryphase1
				b = self.nextballot(b)
				continue
			
			# Instance is ready, proceed. Phase 2:
			if res_val is not None:
				v = res_val	# Instance is reserved; we must choose this value.

			resps = self._rpcclient.accept(i, b, v)
			if not asyncrpc._is_majority(len(self._peers), resps):
				state = retryphase1
				b = self.nextballot(b)
				continue

			# Instance is closed. Convey "learn" messages to local learner.
			self._learner.learn(i, v)
			i += 1
Esempio n. 2
0
def _majority(n_peers, values):
	"""
	Takes in a number of peers, and a list of at most n_peers (V, VB) pairs.

	Returns (True, None) if the instance is empty.
	Returns (True, v) if the instance is reserved.
	Returns (False, None) if a quorum of acceptors failed to reply.
	"""
	if not asyncrpc._is_majority(n_peers, values):
		return (False, None)

	empty = True
	maxVB = None
	maxV = None
	for (V, VB) in values:
		if VB is not None and (empty or VB > maxVB):
			maxV = V
			maxVB = VB
			empty = False

	if empty:
		return (True, None)

	return (True, maxV)