-
Notifications
You must be signed in to change notification settings - Fork 598
HDDS-13963. Atomic Create-If-Not-Exists #9332
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
afa8b6c
7868a86
d630699
f7ad505
2fdb6de
da492ce
0d4dfb0
f238ade
4e9665c
b5249f1
88aa08e
a1898c0
e5f5e3d
86489b6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -94,7 +94,13 @@ public OMRequest preExecute(OzoneManager ozoneManager) throws IOException { | |
| KeyArgs keyArgs = commitKeyRequest.getKeyArgs(); | ||
|
|
||
| if (keyArgs.hasExpectedDataGeneration()) { | ||
| ozoneManager.checkFeatureEnabled(OzoneManagerVersion.ATOMIC_REWRITE_KEY); | ||
| if (keyArgs.getExpectedDataGeneration() | ||
| == OzoneConsts.EXPECTED_GEN_CREATE_IF_NOT_EXISTS) { | ||
| ozoneManager.checkFeatureEnabled( | ||
| OzoneManagerVersion.ATOMIC_CREATE_IF_NOT_EXISTS); | ||
| } else { | ||
| ozoneManager.checkFeatureEnabled(OzoneManagerVersion.ATOMIC_REWRITE_KEY); | ||
| } | ||
| } | ||
|
|
||
| if (ozoneManager.getConfig().isKeyNameCharacterCheckEnabled()) { | ||
|
|
@@ -616,14 +622,23 @@ protected void validateAtomicRewrite(OmKeyInfo existing, OmKeyInfo toCommit, Map | |
| if (toCommit.getExpectedDataGeneration() != null) { | ||
| // These values are not passed in the request keyArgs, so add them into the auditMap if they are present | ||
| // in the open key entry. | ||
| auditMap.put(OzoneConsts.REWRITE_GENERATION, String.valueOf(toCommit.getExpectedDataGeneration())); | ||
| if (existing == null) { | ||
| throw new OMException("Atomic rewrite is not allowed for a new key", KEY_NOT_FOUND); | ||
| } | ||
| if (!toCommit.getExpectedDataGeneration().equals(existing.getUpdateID())) { | ||
| throw new OMException("Cannot commit as current generation (" + existing.getUpdateID() + | ||
| ") does not match the expected generation to rewrite (" + toCommit.getExpectedDataGeneration() + ")", | ||
| KEY_NOT_FOUND); | ||
| Long expectedGen = toCommit.getExpectedDataGeneration(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is the original purpose of this field?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The original purpose of this field was to support atomic key rewrite/create using optimistic concurrency. The client sends the generation it observed for the existing key, and OM only allows the write to proceed if the key still has that same generation at open and commit time. In practice, this generation is currently the key’s updateID, so the field is used for fencing against concurrent modification, rather than as a generic resource epoch. |
||
| auditMap.put(OzoneConsts.REWRITE_GENERATION, String.valueOf(expectedGen)); | ||
|
|
||
| if (expectedGen == OzoneConsts.EXPECTED_GEN_CREATE_IF_NOT_EXISTS) { | ||
| if (existing != null) { | ||
| throw new OMException("Key already exists", | ||
| OMException.ResultCodes.KEY_ALREADY_EXISTS); | ||
| } | ||
|
Comment on lines
+629
to
+632
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you help check whether it's better to use a new
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can use the header to tell the meaning behind the exception just like how } else if (ex.getResult() == ResultCodes.KEY_NOT_FOUND
&& getHeaders().getHeaderString(S3Consts.IF_MATCH_HEADER) != null) {
// If-Match failed because the key doesn't exist
throw newError(PRECOND_FAILED, keyPath, ex); |
||
| } else { | ||
| if (existing == null) { | ||
| throw new OMException("Atomic rewrite is not allowed for a new key", KEY_NOT_FOUND); | ||
| } | ||
| if (expectedGen != existing.getUpdateID()) { | ||
| throw new OMException("Cannot commit as current generation (" + existing.getUpdateID() + | ||
| ") does not match the expected generation to rewrite (" + expectedGen + ")", | ||
| KEY_NOT_FOUND); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.