Ejemplo n.º 1
0
  /**
   * Aborts a temp block.
   *
   * @param sessionId the id of session
   * @param blockId the id of block
   * @throws BlockDoesNotExistException if block id can not be found in temporary blocks
   * @throws BlockAlreadyExistsException if block id already exists in committed blocks
   * @throws InvalidWorkerStateException if block id is not owned by session id
   * @throws IOException if I/O errors occur when deleting the block file
   */
  private void abortBlockInternal(long sessionId, long blockId)
      throws BlockDoesNotExistException, BlockAlreadyExistsException, InvalidWorkerStateException,
          IOException {
    long lockId = mLockManager.lockBlock(sessionId, blockId, BlockLockType.WRITE);
    try {
      String path;
      TempBlockMeta tempBlockMeta;
      mMetadataReadLock.lock();
      try {
        checkTempBlockOwnedBySession(sessionId, blockId);
        tempBlockMeta = mMetaManager.getTempBlockMeta(blockId);
        path = tempBlockMeta.getPath();
      } finally {
        mMetadataReadLock.unlock();
      }

      // Heavy IO is guarded by block lock but not metadata lock. This may throw IOException.
      Files.delete(Paths.get(path));

      mMetadataWriteLock.lock();
      try {
        mMetaManager.abortTempBlockMeta(tempBlockMeta);
      } catch (BlockDoesNotExistException e) {
        throw Throwables.propagate(e); // We shall never reach here
      } finally {
        mMetadataWriteLock.unlock();
      }
    } finally {
      mLockManager.unlockBlock(lockId);
    }
  }
Ejemplo n.º 2
0
 /**
  * Checks if block id is a temporary block and owned by session id. This method must be enclosed
  * by {@link #mMetadataLock}.
  *
  * @param sessionId the id of session
  * @param blockId the id of block
  * @throws BlockDoesNotExistException if block id can not be found in temporary blocks
  * @throws BlockAlreadyExistsException if block id already exists in committed blocks
  * @throws InvalidWorkerStateException if block id is not owned by session id
  */
 private void checkTempBlockOwnedBySession(long sessionId, long blockId)
     throws BlockDoesNotExistException, BlockAlreadyExistsException, InvalidWorkerStateException {
   if (mMetaManager.hasBlockMeta(blockId)) {
     throw new BlockAlreadyExistsException(ExceptionMessage.TEMP_BLOCK_ID_COMMITTED, blockId);
   }
   TempBlockMeta tempBlockMeta = mMetaManager.getTempBlockMeta(blockId);
   long ownerSessionId = tempBlockMeta.getSessionId();
   if (ownerSessionId != sessionId) {
     throw new InvalidWorkerStateException(
         ExceptionMessage.BLOCK_ID_FOR_DIFFERENT_SESSION, blockId, ownerSessionId, sessionId);
   }
 }
Ejemplo n.º 3
0
 @Override
 public BlockWriter getBlockWriter(long sessionId, long blockId)
     throws BlockDoesNotExistException, IOException {
   // NOTE: a temp block is supposed to only be visible by its own writer, unnecessary to acquire
   // block lock here since no sharing
   // TODO(bin): Handle the case where multiple writers compete for the same block.
   mMetadataReadLock.lock();
   try {
     TempBlockMeta tempBlockMeta = mMetaManager.getTempBlockMeta(blockId);
     return new LocalFileBlockWriter(tempBlockMeta.getPath());
   } finally {
     mMetadataReadLock.unlock();
   }
 }
Ejemplo n.º 4
0
  /**
   * Commits a temp block.
   *
   * @param sessionId the id of session
   * @param blockId the id of block
   * @return destination location to move the block
   * @throws BlockDoesNotExistException if block id can not be found in temporary blocks
   * @throws BlockAlreadyExistsException if block id already exists in committed blocks
   * @throws InvalidWorkerStateException if block id is not owned by session id
   * @throws IOException if I/O errors occur when deleting the block file
   */
  private BlockStoreLocation commitBlockInternal(long sessionId, long blockId)
      throws BlockAlreadyExistsException, InvalidWorkerStateException, BlockDoesNotExistException,
          IOException {
    long lockId = mLockManager.lockBlock(sessionId, blockId, BlockLockType.WRITE);
    try {
      // When committing TempBlockMeta, the final BlockMeta calculates the block size according to
      // the actual file size of this TempBlockMeta. Therefore, commitTempBlockMeta must happen
      // after moving actual block file to its committed path.
      BlockStoreLocation loc;
      String srcPath;
      String dstPath;
      TempBlockMeta tempBlockMeta;
      mMetadataReadLock.lock();
      try {
        checkTempBlockOwnedBySession(sessionId, blockId);
        tempBlockMeta = mMetaManager.getTempBlockMeta(blockId);
        srcPath = tempBlockMeta.getPath();
        dstPath = tempBlockMeta.getCommitPath();
        loc = tempBlockMeta.getBlockLocation();
      } finally {
        mMetadataReadLock.unlock();
      }

      // Heavy IO is guarded by block lock but not metadata lock. This may throw IOException.
      FileUtils.move(srcPath, dstPath);

      mMetadataWriteLock.lock();
      try {
        mMetaManager.commitTempBlockMeta(tempBlockMeta);
      } catch (BlockAlreadyExistsException e) {
        throw Throwables.propagate(e); // we shall never reach here
      } catch (BlockDoesNotExistException e) {
        throw Throwables.propagate(e); // we shall never reach here
      } catch (WorkerOutOfSpaceException e) {
        throw Throwables.propagate(e); // we shall never reach here
      } finally {
        mMetadataWriteLock.unlock();
      }
      return loc;
    } finally {
      mLockManager.unlockBlock(lockId);
    }
  }
Ejemplo n.º 5
0
 /**
  * Increases the temp block size only if this temp block's parent dir has enough available space.
  *
  * @param blockId block Id
  * @param additionalBytes additional bytes to request for this block
  * @return a pair of boolean and {@link BlockStoreLocation}. The boolean indicates if the
  *     operation succeeds and the {@link BlockStoreLocation} denotes where to free more space if
  *     it fails.
  * @throws BlockDoesNotExistException if this block is not found
  */
 private Pair<Boolean, BlockStoreLocation> requestSpaceInternal(long blockId, long additionalBytes)
     throws BlockDoesNotExistException {
   // NOTE: a temp block is supposed to be visible for its own writer, unnecessary to acquire
   // block lock here since no sharing
   mMetadataWriteLock.lock();
   try {
     TempBlockMeta tempBlockMeta = mMetaManager.getTempBlockMeta(blockId);
     if (tempBlockMeta.getParentDir().getAvailableBytes() < additionalBytes) {
       return new Pair<Boolean, BlockStoreLocation>(false, tempBlockMeta.getBlockLocation());
     }
     // Increase the size of this temp block
     try {
       mMetaManager.resizeTempBlockMeta(
           tempBlockMeta, tempBlockMeta.getBlockSize() + additionalBytes);
     } catch (InvalidWorkerStateException e) {
       throw Throwables.propagate(e); // we shall never reach here
     }
     return new Pair<Boolean, BlockStoreLocation>(true, null);
   } finally {
     mMetadataWriteLock.unlock();
   }
 }