Skip to content

ARSN-617: clean-read filter hiding non-localized versions - #2688

Open
DarkIsDude wants to merge 6 commits into
development/8.5from
improvement/ARSN-617/clean-read-filter
Open

ARSN-617: clean-read filter hiding non-localized versions#2688
DarkIsDude wants to merge 6 commits into
development/8.5from
improvement/ARSN-617/clean-read-filter

Conversation

@DarkIsDude

@DarkIsDude DarkIsDude commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Context

https://scality.atlassian.net/browse/ARSN-617

In a clean room, metadata is replicated before the object data is copied locally: until then the version's dataStoreName still points at the remote production site. Such a version is non-localized and must not be visible to clients.

What this adds

A per-call hideNonLocalizedVersions flag on the metadata read and listing APIs (getObject, getObjects, getBucketAndObject, listObject, listMultipartUploads).

Notes for ARSN-618

ARSN-618 answers the same "which version is current" question at write time, unconditionally, and can reuse the condition helpers and the getLatestVersion filter parameter added here. Read-time resolution stays necessary for entries that never traverse the write path (mongodump/mongorestore bootstrap and re-bootstrap loads); since the design rejected read-time master filtering, the design and ARSN-618 should record that it now exists. We can also decide to drop it as this use case should not exist in a DR architecture.

Add a per-call `cleanRead` flag on the metadata read and listing APIs,
hiding the object versions whose data still lives on a remote source
site (`locations[objMD.dataStoreName].isCRR`), as needed by the
clean-room D/R deployments. MongoClientInterface implements it in the
MongoDB query itself, so that listing limits and truncation stay
correct, and MetadataWrapper sets the flag on every read and listing
call when the deployment enables it.

Issue: ARSN-617
@bert-e

bert-e commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Hello darkisdude,

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.
/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 Aug 19, 2026

Copy link
Copy Markdown
Contributor

Incorrect fix version

The Fix Version/s in issue ARSN-617 contains:

  • None

Considering where you are trying to merge, I ignored possible hotfix versions and I expected to find:

  • 8.5.15

Please check the Fix Version/s of ARSN-617, or the target
branch of this pull request.

@codecov

codecov Bot commented Aug 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.13158% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.77%. Comparing base (d6ef4ed) to head (cad4307).
⚠️ Report is 3 commits behind head on development/8.5.

Files with missing lines Patch % Lines
lib/storage/metadata/mongoclient/readStream.js 73.07% 7 Missing ⚠️
lib/algos/list/delimiterMaster.ts 90.74% 5 Missing ⚠️
...orage/metadata/mongoclient/MongoClientInterface.ts 94.11% 3 Missing ⚠️
Additional details and impacted files
@@                 Coverage Diff                 @@
##           development/8.5    #2688      +/-   ##
===================================================
+ Coverage            74.66%   74.77%   +0.11%     
===================================================
  Files                  227      227              
  Lines                18606    18650      +44     
  Branches              3880     3892      +12     
===================================================
+ Hits                 13892    13946      +54     
+ Misses                4709     4699      -10     
  Partials                 5        5              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@DarkIsDude DarkIsDude self-assigned this Aug 24, 2026
@bert-e

bert-e commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Incorrect fix version

The Fix Version/s in issue ARSN-617 contains:

  • None

Considering where you are trying to merge, I ignored possible hotfix versions and I expected to find:

  • 8.5.16

Please check the Fix Version/s of ARSN-617, or the target
branch of this pull request.

Rename the per-call flag to `hideNonLocalizedVersions`, keep the
callback as the last argument of `getLatestVersion`, and trim the
comments down to the non-obvious ones.

Issue: ARSN-617
A master pointing at a non-localized version is no longer hidden: the
master key is resolved on the way out of the listing stream, exposing
the newest localized version of the object — the same resolution a PHD
key goes through, and the same one getObject already performs, so a
listing and a GET agree. Only an object with no localized version at
all is dropped.

Issue: ARSN-617
@bert-e

bert-e commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Incorrect fix version

The Fix Version/s in issue ARSN-617 contains:

  • 8.5.15

