<commit_before>/*
 * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0
 * (the "License"). You may not use this work except in compliance with the License, which is
 * available at www.apache.org/licenses/LICENSE-2.0
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied, as more fully set forth in the License.
 *
 * See the NOTICE file distributed with this work for information regarding copyright ownership.
 */

package alluxio.master.file.meta;

import alluxio.AlluxioURI;
import alluxio.exception.ExceptionMessage;
import alluxio.master.journal.JournalContext;
import alluxio.proto.journal.File;
import alluxio.proto.journal.Journal;
import alluxio.retry.ExponentialBackoffRetry;
import alluxio.retry.RetryPolicy;
import alluxio.security.authorization.Mode;
import alluxio.underfs.UnderFileSystem;
import alluxio.underfs.options.MkdirsOptions;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * Utility methods for inodes.
 */
public final class InodeUtils {
  private static final Logger LOG = LoggerFactory.getLogger(InodeUtils.class);
  /** The base amount (exponential backoff) to sleep before retrying persisting an inode. */
  private static final int PERSIST_WAIT_BASE_SLEEP_MS = 2;
  /** Maximum amount (exponential backoff) to sleep before retrying persisting an inode. */
  private static final int PERSIST_WAIT_MAX_SLEEP_MS = 1000;
  /** The maximum retries for persisting an inode. */
  private static final int PERSIST_WAIT_MAX_RETRIES = 50;

  private InodeUtils() {} // prevent instantiation

  /**
   * Synchronously persists an {@link InodeDirectory} to the UFS. If concurrent calls are made, only
   * one thread will persist to UFS, and the others will wait until it is persisted.
   *
   * @param dir the {@link InodeDirectory} to persist
   * @param inodeTree the {@link InodeTree}
   * @param mountTable the {@link MountTable}
   * @param journalContext the journal context
   * @throws IOException if the file fails to persist
   */
  public static void syncPersistDirectory(InodeDirectory dir, InodeTree inodeTree,
      MountTable mountTable, JournalContext journalContext) throws IOException {
    RetryPolicy retry =
        new ExponentialBackoffRetry(PERSIST_WAIT_BASE_SLEEP_MS, PERSIST_WAIT_MAX_SLEEP_MS,
            PERSIST_WAIT_MAX_RETRIES);
    while (dir.getPersistenceState() != PersistenceState.PERSISTED) {
      if (dir.compareAndSwap(PersistenceState.NOT_PERSISTED,
          PersistenceState.TO_BE_PERSISTED)) {
        boolean success = false;
        StringBuilder errorDetails = new StringBuilder("Inode: ").append(dir.toString());
        try {
          AlluxioURI uri = inodeTree.getPath(dir);
          MountTable.Resolution resolution = mountTable.resolve(uri);
          String ufsUri = resolution.getUri().toString();
          errorDetails.append(" ufsUri: ").append(ufsUri);
          UnderFileSystem ufs = resolution.getUfs();
          MkdirsOptions mkdirsOptions =
              MkdirsOptions.defaults().setCreateParent(false).setOwner(dir.getOwner())
                  .setGroup(dir.getGroup()).setMode(new Mode(dir.getMode()));
          if (!ufs.isDirectory(ufsUri)) {
            ufs.mkdirs(ufsUri, mkdirsOptions);
          }
          dir.setPersistenceState(PersistenceState.PERSISTED);

          // Append the persist entry to the journal.
          File.PersistDirectoryEntry persistDirectory =
              File.PersistDirectoryEntry.newBuilder().setId(dir.getId()).build();
          journalContext.append(
              Journal.JournalEntry.newBuilder().setPersistDirectory(persistDirectory).build());
          success = true;
        } catch (Exception e) {
          // Ignore
          LOG.warn("Failed to persist directory to UFS: {} : {}", errorDetails.toString(),
              e.getMessage());
          LOG.debug("Exception: ", e);
        } finally {
          if (!success) {
            // Failed to persist the inode, so set the state back to NOT_PERSISTED.
            dir.setPersistenceState(PersistenceState.NOT_PERSISTED);
          }
        }
      } else {
        if (!retry.attemptRetry()) {
          throw new IOException(ExceptionMessage.FAILED_UFS_CREATE.getMessage(dir.getName()));
        }
      }
    }
  }
}<commit_msg>Expose exceptions in syncPersistDirectory<commit_after>/*
 * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0
 * (the "License"). You may not use this work except in compliance with the License, which is
 * available at www.apache.org/licenses/LICENSE-2.0
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied, as more fully set forth in the License.
 *
 * See the NOTICE file distributed with this work for information regarding copyright ownership.
 */

