Skip to content

Added headers for CRR Cascaded#24

Open
SylvainSenechal wants to merge 2 commits into
development/1.0from
improvement/CLDSRVCLT-14
Open

Added headers for CRR Cascaded#24
SylvainSenechal wants to merge 2 commits into
development/1.0from
improvement/CLDSRVCLT-14

Conversation

@SylvainSenechal

@SylvainSenechal SylvainSenechal commented May 21, 2026

Copy link
Copy Markdown
Contributor

ISSUE : CLDSRVCLT-14

Crr cascaded design : https://github.com/scality/citadel/pull/349

Related PRs :
Arsenal : scality/Arsenal#2628
Cloudserver : scality/cloudserver#6179
Backbeat : scality/backbeat#2747
S3utils : scality/s3utils#395

@bert-e

bert-e commented May 21, 2026

Copy link
Copy Markdown

Hello sylvainsenechal,

My role is to assist you with the merge of this
pull request. Please type @bert-e help to get information
on this process, or consult the user documentation.

Available options
name description privileged authored
/after_pull_request Wait for the given pull request id to be merged before continuing with the current one.
/bypass_author_approval Bypass the pull request author's approval
/bypass_build_status Bypass the build and test status
/bypass_commit_size Bypass the check on the size of the changeset TBA
/bypass_incompatible_branch Bypass the check on the source branch prefix
/bypass_jira_check Bypass the Jira issue check
/bypass_peer_approval Bypass the pull request peers' approval
/bypass_leader_approval Bypass the pull request leaders' approval
/approve Instruct Bert-E that the author has approved the pull request. ✍️
/create_pull_requests Allow the creation of integration pull requests.
/create_integration_branches Allow the creation of integration branches.
/no_octopus Prevent Wall-E from doing any octopus merge and use multiple consecutive merge instead
/unanimity Change review acceptance criteria from one reviewer at least to all reviewers
/wait Instruct Bert-E not to run until further notice.
Available commands
name description privileged
/help Print Bert-E's manual in the pull request.
/status Print Bert-E's current status in the pull request TBA
/clear Remove all comments from Bert-E from the history TBA
/retry Re-start a fresh build TBA
/build Re-start a fresh build TBA
/force_reset Delete integration branches & pull requests, and restart merge process from the beginning.
/reset Try to remove integration branches unless there are commits on them which do not appear on the source branch.

Status report is not available.

@bert-e

bert-e commented May 21, 2026

Copy link
Copy Markdown

Waiting for approval

The following approvals are needed before I can proceed with the merge:

  • the author

  • 2 peers

Comment thread models/backbeatRoutes/putdata.smithy
@SylvainSenechal SylvainSenechal force-pushed the improvement/CLDSRVCLT-14 branch 3 times, most recently from e2a81bf to 798a647 Compare May 29, 2026 18:39

@SylvainSenechal SylvainSenechal May 29, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First I added some tests in this codebase, but they were too functional and not really oriented toward just testing the client itself. + we already have test testing the client itself for putData/putMetadata

So I added the tests in Cloudserver : They are functional tests using CloudserverClient with the micro version id, testing 409 error, actual api behavior etc. I think they are better in cloudserver than in here

Comment thread models/backbeatRoutes/putdata.smithy Outdated
RequestUids: String,

@httpHeader("x-scal-micro-version-id")
MicroVersionId: String,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as discussed (late) in the design, not an input parameter : PutData should minimize work/logic related to metadata, and should simply return the current microVersionId (instead of "x-scal-cascade-loop-detected")

this will reduce coupling, while giving all flexibility for backbeat to take all decisions.

Comment on lines +49 to +50
@httpHeader("x-scal-cascade-loop-detected")
CascadeLoopDetected: Boolean

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PutMetadata is a generic api, used in many more cases than CRR.
→ api should stay generic, no reason to introduce "crr cascaded" vocabulary : stick to some generic concept, like "conflict" or "already have microVersionId"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about this but I thought it would be better for future maintainers to understand what this field is used for.
I dont wanna go with conflict as this would already be used for microVersionId that are too old, but I'll find something for the equality around "already have micro version id"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

