Upgrade microVersionId to timestamp-ordered format and add isReplica#2628
Upgrade microVersionId to timestamp-ordered format and add isReplica#2628maeldonn wants to merge 2 commits into
Conversation
Hello maeldonn,My role is to assist you with the merge of this Available options
Available commands
Status report is not available. |
|
LGTM |
caf9a51 to
868cae8
Compare
Review by Claude Code |
868cae8 to
2eae0c5
Compare
|
LGTM |
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
|
Review by Claude Code |
fbaf3fe to
3160d6b
Compare
|
LGTM — one breaking change to flag: |
3160d6b to
5f4839a
Compare
2d68077 to
031c259
Compare
| storageType: storageType || '', | ||
| dataStoreVersionId: dataStoreVersionId || '', | ||
| isNFS, | ||
| isReplica: isReplica !== undefined ? isReplica : (status === 'REPLICA' ? true : undefined), |
There was a problem hiding this comment.
| isReplica: isReplica !== undefined ? isReplica : (status === 'REPLICA' ? true : undefined), | |
| isReplica: isReplica !== undefined ? isReplica : (status === 'REPLICA' ? true : false), |
not sure if undefined or false when status not REPLICA
There was a problem hiding this comment.
Since it's a boolean i would say false. But if we can save some storage in database, we should use undefined.
There was a problem hiding this comment.
I would say false too, avoid as much undefined variable as possible 🤔 What do other think ?
110b0c8 to
e166386
Compare
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## development/8.4 #2628 +/- ##
===================================================
+ Coverage 73.92% 73.96% +0.04%
===================================================
Files 229 229
Lines 18480 18501 +21
Branches 3822 3830 +8
===================================================
+ Hits 13661 13685 +24
+ Misses 4814 4811 -3
Partials 5 5 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
e166386 to
2c429ab
Compare
|
| * - the legacy 16-char random-hex value written by old ObjectMD code | ||
| * - any other string shorter than the minimum valid raw length (27 chars) | ||
| */ | ||
| export function isMicroVersionIdComparable(id: string | null | undefined): boolean { |
There was a problem hiding this comment.
| export function isMicroVersionIdComparable(id: string | null | undefined): boolean { | |
| export function isComparable(id?: string | null): boolean { |
There was a problem hiding this comment.
Can the field really be null ? 🤔
There was a problem hiding this comment.
Re-using this comment to ask :
you want some name changes
isMicroVersionIdComparable -> isComparable
checkCrrCascadeEvent -> compare
I say why not but its a bit annoying that the repo using this code
has to do :
const { versioning } = require('arsenal');
versioning.VersionID.checkCrrCascadeEvent()
Or
const { decode, encode, checkCrrCascadeEvent } = versioning.VersionID;
checkCrrCascadeEvent()
Like I mean the namespace isnt microversionId exactly 🤔
| * 16-char hex, or otherwise too short) : a legacy incoming ID must never | ||
| * produce a false 'stale' or 'loop' event | ||
| */ | ||
| export function checkCrrCascadeEvent( |
There was a problem hiding this comment.
| export function checkCrrCascadeEvent( | |
| export function compare( |
There was a problem hiding this comment.
'loop' | 'stale' | 'proceed' are specific to CRR not to versionID format. We should just expose a simple compare function in this file
There was a problem hiding this comment.
ah yeah something that would return
'equal' | 'older' | 'younger' 🤔
It's a bit annoying though, because in the first if, it's just not comparable and we return proceed.
Feels like we would need another utility function on top of this utility function if we want something nice usable for crr cascade 🤔 Or need to return a fourth 'not comparable' value, then it can work
Like in backbeat I would prefer to call
if checkCrrCascadeEvent(id1, id2) === 'proceed' {do proceed logic}
than
if compare(id1,id1) === ('older' || 'not comparable') {do proceed logic} 🤔
I want some more THOUGHTS before making a change
|
|
||
| setReplicationStatus(status: string) { | ||
| this._data.replicationInfo.status = status; | ||
| if (status === 'REPLICA') { |
There was a problem hiding this comment.
I think this is useless since we are not going anymore to set status to 'REPLICA'
There was a problem hiding this comment.
Shouldn't we at least keep it to avoid weird state ?
Really not sure about this, maybe we can get thoughts from somebody else.
Also are you sure we aren't gonna use setReplicationStatus ? In backbeat, in ObjectQueueEntry.js, I see some setReplicationStatus('REPLICA'), I haven't touched them for crrCascade, maybe you did for multi destination, but not sure.
There was a problem hiding this comment.
I'd also say lets keep it to avoid breaking any behavior
| * @return true if this object is a replica | ||
| */ | ||
| getReplicationIsReplica(): boolean { | ||
| return this._data.replicationInfo.isReplica === true |
There was a problem hiding this comment.
Not sure if we need logic in this getter. Is it used somewhere ?
There was a problem hiding this comment.
I don't understand the comment 🤔
What logic in this getter is not needed, the || this._data.replicationInfo.status === 'REPLICA'; ?
Do you mean we should only return isReplica ?
Replace the random 8-byte hex microVersionId the timestamp-ordered identifier matching the versionId scheme, and add helpers for the crr cascade feature. Add an optional isReplica flag to ReplicationInfo to distinguish replica writes from user writes, enabling cascaded CRR. Issue: ARSN-578
2c429ab to
83682d1
Compare
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
|
|
| if (incomingRaw === existing) { | ||
| return 'loop'; | ||
| } | ||
| if (incomingRaw > existing) { |
There was a problem hiding this comment.
is comparing the full id intentional?
the ordering after timestamp/seq includes rg/instance data, so same-slot writes can be classified as stale based on ids, not time
| * - any other string shorter than the minimum valid raw length (27 chars) | ||
| */ | ||
| export function isMicroVersionIdComparable(id: string | null | undefined): boolean { | ||
| return typeof id === 'string' && id.length >= LEGACY_BASE62_DECODED_LENGTH; |
There was a problem hiding this comment.
is length really enough to decide this is comparable?
if this can come from metadata or headers, a malformed 27+ chars string may produce a stale decision..

Replace the random 8-byte hex microVersionId with a 20-character timestamp-ordered identifier matching the versionId scheme, and add encode/decode/compare helpers in a new MicroVersionID module. Add an optional isReplica flag to ReplicationInfo to distinguish replica writes from user writes, enabling cascaded CRR.
Issue: ARSN-578
Crr cascaded design : https://github.com/scality/citadel/pull/349
Related PRs :
Cloudserver : scality/cloudserver#6179
CloudserverClient : scality/cloudserverclient#24
Backbeat : scality/backbeat#2747
S3utils : scality/s3utils#395