Commit f35b298b authored by Vincent Pelletier's avatar Vincent Pelletier

Make getNewUUID internally avoid duplicate UUIDs.

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