Commit f35b298b by Vincent Pelletier

Make getNewUUID internally avoid duplicate UUIDs.

1 parent 58058cca
......@@ -46,6 +46,7 @@ class Application(object):
last_transaction = ZERO_TID
backup_tid = None
backup_app = None
uuid = None
def __init__(self, config):
# Internal attributes.
......@@ -85,7 +86,7 @@ class Application(object):
# Generate an UUID for self
uuid = config.getUUID()
if uuid is None or uuid == '':
uuid = self.getNewUUID(NodeTypes.MASTER)
uuid = self.getNewUUID(None, self.server, NodeTypes.MASTER)
self.uuid = uuid
logging.info('UUID : %s', dump(uuid))
......@@ -424,17 +425,14 @@ class Application(object):
handler.connectionCompleted(conn)
self.cluster_state = state
def getNewUUID(self, node_type):
try:
return UUID_NAMESPACES[node_type] + os.urandom(15)
except KeyError:
raise RuntimeError, 'No UUID namespace found for this node type'
def isValidUUID(self, uuid, addr):
if uuid == self.uuid or uuid is None:
return False
node = self.nm.getByUUID(uuid)
return node is None or node.getAddress() in (None, addr)
def getNewUUID(self, uuid, address, node_type):
if None != uuid != self.uuid and \
self.nm.getByAddress(address) is self.nm.getByUUID(uuid):
return uuid
while True:
uuid = UUID_NAMESPACES[node_type] + os.urandom(15)
if uuid != self.uuid and self.nm.getByUUID(uuid) is None:
return uuid
def getClusterState(self):
return self.cluster_state
......
......@@ -141,8 +141,7 @@ class ServerElectionHandler(BaseElectionHandler, MasterHandler):
if node is None:
node = app.nm.createMaster(address=address)
# supply another uuid in case of conflict
while not app.isValidUUID(uuid, address):
uuid = app.getNewUUID(node_type)
uuid = app.getNewUUID(uuid, address, node_type)
node.setUUID(uuid)
conn.setUUID(uuid)
......
......@@ -67,8 +67,7 @@ class IdentificationHandler(MasterHandler):
else:
raise NotImplementedError(node_type)
while not app.isValidUUID(uuid, address):
uuid = app.getNewUUID(node_type)
uuid = app.getNewUUID(uuid, address, node_type)
logging.info('Accept a' + human_readable_node_type + dump(uuid))
if node is None:
node = node_ctor(uuid=uuid, address=address)
......
......@@ -796,11 +796,18 @@ def predictable_random(seed=None):
logging.info("using seed %r", s)
r = random.Random(s)
try:
MasterApplication.getNewUUID = lambda self, node_type: (
super(MasterApplication, self).getNewUUID(node_type)
if node_type == NodeTypes.CLIENT else
UUID_NAMESPACES[node_type] + ''.join(
chr(r.randrange(256)) for _ in xrange(15)))
def getNewUUID(self, uuid, address, node_type):
if node_type == NodeTypes.CLIENT:
return super(MasterApplication, self).getNewUUID(uuid,
address, node_type)
while uuid is None or uuid == self.uuid:
node = self.nm.getByUUID(uuid)
if node is None or node.getAddress() in (None, addr):
uuid = UUID_NAMESPACES[node_type] + ''.join(
chr(r.randrange(256)) for _ in xrange(15))
return uuid
MasterApplication.getNewUUID = getNewUUID
administration.random = backup_app.random = replicator.random \
= r
return wrapped(*args, **kw)
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!