wecharyu commented on code in PR #10886:
URL: https://github.com/apache/hudi/pull/10886#discussion_r1571697843


##########
hudi-common/src/main/java/org/apache/hudi/common/model/HoodiePartitionMetadata.java:
##########
@@ -92,37 +94,33 @@ public int getPartitionDepth() {
 
   /**
    * Write the metadata safely into partition atomically.
+   * To avoid concurrent write into the same partition (for example in 
speculative case),
+   * please make sure writeToken is unique.
    */
-  public void trySave(int taskPartitionId) {
+  public void trySave(String writeToken) throws IOException {
     String extension = getMetafileExtension();
-    Path tmpMetaPath =
-        new Path(partitionPath, 
HoodiePartitionMetadata.HOODIE_PARTITION_METAFILE_PREFIX + "_" + 
taskPartitionId + extension);
     Path metaPath = new Path(partitionPath, 
HoodiePartitionMetadata.HOODIE_PARTITION_METAFILE_PREFIX + extension);
-    boolean metafileExists = false;
 
-    try {
-      metafileExists = fs.exists(metaPath);
-      if (!metafileExists) {
-        // write to temporary file
-        writeMetafile(tmpMetaPath);
-        // move to actual path
-        fs.rename(tmpMetaPath, metaPath);
-      }
-    } catch (IOException ioe) {
-      LOG.warn("Error trying to save partition metadata (this is okay, as long 
as at least 1 of these succeeded), "
-          + partitionPath, ioe);
-    } finally {
-      if (!metafileExists) {
-        try {
-          // clean up tmp file, if still lying around
-          if (fs.exists(tmpMetaPath)) {
-            fs.delete(tmpMetaPath, false);
+    // This retry mechanism enables an exit-fast in metaPath exists check, 
which avoid the
+    // tasks failures when there are two or more tasks trying to create the 
same metaPath.
+    RetryHelper<Void, IOException>  retryHelper = new RetryHelper(1000, 3, 
1000, IOException.class.getName())
+        .tryWith(() -> {
+          if (!fs.exists(metaPath)) {
+            if (format.isPresent()) {
+              Path tmpMetaPath = new Path(partitionPath, 
HoodiePartitionMetadata.HOODIE_PARTITION_METAFILE_PREFIX + "_" + writeToken + 
extension);
+              writeMetafileInFormat(metaPath, tmpMetaPath, format.get());
+            } else {
+              // Backwards compatible properties file format
+              try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+                props.store(os, "partition metadata");
+                Option content = Option.of(os.toByteArray());
+                HadoopFSUtils.createImmutableFileInPath(fs, metaPath, content, 
true, "_" + writeToken);

Review Comment:
   Done.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to