Considering where you are trying to merge, I ignored possible hotfix versions and I expected to find:

  • 8.5.16

Please check the Fix Version/s of ARSN-617, or the target
branch of this pull request.

@bert-e

bert-e commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Waiting for approval

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

  • the author

  • 2 peers

@DarkIsDude
DarkIsDude marked this pull request as ready for review August 31, 2026 09:11
@DarkIsDude
DarkIsDude requested review from a team, SylvainSenechal, delthas and maeldonn August 31, 2026 09:11
@maeldonn

Copy link
Copy Markdown
Contributor

Please remove the footer Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> from your commits 🙏

@DarkIsDude
DarkIsDude force-pushed the improvement/ARSN-617/clean-read-filter branch from ae474fa to cad4307 Compare August 31, 2026 13:02
this.replicationGroupId = replicationGroupId;
this.database = database;
this.isLocationTransient = isLocationTransient;
this.getLocationConstraints = getLocationConstraints;

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.

this does not look the a list of "location constraints" : but really the actual list/map of locations.

("Location constraint" is a parameter of a bucket, which indicates in AWS in which region the bucket is; and which we use instead to track the default data location for the bucket)

if (!hide) {
return null;
}
const excluded = this.nonLocalizedLocations();

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.

list of locations do not change, best to compute this list just once in constructor

Comment on lines +2488 to +2490
// when the master keys are resolved, the stream must keep the
// non-localized masters so that they can be replaced by the newest
// localized version of their object

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.

not needed : c.f. design and next ticket ARSN-618, the master is not updated when inserting a non-localized version... so only versions need filtering.

or is there something which was missed in the design?

Comment on lines +354 to +355
`getLocationConstraints` parameter, evaluated on each call so that
configuration updates are picked up.

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.

configuration cannot be updated dynamically. The locations are defined in a config file, and service is restarted when the list changes.

stream, the same way a PHD key is resolved. An object with no localized
version at all is dropped from the listing;
- `getObject` resolves a hidden master the same way, so a listing and a `GET`
agree on which version is current;

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.

The current version IS the localized version (the non-localized version in an "internal" version, so to say):

  • getObject should only point to latest localized version
  • GetObjectVersion returns the version, whether it is localized or not

Backbeat needs (internally) be able to see all the versions, but I don't think it needs the master: thinking of the use cases, maybe it is actually safer if even backbeat does not list these objets:

  • Lifecycle must not delete these objects (or delete the next "non-current" versions),
  • Bucket notification acts on versions, no listing or master access - so not affected
  • Replication cannot (yet) replicate the objects, so should ignore them
  • Pull-replication does not perform listing or access master, but must be able to both read and update the metadata of any version
  • Listing versions may be needed for tooling (e.g. finding non-localized objects), but this should not affect listing of masters

Some filtering will be done in backbeat indeed, and we probably need to "strict" when answering to external client (i.e. reject reading object/version if not localized) ; but we should avoid complexfying the code for path which do not need it (e.g. listing master or resolving non-localized master): are there situations where do you think this is needed?

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.

Read-time resolution stays necessary for entries that never traverse the write path (mongodump/mongorestore bootstrap and re-bootstrap loads)

Bootstrap should no copy master either (since they are not localized), and thus master resolution is not needed: the master is only created when the ObjMD is finally "localized" - which happens regular arsenal calls and would be handled by ARSN-618

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.

Not at all, as explained in the description. I was not really sure if I should be strict or not, you seems to have the answer. I'll then remove that and have a less defensive code 🙏

and are therefore never hidden;
- a master listing (`DelimiterMaster`) keeps the objects whose current version
is not localized, and lists them with their newest localized version — the
master key is resolved through `getLatestVersion` on the way out of the

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.

the master should always point to a localized version, per the design : next (arsenal) ticket is about making sure putObject handles this

return false;
}
try {
return nonLocalizedLocations.includes(JSON.parse(obj.value).dataStoreName);

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.

this can be quite costly: JSON parse() call (object MD can be large, esp. for bug MPUs) + linear search (though not sure how many CRR locations we would have)

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.

4 participants