use of alluxio.exception.BlockAlreadyExistsException in project alluxio by Alluxio.
the class UnderFileSystemBlockReader method updateBlockWriter.
/**
* Updates the block writer given an offset to read. If the offset is beyond the current
* position of the block writer, the block writer will be aborted.
*
* @param offset the read offset
*/
private void updateBlockWriter(long offset) throws IOException {
try {
if (mBlockWriter != null && offset > mBlockWriter.getPosition()) {
mBlockWriter.close();
mBlockWriter = null;
mLocalBlockStore.abortBlock(mBlockMeta.getSessionId(), mBlockMeta.getBlockId());
}
} catch (BlockDoesNotExistException e) {
// This can only happen when the session is expired.
LOG.warn("Block {} does not exist when being aborted.", mBlockMeta.getBlockId());
} catch (BlockAlreadyExistsException | InvalidWorkerStateException | IOException e) {
// reader does not commit the block if it fails to abort the block.
throw CommonUtils.castToIOException(e);
}
try {
if (mBlockWriter == null && offset == 0 && !mNoCache) {
BlockStoreLocation loc = BlockStoreLocation.anyDirInTier(mStorageTierAssoc.getAlias(0));
String blockPath = mLocalBlockStore.createBlock(mBlockMeta.getSessionId(), mBlockMeta.getBlockId(), loc, mInitialBlockSize).getPath();
mBlockWriter = new LocalFileBlockWriter(blockPath);
}
} catch (IOException | BlockAlreadyExistsException | WorkerOutOfSpaceException e) {
// This can happen when there are concurrent UFS readers who are all trying to cache to block.
LOG.debug("Failed to update block writer for UFS block [blockId: {}, ufsPath: {}, offset: {}]", mBlockMeta.getBlockId(), mBlockMeta.getUnderFileSystemPath(), offset, e);
mBlockWriter = null;
}
}
use of alluxio.exception.BlockAlreadyExistsException in project alluxio by Alluxio.
the class UnderFileSystemBlockStore method acquireAccess.
/**
* Acquires access for a UFS block given a {@link UnderFileSystemBlockMeta} and the limit on
* the maximum concurrency on the block. If the number of concurrent readers on this UFS block
* exceeds a threshold, the token is not granted and this method returns false.
*
* @param sessionId the session ID
* @param blockId maximum concurrency
* @param options the options
* @return whether an access token is acquired
* @throws BlockAlreadyExistsException if the block already exists for a session ID
*/
public boolean acquireAccess(long sessionId, long blockId, OpenUfsBlockOptions options) throws BlockAlreadyExistsException {
UnderFileSystemBlockMeta blockMeta = new UnderFileSystemBlockMeta(sessionId, blockId, options);
mLock.lock();
try {
Key key = new Key(sessionId, blockId);
if (mBlocks.containsKey(key)) {
throw new BlockAlreadyExistsException(ExceptionMessage.UFS_BLOCK_ALREADY_EXISTS_FOR_SESSION, blockId, blockMeta.getUnderFileSystemPath(), sessionId);
}
Set<Long> sessionIds = mBlockIdToSessionIds.get(blockId);
if (sessionIds != null && sessionIds.size() >= options.getMaxUfsReadConcurrency()) {
return false;
}
if (sessionIds == null) {
sessionIds = new HashSet<>();
mBlockIdToSessionIds.put(blockId, sessionIds);
}
sessionIds.add(sessionId);
mBlocks.put(key, new BlockInfo(blockMeta));
Set<Long> blockIds = mSessionIdToBlockIds.get(sessionId);
if (blockIds == null) {
blockIds = new HashSet<>();
mSessionIdToBlockIds.put(sessionId, blockIds);
}
blockIds.add(blockId);
} finally {
mLock.unlock();
}
return true;
}
use of alluxio.exception.BlockAlreadyExistsException in project alluxio by Alluxio.
the class DefaultBlockWorker method commitBlock.
@Override
public void commitBlock(long sessionId, long blockId) throws BlockAlreadyExistsException, BlockDoesNotExistException, InvalidWorkerStateException, IOException, WorkerOutOfSpaceException {
// TODO(binfan): find a better way to handle retry logic
try {
mBlockStore.commitBlock(sessionId, blockId);
} catch (BlockAlreadyExistsException e) {
LOG.debug("Block {} has been in block store, this could be a retry due to master-side RPC " + "failure, therefore ignore the exception", blockId, e);
}
// TODO(calvin): Reconsider how to do this without heavy locking.
// Block successfully committed, update master with new block metadata
Long lockId = mBlockStore.lockBlock(sessionId, blockId);
try {
BlockMeta meta = mBlockStore.getBlockMeta(sessionId, blockId, lockId);
BlockStoreLocation loc = meta.getBlockLocation();
Long length = meta.getBlockSize();
BlockStoreMeta storeMeta = mBlockStore.getBlockStoreMeta();
Long bytesUsedOnTier = storeMeta.getUsedBytesOnTiers().get(loc.tierAlias());
mBlockMasterClient.commitBlock(mWorkerId.get(), bytesUsedOnTier, loc.tierAlias(), blockId, length);
} catch (AlluxioTException | IOException | ConnectionFailedException e) {
throw new IOException(ExceptionMessage.FAILED_COMMIT_BLOCK_TO_MASTER.getMessage(blockId), e);
} finally {
mBlockStore.unlockBlock(lockId);
}
}
use of alluxio.exception.BlockAlreadyExistsException in project alluxio by Alluxio.
the class TieredBlockStore method createBlockMetaInternal.
/**
* Creates a temp block meta only if allocator finds available space. This method will not trigger
* any eviction.
*
* @param sessionId session Id
* @param blockId block Id
* @param location location to create the block
* @param initialBlockSize initial block size in bytes
* @param newBlock true if this temp block is created for a new block
* @return a temp block created if successful, or null if allocation failed (instead of throwing
* {@link WorkerOutOfSpaceException} because allocation failure could be an expected case)
* @throws BlockAlreadyExistsException if there is already a block with the same block id
*/
private TempBlockMeta createBlockMetaInternal(long sessionId, long blockId, BlockStoreLocation location, long initialBlockSize, boolean newBlock) throws BlockAlreadyExistsException {
// block lock here since no sharing
try (LockResource r = new LockResource(mMetadataWriteLock)) {
if (newBlock) {
checkTempBlockIdAvailable(blockId);
}
StorageDirView dirView = mAllocator.allocateBlockWithView(sessionId, initialBlockSize, location, getUpdatedView());
if (dirView == null) {
// Allocator fails to find a proper place for this new block.
return null;
}
// TODO(carson): Add tempBlock to corresponding storageDir and remove the use of
// StorageDirView.createTempBlockMeta.
TempBlockMeta tempBlock = dirView.createTempBlockMeta(sessionId, blockId, initialBlockSize);
try {
// Add allocated temp block to metadata manager. This should never fail if allocator
// correctly assigns a StorageDir.
mMetaManager.addTempBlockMeta(tempBlock);
} catch (WorkerOutOfSpaceException | BlockAlreadyExistsException e) {
// If we reach here, allocator is not working properly
LOG.error("Unexpected failure: {} bytes allocated at {} by allocator, " + "but addTempBlockMeta failed", initialBlockSize, location);
throw Throwables.propagate(e);
}
return tempBlock;
}
}
use of alluxio.exception.BlockAlreadyExistsException in project alluxio by Alluxio.
the class TieredBlockStore method commitBlockInternal.
/**
* Commits a temp block.
*
* @param sessionId the id of session
* @param blockId the id of block
* @param pinOnCreate is block pinned on create
* @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
*/
private BlockStoreLocation commitBlockInternal(long sessionId, long blockId, boolean pinOnCreate) throws BlockAlreadyExistsException, InvalidWorkerStateException, BlockDoesNotExistException, IOException {
// 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;
try (LockResource r = new LockResource(mMetadataReadLock)) {
checkTempBlockOwnedBySession(sessionId, blockId);
tempBlockMeta = mMetaManager.getTempBlockMeta(blockId);
srcPath = tempBlockMeta.getPath();
dstPath = tempBlockMeta.getCommitPath();
loc = tempBlockMeta.getBlockLocation();
}
// Heavy IO is guarded by block lock but not metadata lock. This may throw IOException.
FileUtils.move(srcPath, dstPath);
try (LockResource r = new LockResource(mMetadataWriteLock)) {
mMetaManager.commitTempBlockMeta(tempBlockMeta);
} catch (BlockAlreadyExistsException | BlockDoesNotExistException | WorkerOutOfSpaceException e) {
// we shall never reach here
throw Throwables.propagate(e);
}
// Check if block is pinned on commit
if (pinOnCreate) {
addToPinnedInodes(BlockId.getFileId(blockId));
}
return loc;
}
Aggregations