From: sourabh_sourabh Date: Thu, 17 Apr 2025 16:38:54 +0000 (+0100) Subject: Simplify hostname-based startup delay logic with consistent hash-based approach X-Git-Tag: 3.6.3~42 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=51bec9275379e5f693398d3dc5d2bb2ebbd07065;p=cps.git Simplify hostname-based startup delay logic with consistent hash-based approach - Removed conditional logic based on last character of the hostname - Applied a uniform hash-based delay calculation up to 5000 ms - Improves consistency and simplifies the code logic - Updated JavaDoc to reflect the new approach Issue-ID: CPS-2752 Change-Id: Ic9e5cffb7396695e90b94edba79984f7f0f859aa Signed-off-by: sourabh_sourabh --- diff --git a/cps-application/src/main/java/org/onap/cps/startup/InstanceStartupDelayManager.java b/cps-application/src/main/java/org/onap/cps/startup/InstanceStartupDelayManager.java index b221bdc03b..927c59f75d 100644 --- a/cps-application/src/main/java/org/onap/cps/startup/InstanceStartupDelayManager.java +++ b/cps-application/src/main/java/org/onap/cps/startup/InstanceStartupDelayManager.java @@ -29,25 +29,20 @@ import lombok.extern.slf4j.Slf4j; public class InstanceStartupDelayManager { /** - * Applies a startup delay based on the host's name to avoid race conditions during schema migration. - - * In environments with multiple instances (e.g., Docker Compose, Kubernetes), - * this delay helps avoid simultaneous Liquibase executions that may result in conflicts. - + * Applies a consistent hash-based startup delay based on the host's name + * to avoid race conditions during schema migration. + * This method is useful in environments with multiple instances + * (e.g., Docker Compose, Kubernetes), where simultaneous Liquibase executions + * might result in conflicts. * Delay logic: - * - If the last character of the hostname is a digit, delay = digit * 1000 ms. - * - Otherwise, a hash-based fallback delay up to 3000 ms is applied. + * - A hash of the hostname is calculated. + * - The result is used to derive a delay up to 5000 milliseconds. + * - This provides a reasonably distributed delay across instances. */ public void applyHostnameBasedStartupDelay() { try { final String hostname = getHostName(); - final char lastCharacterOfHostName = hostname.charAt(hostname.length() - 1); - final long startupDelayInMillis; - if (Character.isDigit(lastCharacterOfHostName)) { - startupDelayInMillis = Character.getNumericValue(lastCharacterOfHostName) * 1_000L; - } else { - startupDelayInMillis = Math.abs(hostname.hashCode() % 3_000L); - } + final long startupDelayInMillis = Math.abs(hostname.hashCode() % 5_000L); log.info("Startup delay applied for Hostname: {} | Delay: {} ms", hostname, startupDelayInMillis); haveALittleSleepInMs(startupDelayInMillis); } catch (final InterruptedException e) { diff --git a/cps-application/src/test/groovy/org/onap/cps/startup/InstanceStartupDelayManagerSpec.groovy b/cps-application/src/test/groovy/org/onap/cps/startup/InstanceStartupDelayManagerSpec.groovy index 68ef6cce34..0ad02f4551 100644 --- a/cps-application/src/test/groovy/org/onap/cps/startup/InstanceStartupDelayManagerSpec.groovy +++ b/cps-application/src/test/groovy/org/onap/cps/startup/InstanceStartupDelayManagerSpec.groovy @@ -27,34 +27,14 @@ class InstanceStartupDelayManagerSpec extends Specification { def objectUnderTest = Spy(InstanceStartupDelayManager) def 'Startup delay with real hostname.'() { - when: 'start up delay is called' - objectUnderTest.applyHostnameBasedStartupDelay() - then: 'the system will sleep for some time' - 1 * objectUnderTest.haveALittleSleepInMs(_ as Long) >> { /* don't really sleep */ } - } - - def 'Startup delay for hostname that ends with digit.'() { - given: 'a hostname with a digit at the end' - objectUnderTest.getHostName() >> 'host' + lastDigit - and: 'the expected delay is based on last digit' - def expectedDelay = lastDigit * 1_000 - when: 'startup delay is called' - objectUnderTest.applyHostnameBasedStartupDelay() - then: 'the system will sleep for expected time' - 1 * objectUnderTest.haveALittleSleepInMs(expectedDelay) - where: 'following last digits are used' - lastDigit << [0, 1] - } - - def 'Startup delay for hostname that does not end with digit.'() { - given: 'a hostname with a non-digit at the end' + given: 'a hostname is resolved' objectUnderTest.getHostName() >> 'hostX' - and: 'the expected delay is based on hash code with max of 3,000 ms' - def expectedDelay = Math.abs('hostX'.hashCode() % 3_000) + and: 'the expected delay is based on hash code with max of 5,000 ms' + def expectedDelay = Math.abs('hostX'.hashCode() % 5_000) when: 'startup delay is called' objectUnderTest.applyHostnameBasedStartupDelay() then: 'the system will sleep for expected time' - 1 * objectUnderTest.haveALittleSleepInMs(expectedDelay) >> { /* don't really sleep */ } + 1 * objectUnderTest.haveALittleSleepInMs(expectedDelay) } def 'Startup delay when hostname cannot be resolved.'() {