Added headers for CRR Cascaded#24
Conversation
Hello sylvainsenechal,My role is to assist you with the merge of this Available options
Available commands
Status report is not available. |
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
|
e2a81bf to
798a647
Compare
There was a problem hiding this comment.
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
| @httpHeader("x-scal-cascade-loop-detected") | ||
| CascadeLoopDetected: Boolean |
There was a problem hiding this comment.
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"
There was a problem hiding this comment.
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"
There was a problem hiding this comment.
edit: name updated, let me know if you have other name ideas
There was a problem hiding this comment.
I thought it would be better for future maintainers to understand what this field is used for.
this is exactly my point : it will be easier to maintain a simple contract (return a conflict error if micro version id is older; also return previous micro version id), and be reusable ; instead of having a contract which is specific to a specific use case (when doing cascaded crr, backbeat will make this call and cloudserver should do this specific logic, so that ...)
i.e. we should avoid "specific use case" in API, and "simple, generic, intelligible contracts"
|
|
||
|
|
||
| @httpHeader("x-scal-micro-version-id") | ||
| MicroVersionId: String, |
There was a problem hiding this comment.
nit: to make the semantic explicit, field could be name something like IfMicroVersionIdOlderThan (i.e. semantics is part of the API)
There was a problem hiding this comment.
Leaving for now, what do other ppl think about the naming ?
There was a problem hiding this comment.
@scality/raving-robots WDYT?
There was a problem hiding this comment.
x-scal-micro-version-id is simpler and easier to understand.
There was a problem hiding this comment.
🤝ok.
We however should document the semantics of this field here: i.e. it will conflict (and not write metadata) if micro version id is older than the one already stored
798a647 to
a072957
Compare
|
|
||
|
|
||
| @httpHeader("x-scal-micro-version-id") | ||
| MicroVersionId: String, |
There was a problem hiding this comment.
x-scal-micro-version-id is simpler and easier to understand.
| versionId: String, | ||
|
|
||
| @httpHeader("x-scal-micro-version-id-exists") | ||
| MicroVersionIdExists: Boolean |
There was a problem hiding this comment.
Should be x-scal-replication-loop to differentiate between a success write and a loop skip.
There was a problem hiding this comment.
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
| input: PutMetadataInput, | ||
| output: PutMetadataOutput | ||
| output: PutMetadataOutput, | ||
| errors: [ConflictException] |
There was a problem hiding this comment.
Should also be added to putData
There was a problem hiding this comment.
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..
There was a problem hiding this comment.
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 🤔
There was a problem hiding this comment.
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
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
The following reviewers are expecting changes from the author, or must review again: |
a072957 to
ec98192
Compare
| ReplicationLoop: Boolean | ||
| } | ||
|
|
||
| @error("client") |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
When testing cloudserver client, there is some kind of circular dependency where I can test the client either here, in cloudserver or in backbeat.
I have functional tests in both backbeat and cloudserver that triggers these errors
| @httpError(409) | ||
| structure StaleMicroVersionIdException { | ||
| @required | ||
| message: String |
There was a problem hiding this comment.
- should the micro-version-id be returned in that case? Maybe we don't use it today, but could be used?
- would also allow to use the same Exception for PutData and PutMetadata 409 errors
There was a problem hiding this comment.
I'm adding the micro version id as its not really costing us anything
I don't think we should merge the 2 error exception, that would force backbeat to have more logic to reclassify to first verify 409, then classify the 409 based on the microversion id
With the current setup, the classification is done directly in cloudserver and the backbeat code handling the error reads easily
|
|
||
| @error("client") | ||
| @httpError(409) | ||
| structure VersionIdCollisionException { |
There was a problem hiding this comment.
Backbeat will pattern-match on this (err.name == VersionIdCollisionException). Consider documenting the error:
/// Returned by PutData when the destination already has an object at this
/// versionId. The existing microVersionId is included in the response header
/// so the caller can run the cascade loop/stale/proceed classification.
@error("client")
@httpError(409)
structure VersionIdCollisionException { ... }| structure PutMetadataOutput { | ||
| /// Version ID of the stored metadata | ||
| versionId: String | ||
| versionId: String, |
There was a problem hiding this comment.
Align all fields to camelCase or PascalCase
There was a problem hiding this comment.
Actually, versionId is an existing field, i think it was already lowered case even before we started using cloudserverclient.
Looking at many other apis, their output is almost always using lowered case versionIds, so I think instead i will switch ReplicationLoop to camelCase
|
|
||
| @error("client") | ||
| @httpError(409) | ||
| structure StaleMicroVersionIdException { |
There was a problem hiding this comment.
Same doc-comment suggestion as VersionIdCollisionException:
/// Returned by PutMetadata when the incoming microVersionId is older than
/// the destination's current value (stale cascade event). The write is not
/// applied; the caller should mark the replication as FAILED (non-retryable).
@error("client")
@httpError(409)
structure StaleMicroVersionIdException { ... }ec98192 to
94c822c
Compare
| versionId: String, | ||
|
|
||
| @httpHeader("x-scal-replication-loop") | ||
| replicationLoop: Boolean |
There was a problem hiding this comment.
when do we have 200 and "replicationLoop" ?
is this not just a StaleMicroVersionIdException as well (with the same micro version id) ?
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