From 52f9c6df95cae035fda3771e96f1296b880e3370 Mon Sep 17 00:00:00 2001 From: Dmytro Vyazelenko <696855+vyazelenko@users.noreply.github.com> Date: Wed, 15 May 2024 14:01:14 +0200 Subject: [PATCH] [Java] Increment sequence if the clock is not advancing or going backwards. --- .../agrona/concurrent/SnowflakeIdGenerator.java | 7 +------ .../concurrent/SnowflakeIdGeneratorTest.java | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/agrona/src/main/java/org/agrona/concurrent/SnowflakeIdGenerator.java b/agrona/src/main/java/org/agrona/concurrent/SnowflakeIdGenerator.java index c72cc4294..883815cfc 100644 --- a/agrona/src/main/java/org/agrona/concurrent/SnowflakeIdGenerator.java +++ b/agrona/src/main/java/org/agrona/concurrent/SnowflakeIdGenerator.java @@ -225,7 +225,7 @@ public long nextId() return newTimestampSequence | nodeBits; } } - else if (timestampMs == oldTimestampMs) + else { final long oldSequence = oldTimestampSequence & maxSequence; if (oldSequence < maxSequence) @@ -237,11 +237,6 @@ else if (timestampMs == oldTimestampMs) } } } - else - { - throw new IllegalStateException( - "clock has gone backwards: timestampMs=" + timestampMs + " < oldTimestampMs=" + oldTimestampMs); - } if (Thread.currentThread().isInterrupted()) { diff --git a/agrona/src/test/java/org/agrona/concurrent/SnowflakeIdGeneratorTest.java b/agrona/src/test/java/org/agrona/concurrent/SnowflakeIdGeneratorTest.java index fd8cd3ede..f95c63900 100644 --- a/agrona/src/test/java/org/agrona/concurrent/SnowflakeIdGeneratorTest.java +++ b/agrona/src/test/java/org/agrona/concurrent/SnowflakeIdGeneratorTest.java @@ -205,7 +205,7 @@ void shouldAdvanceTimestamp() } @Test - void shouldDetectClockGoingBackwards() + void shouldAdvanceSequenceWhenClockIsGoingBackwards() { final long nodeId = 7; final long timestampOffset = 0; @@ -215,10 +215,18 @@ void shouldDetectClockGoingBackwards() NODE_ID_BITS_DEFAULT, SEQUENCE_BITS_DEFAULT, nodeId, timestampOffset, clock); clock.update(7); - idGenerator.nextId(); + final long firstId = idGenerator.nextId(); + final long firstTimestamp = clock.time(); + assertEquals(firstTimestamp, idGenerator.extractTimestamp(firstId)); + assertEquals(nodeId, idGenerator.extractNodeId(firstId)); + assertEquals(0L, idGenerator.extractSequence(firstId)); - clock.update(3); - assertThrows(IllegalStateException.class, idGenerator::nextId); + clock.update(4); + + final long secondId = idGenerator.nextId(); + assertEquals(firstTimestamp, idGenerator.extractTimestamp(secondId)); + assertEquals(nodeId, idGenerator.extractNodeId(secondId)); + assertEquals(1L, idGenerator.extractSequence(secondId)); } @Test