Skip to content

Commit 71bf292

Browse files
committed
fix(snowflake): Ensure random number are sequential
Otherwise tests fails from time to time as they expect entities to be ordered. Signed-off-by: Carl Schwan <[email protected]>
1 parent e6c269e commit 71bf292

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

lib/private/Snowflake/Generator.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
* @since 33.0.0
2222
*/
2323
final class Generator implements IGenerator {
24+
private int $lastSeconds = -1;
25+
private int $lastMilliseconds = -1;
26+
private int $sequence;
27+
2428
public function __construct(
2529
private readonly ITimeFactory $timeFactory,
2630
) {
@@ -124,6 +128,7 @@ private function getSequenceId(int $seconds, int $milliseconds, int $serverId):
124128
return false;
125129
}
126130

131+
$success = false;
127132
$sequenceId = apcu_inc($key, success: $success, ttl: 1);
128133
if ($success === true) {
129134
return $sequenceId;
@@ -133,6 +138,18 @@ private function getSequenceId(int $seconds, int $milliseconds, int $serverId):
133138
}
134139

135140
// Otherwise, just return a random number
136-
return random_int(0, 0xFFF - 1);
141+
if ($this->lastSeconds === $seconds && $this->lastMilliseconds === $milliseconds) {
142+
$this->sequence++;
143+
$this->lastSeconds = $seconds;
144+
$this->lastMilliseconds = $milliseconds;
145+
146+
return $this->sequence;
147+
}
148+
149+
$this->sequence = crc32(uniqid((string)random_int(0, PHP_INT_MAX), true)) % 0xFFF;
150+
$this->lastSeconds = $seconds;
151+
$this->lastMilliseconds = $milliseconds;
152+
153+
return $this->sequence;
137154
}
138155
}

0 commit comments

Comments
 (0)