package alluxio.master.file.meta;

import alluxio.AlluxioURI;
import alluxio.exception.ExceptionMessage;
import alluxio.exception.FileDoesNotExistException;
import alluxio.exception.InvalidPathException;
import alluxio.master.journal.JournalContext;
import alluxio.proto.journal.File;
import alluxio.proto.journal.Journal;
import alluxio.retry.ExponentialBackoffRetry;
import alluxio.retry.RetryPolicy;
import alluxio.security.authorization.Mode;
import alluxio.underfs.UnderFileSystem;
import alluxio.underfs.options.MkdirsOptions;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * Utility methods for inodes.
 */
public final class InodeUtils {
  private static final Logger LOG = LoggerFactory.getLogger(InodeUtils.class);
  /** The base amount (exponential backoff) to sleep before retrying persisting an inode. */
  private static final int PERSIST_WAIT_BASE_SLEEP_MS = 2;
  /** Maximum amount (exponential backoff) to sleep before retrying persisting an inode. */
  private static final int PERSIST_WAIT_MAX_SLEEP_MS = 1000;
  /** The maximum retries for persisting an inode. */
  private static final int PERSIST_WAIT_MAX_RETRIES = 50;

  private InodeUtils() {} // prevent instantiation

  /**
   * Synchronously persists an {@link InodeDirectory} to the UFS. If concurrent calls are made, only
   * one thread will persist to UFS, and the others will wait until it is persisted.
   *
   * @param dir the {@link InodeDirectory} to persist
   * @param inodeTree the {@link InodeTree}
   * @param mountTable the {@link MountTable}
   * @param journalContext the journal context
   * @throws IOException if the file fails to persist
   */
  public static void syncPersistDirectory(InodeDirectory dir, InodeTree inodeTree,
      MountTable mountTable, JournalContext journalContext) throws IOException,
      InvalidPathException, FileDoesNotExistException {
    RetryPolicy retry =
        new ExponentialBackoffRetry(PERSIST_WAIT_BASE_SLEEP_MS, PERSIST_WAIT_MAX_SLEEP_MS,
            PERSIST_WAIT_MAX_RETRIES);
    while (dir.getPersistenceState() != PersistenceState.PERSISTED) {
      if (dir.compareAndSwap(PersistenceState.NOT_PERSISTED,
          PersistenceState.TO_BE_PERSISTED)) {
        boolean success = false;
        StringBuilder errorDetails = new StringBuilder("Inode: ").append(dir.toString());
        try {
          AlluxioURI uri = inodeTree.getPath(dir);
          MountTable.Resolution resolution = mountTable.resolve(uri);
          String ufsUri = resolution.getUri().toString();
          errorDetails.append(" ufsUri: ").append(ufsUri);
          UnderFileSystem ufs = resolution.getUfs();
          MkdirsOptions mkdirsOptions =
              MkdirsOptions.defaults().setCreateParent(false).setOwner(dir.getOwner())
                  .setGroup(dir.getGroup()).setMode(new Mode(dir.getMode()));
          ufs.mkdirs(ufsUri, mkdirsOptions);
          dir.setPersistenceState(PersistenceState.PERSISTED);

          // Append the persist entry to the journal.
          File.PersistDirectoryEntry persistDirectory =
              File.PersistDirectoryEntry.newBuilder().setId(dir.getId()).build();
          journalContext.append(
              Journal.JournalEntry.newBuilder().setPersistDirectory(persistDirectory).build());
          success = true;
        } finally {
          if (!success) {
            // Failed to persist the inode, so set the state back to NOT_PERSISTED.
            dir.setPersistenceState(PersistenceState.NOT_PERSISTED);
          }
        }
      } else {
        if (!retry.attemptRetry()) {
          throw new IOException(ExceptionMessage.FAILED_UFS_CREATE.getMessage(dir.getName()));
        }
      }
    }
  }
}
{'fraction_non_alphanumeric': 0.08850985363604932, 'fraction_numerical': 0.0029964273366370866, 'mean_word_length': 3.4050761421319797, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3142306', 'n_tokens_mistral': 2458, 'n_tokens_neox': 2429, 'n_words': 665}