edit: name updated, let me know if you have other name ideas



@httpHeader("x-scal-micro-version-id")
MicroVersionId: String,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: to make the semantic explicit, field could be name something like IfMicroVersionIdOlderThan (i.e. semantics is part of the API)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving for now, what do other ppl think about the naming ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@scality/raving-robots WDYT?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

x-scal-micro-version-id is simpler and easier to understand.

versionId: String,

@httpHeader("x-scal-micro-version-id-exists")
MicroVersionIdExists: Boolean

@francoisferrand francoisferrand Jun 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: when it exists, should it return just a bool or actually the value itself ?(previous or current, not sure what we need)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be a bool

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bool works, although yeah, we could return a microVersionId and let backbeat decide for itself what it should do with it

Comment thread models/backbeatRoutes/putdata.smithy Outdated
SSEKMSKeyId: String,

@httpHeader("x-scal-micro-version-id")
ExistingMicroVersionId: String

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just MicroVersionId, consistent with the x-scal header

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah and actually i did some rework to integrate this with the error of handling of smithy, this is defined and returned with the VersionIdCollisionException now

@httpHeader("X-Scal-Request-Uids")
RequestUids: String,

@httpHeader("x-scal-source-version-id")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why "source" ? you usual header is x-scal-version-id I think, should stick to it ?

@SylvainSenechal SylvainSenechal Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a code that's already not super easy to read, I think its easy to mix up ids, and being able to write this on cloudserver just make thing very clear 🤔

const incomingVersionIdEncoded = request.headers['x-scal-source-version-id'];

edit: Yeah actually in cloudserver, we already have similar pattern in routebackbeat (x-scal-source-version-id, x-scal-source-bucket), so I prefer to keep it like this

@httpHeader("X-Scal-Request-Uids")
RequestUids: String,

@httpHeader("x-scal-source-version-id")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be marked as "optional" : if not set, we should keep previous/existing behavior (no conflict detection etc)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be confirmed, but I think it's optional by default.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thats right, there is an @required field
that will produce this for example.
Else the field is optional
Image



@httpHeader("x-scal-micro-version-id")
MicroVersionId: String,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

x-scal-micro-version-id is simpler and easier to understand.

versionId: String,

@httpHeader("x-scal-micro-version-id-exists")
MicroVersionIdExists: Boolean

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be x-scal-replication-loop to differentiate between a success write and a loop skip.

@SylvainSenechal SylvainSenechal Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used
if data.MicroVersionIdExists to check if we had a success or a loop

edit:
nvm yeah I reviewed the naming and used
x-scal-replication-loop
replicationLoop

versionId: String,

@httpHeader("x-scal-micro-version-id-exists")
MicroVersionIdExists: Boolean

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be a bool

input: PutMetadataInput,
output: PutMetadataOutput
output: PutMetadataOutput,
errors: [ConflictException]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also be added to putData

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it from putData, it doesn't raise a 409 anymore, and instead just return 200 with micro version id, and backbeat do the check.

But honestly this is all a bit complicated, having to deal with both error code and returned values that are either booleans or microVersionId..

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah i'm a bit starting to question the current implementation, as again it works but it's tricky to mix error code, with boolean flag, with string returned value.

Would probably be wiser and easier to maintain to just have a "CrrCascadeOutcome" = 'dataAlreadyExists' | 'loop' | 'stale' or whatever we need, and just have backbeat switch on all cases.

Because here in backbeat it gets a bit dirty 🤔

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forget about the 2 other messages,
I did some rework to properly integrate the smithy errors

Now backbeat will be able to check errors like this :

err instanceof StaleMicroVersionIdException

@bert-e

bert-e commented Jun 5, 2026

Copy link
Copy Markdown

Waiting for approval

The following approvals are needed before I can proceed with the merge:

  • the author

  • 2 peers

The following reviewers are expecting changes from the author, or must review again:

ReplicationLoop: Boolean
}

@error("client")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add a test for this changes the generated client contract, but nothing checks that MicroVersionId / versionId are serialized as headers, nor that the new 409 errors are deserialized with their headers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants