ARSN-617: clean-read filter hiding non-localized versions - #2688
ARSN-617: clean-read filter hiding non-localized versions#2688DarkIsDude wants to merge 6 commits into
Conversation
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
Hello darkisdude,My role is to assist you with the merge of this Available options
Available commands
Status report is not available. |
Codecov Report❌ Patch coverage is 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. 🚀 New features to boost your workflow:
|
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
Waiting for approvalThe following approvals are needed before I can proceed with the merge:
|
|
Please remove the footer |
ae474fa to
cad4307
Compare
| this.replicationGroupId = replicationGroupId; | ||
| this.database = database; | ||
| this.isLocationTransient = isLocationTransient; | ||
| this.getLocationConstraints = getLocationConstraints; |
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
list of locations do not change, best to compute this list just once in constructor
| // 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 |
There was a problem hiding this comment.
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?
| `getLocationConstraints` parameter, evaluated on each call so that | ||
| configuration updates are picked up. |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
The current version IS the localized version (the non-localized version in an "internal" version, so to say):
getObjectshould only point to latest localized versionGetObjectVersionreturns 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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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)
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
dataStoreNamestill 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
hideNonLocalizedVersionsflag 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
getLatestVersionfilter 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.