From 3b1ee9c81f9c2e5c6bc6ac7c7727e70ac28f80e1 Mon Sep 17 00:00:00 2001 From: Renaud Guillard Date: Sat, 28 Jun 2025 19:40:21 +0200 Subject: [PATCH] Automatic resolution of service name conflicts when publising Rename service using a " (#)" suffix as macOS APIs could do. --- src/lib/registry.ts | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/lib/registry.ts b/src/lib/registry.ts index 8986c47..5a4574e 100644 --- a/src/lib/registry.ts +++ b/src/lib/registry.ts @@ -17,7 +17,7 @@ export class Registry { public publish(config: ServiceConfig): Service { - function start(service: Service, registry: Registry, opts?: { probe: boolean }) { + async function start(service: Service, registry: Registry, opts?: { probe: boolean }) { if (service.activated) return service.activated = true @@ -25,18 +25,33 @@ export class Registry { if(!(service instanceof Service)) return - if(opts?.probe) { - registry.probe(registry.server.mdns, service, (exists: boolean) => { - if(exists) { - if(service.stop !== undefined) service.stop() - console.log(new Error('Service name is already in use on the network')) - return - } - registry.announce(registry.server, service) - }) - } else { - registry.announce(registry.server, service) + if(opts?.probe === false) { + registry.announce(registry.server, service) + return + } + + let conflicts = true + let attempt = 1 + const name = service.name + const fqdnSuffix = service.fqdn.substring(name.length) + while (conflicts) { + conflicts = false + try { + await new Promise ((resolve, reject) => { + registry.probe(registry.server.mdns, service, (exists: boolean) => { + if(exists) reject(service.name) + else resolve(service.name) + }) + }) + } catch (e) { + ++attempt + conflicts = true + service.name = name + ' (' + attempt + ')' + service.fqdn = service.name + fqdnSuffix + } } + + registry.announce(registry.server, service) } function stop(service: Service, registry: Registry, callback?: CallableFunction) {