Skip to content

Support weaker consistency model for S3 MPUs#138663

Merged
DaveCTurner merged 10 commits intoelastic:mainfrom
DaveCTurner:2025/11/26/s3-conditional-mpu-cas
Nov 27, 2025
Merged

Support weaker consistency model for S3 MPUs#138663
DaveCTurner merged 10 commits intoelastic:mainfrom
DaveCTurner:2025/11/26/s3-conditional-mpu-cas

Conversation

@DaveCTurner
Copy link
Contributor

Adjusts the implementation of linearizable registers in S3 repositories
to allow for the weaker multipart upload API semantics observed in
practice.

Also adjusts the S3 test fixture to (optionally) simulate the weaker
semantics, and extends the repository analysis REST tests to cover both
cases.

Adjusts the implementation of linearizable registers in S3 repositories
to allow for the weaker multipart upload API semantics observed in
practice.

Also adjusts the S3 test fixture to (optionally) simulate the weaker
semantics, and extends the repository analysis REST tests to cover both
cases.
@DaveCTurner DaveCTurner added >bug :Distributed/Snapshot/Restore Anything directly related to the `_snapshot/*` APIs v9.3.0 labels Nov 26, 2025
@elasticsearchmachine elasticsearchmachine added the Team:Distributed Coordination (obsolete) Meta label for Distributed Coordination team. Obsolete. Please do not use. label Nov 26, 2025
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-distributed-coordination (Team:Distributed Coordination)

@elasticsearchmachine
Copy link
Collaborator

Hi @DaveCTurner, I've created a changelog YAML for you.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 26, 2025

🔍 Preview links for changed docs

@github-actions
Copy link
Contributor

ℹ️ Important: Docs version tagging

👋 Thanks for updating the docs! Just a friendly reminder that our docs are now cumulative. This means all 9.x versions are documented on the same page and published off of the main branch, instead of creating separate pages for each minor version.

We use applies_to tags to mark version-specific features and changes.

Expand for a quick overview

When to use applies_to tags:

✅ At the page level to indicate which products/deployments the content applies to (mandatory)
✅ When features change state (e.g. preview, ga) in a specific version
✅ When availability differs across deployments and environments

What NOT to do:

❌ Don't remove or replace information that applies to an older version
❌ Don't add new information that applies to a specific version without an applies_to tag
❌ Don't forget that applies_to tags can be used at the page, section, and inline level

🤔 Need help?

DaveCTurner added a commit to elastic/docs-content that referenced this pull request Nov 26, 2025
Copy link
Contributor

@joshua-adams-1 joshua-adams-1 left a comment

Choose a reason for hiding this comment

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

Looks good to me overall, just had a few small comments

package fixture.s3;

/**
* AWS S3 has weaker consistency for its multipart upload APIs than initially claimed (see support cases 10837136441 and 176070774900712)
Copy link
Contributor

Choose a reason for hiding this comment

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

Side note, are these weaker consistencies to be fixed, or "features" now?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Amazon have not indicated any interest in making changes in this area so we have to consider this a (somewhat-undocumented) feature of AWS S3 to be dealt with on our side.

* The alternative model verified by these tests: the multipart upload APIs are strongly consistent, but the {@code If-Match} and
* {@code If-None-Match} headers are ignored and all writes are unconditional.
*/
STRONG_MPUS(false, true);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible for a model to have both?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, but that's not a very interesting case to test.

Copy link
Contributor

Choose a reason for hiding this comment

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

Uninteresting because it should just work?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes pretty much: if both of the cases here work then the (true,true) case will work automatically. Each of these flags excludes certain kinds of misbehaviour, and the point is that excluding either of those classes yields a correct result. Excluding both classes is stronger than excluding either one of them.

}

protected S3ConsistencyModel consistencyModel() {
return S3ConsistencyModel.AWS_DEFAULT;
Copy link
Contributor

Choose a reason for hiding this comment

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

This value is set in both the S3HttpHandler and the S3HttpFixture. Is there a way to share it between classes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not really, there are various places we use the S3HttpHandler without the surrounding fixture, but if it is running within the fixture then we have to set it like this.

Alternatively we could make it a constructor parameter and set it explicitly everywhere we create one of these things. That adds some noise to this PR so I'd rather keep it like this for now, but I do prefer constructor parameters in general so might follow up with that change later.

}
}

public static void runInParallel(Runnable... tasks) {
Copy link
Contributor

Choose a reason for hiding this comment

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

[Nit] Missing Javadoc

Copy link
Contributor Author

Choose a reason for hiding this comment

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

++ thanks, fixed in 1fc5805.

}

protected S3ConsistencyModel consistencyModel() {
return S3ConsistencyModel.AWS_DEFAULT;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a benefit in randomising this between AWS_DEFAULT and STRONG_MPUS? (Not here, because we'd want multiple consistencyModel calls to be consistent, but as a class variable?). Would this remove the need to have the S3RepositoryAnalysisStrongMpusRestIT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I prefer to use randomisation for parameters that positively shouldn't matter for the purposes of the test, but this one really does matter so it's better to test both. I tried to do tricks with parameterisation etc. but it didn't work out very nicely since we construct the s3Fixture statically. There are some other options (e.g. we could make it mutable and set it during the test run) but nothing seemed totally ideal.

Copy link
Contributor

@joshua-adams-1 joshua-adams-1 left a comment

Choose a reason for hiding this comment

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

LGTM!

* The alternative model verified by these tests: the multipart upload APIs are strongly consistent, but the {@code If-Match} and
* {@code If-None-Match} headers are ignored and all writes are unconditional.
*/
STRONG_MPUS(false, true);
Copy link
Contributor

Choose a reason for hiding this comment

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

Uninteresting because it should just work?

@DaveCTurner DaveCTurner enabled auto-merge (squash) November 27, 2025 14:05
@DaveCTurner DaveCTurner merged commit 40e5ea3 into elastic:main Nov 27, 2025
34 checks passed
@DaveCTurner DaveCTurner deleted the 2025/11/26/s3-conditional-mpu-cas branch November 27, 2025 19:00
DaveCTurner added a commit to elastic/docs-content that referenced this pull request Nov 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

>bug :Distributed/Snapshot/Restore Anything directly related to the `_snapshot/*` APIs Team:Distributed Coordination (obsolete) Meta label for Distributed Coordination team. Obsolete. Please do not use. v9.3.0

3 participants