use of diskCacheV111.vehicles.PoolAcceptFileMessage in project dcache by dCache.
the class SpaceManagerService method processMessage.
private void processMessage(Message message) throws DeadlockLoserDataAccessException {
try {
boolean isSuccessful = false;
int attempts = 0;
while (!isSuccessful) {
try {
processMessageTransactionally(message);
isSuccessful = true;
} catch (DeadlockLoserDataAccessException e) {
LOGGER.debug("Transaction lost deadlock race and will be retried: {}", e.getMessage());
throw e;
} catch (TransientDataAccessException | RecoverableDataAccessException e) {
if (attempts >= 3) {
throw e;
}
LOGGER.warn("Retriable data access error: {}", e.toString());
attempts++;
}
}
} catch (SpaceAuthorizationException e) {
message.setFailedConditionally(CacheException.PERMISSION_DENIED, e);
} catch (NoPoolConfiguredSpaceException e) {
message.setFailed(NO_POOL_CONFIGURED, e.getMessage());
} catch (NoFreeSpaceException e) {
message.setFailedConditionally(CacheException.RESOURCE, e);
} catch (SpaceException e) {
message.setFailedConditionally(CacheException.INVALID_ARGS, e);
} catch (IllegalArgumentException e) {
LOGGER.error("Message processing failed: {}", e.getMessage(), e);
message.setFailedConditionally(CacheException.INVALID_ARGS, e.getMessage());
} catch (DeadlockLoserDataAccessException e) {
throw e;
} catch (DuplicateKeyException e) {
/* For PoolAcceptFileMessage, a duplicate key failure is most likely caused by
* the door resubmitting the message. We trust the door that it doesn't submit
* these to several pools.
*/
if ((message instanceof PoolAcceptFileMessage) && !message.isReply()) {
LOGGER.info("Ignoring exception due to possibly duplicated PoolAcceptFileMessage: {}", e.getMessage());
} else {
throw e;
}
} catch (DataAccessException e) {
LOGGER.error("Message processing failed: {}", e.toString());
message.setFailedConditionally(CacheException.UNEXPECTED_SYSTEM_EXCEPTION, "Internal failure during space management");
} catch (RuntimeException e) {
LOGGER.error("Message processing failed: {}", e.getMessage(), e);
message.setFailedConditionally(CacheException.UNEXPECTED_SYSTEM_EXCEPTION, "Internal failure during space management");
}
}
use of diskCacheV111.vehicles.PoolAcceptFileMessage in project dcache by dCache.
the class SpaceManagerService method selectPool.
/**
* Called upon intercepting PoolMgrSelectWritePoolMsg requests.
* <p>
* Injects the link group name into the request message. Also adds SpaceToken and LinkGroup
* flags to StorageInfo. These are accessed when space manager intercepts the subsequent
* PoolAcceptFileMessage.
*/
private void selectPool(PoolMgrSelectWritePoolMsg selectWritePool) throws DataAccessException, SpaceException {
LOGGER.trace("selectPool({})", selectWritePool);
FileAttributes fileAttributes = selectWritePool.getFileAttributes();
ProtocolInfo protocolInfo = selectWritePool.getProtocolInfo();
String defaultSpaceToken = fileAttributes.getStorageInfo().getMap().get("writeToken");
Subject subject = selectWritePool.getSubject();
if (defaultSpaceToken != null) {
LOGGER.trace("selectPool: file is not found, using default space token");
Space space;
try {
space = db.getSpace(Long.parseLong(defaultSpaceToken));
} catch (EmptyResultDataAccessException | NumberFormatException e) {
throw new IllegalArgumentException("No such space reservation: " + defaultSpaceToken);
}
LinkGroup linkGroup = db.getLinkGroup(space.getLinkGroupId());
String linkGroupName = linkGroup.getName();
if (!isWriteableInLinkgroup(protocolInfo, fileAttributes, linkGroupName)) {
// FIXME provide better information for the user
throw new NoPoolConfiguredSpaceException("Space reservation " + defaultSpaceToken + " may not be used for this write " + "request [net=" + hostnameFrom(protocolInfo) + ",protocol=" + protocolFrom(protocolInfo) + ",store=" + storageFrom(fileAttributes) + ",cache=" + nullToEmpty(fileAttributes.getCacheClass()) + ",linkgroup=" + nullToEmpty(linkGroupName) + "]");
}
selectWritePool.setLinkGroup(linkGroupName);
StorageInfo storageInfo = selectWritePool.getStorageInfo();
storageInfo.setKey("SpaceToken", Long.toString(space.getId()));
storageInfo.setKey("LinkGroupId", Long.toString(linkGroup.getId()));
if (!fileAttributes.isDefined(FileAttribute.ACCESS_LATENCY)) {
fileAttributes.setAccessLatency(space.getAccessLatency());
} else if (fileAttributes.getAccessLatency() != space.getAccessLatency()) {
throw new SpaceException("Access latency conflicts with access latency defined by default space reservation.");
}
if (!fileAttributes.isDefined(FileAttribute.RETENTION_POLICY)) {
fileAttributes.setRetentionPolicy(space.getRetentionPolicy());
} else if (fileAttributes.getRetentionPolicy() != space.getRetentionPolicy()) {
throw new SpaceException("Retention policy conflicts with retention policy defined by default space reservation.");
}
if (space.getDescription() != null) {
storageInfo.setKey("SpaceTokenDescription", space.getDescription());
}
LOGGER.trace("selectPool: found linkGroup = {}, forwarding message", linkGroupName);
} else if (allowUnreservedUploadsToLinkGroups) {
LOGGER.trace("Upload outside a reservation, identifying appropriate linkgroup");
LinkGroup linkGroup = findLinkGroupForWrite(subject, protocolInfo, fileAttributes, selectWritePool.getPreallocated());
if (linkGroup != null) {
String linkGroupName = linkGroup.getName();
selectWritePool.setLinkGroup(linkGroupName);
fileAttributes.getStorageInfo().setKey("LinkGroupId", Long.toString(linkGroup.getId()));
LOGGER.trace("selectPool: found linkGroup = {}, forwarding message", linkGroupName);
}
} else if (isWriteableOutsideLinkgroup(protocolInfo, fileAttributes)) {
LOGGER.debug("Upload proceeding outside of any linkgroup.");
} else {
throw new NoPoolConfiguredSpaceException("No write pools configured outside of a linkgroup.");
}
}
use of diskCacheV111.vehicles.PoolAcceptFileMessage in project dcache by dCache.
the class Transfer method startMoverAsync.
/**
* Creates a mover for the transfer.
*/
public ListenableFuture<Void> startMoverAsync(long timeout) {
FileAttributes fileAttributes = getFileAttributes();
Pool pool = getPool();
if (fileAttributes == null || pool == null) {
throw new IllegalStateException("Need PNFS ID, file attributes and pool before a mover can be started");
}
ProtocolInfo protocolInfo = getProtocolInfoForPool();
PoolIoFileMessage message;
if (isWrite()) {
long allocated = _allocated;
if (allocated == 0 && fileAttributes.isDefined(SIZE)) {
allocated = fileAttributes.getSize();
}
message = new PoolAcceptFileMessage(pool.getName(), protocolInfo, fileAttributes, pool.getAssumption(), _maximumSize, allocated);
} else {
message = new PoolDeliverFileMessage(pool.getName(), protocolInfo, fileAttributes, pool.getAssumption());
}
message.setBillingPath(getBillingPath());
message.setTransferPath(getTransferPath());
message.setIoQueueName(getIoQueue());
message.setInitiator(getTransaction());
message.setId(_id);
message.setSubject(_subject);
/*
* SpaceManager needs to spy mover shutdown to adjust the space reservation. for this reason we have to
* proxy mover start messages through SpaceManager. However, reads can be sent directly to pools.
*
* REVISIT: this should happen only when space manager is enabled.
*/
ListenableFuture<PoolIoFileMessage> reply = isWrite() ? _poolManager.startAsync(pool.getAddress(), message, timeout) : _poolStub.send(new CellPath(pool.getAddress()), message, timeout);
reply = catchingAsync(reply, NoRouteToCellException.class, x -> {
// invalidate pool selection to let the door to start over
clearPoolSelection();
return immediateFailedFuture(x);
});
setStatusUntil("Pool " + pool + ": Creating mover", reply);
return CellStub.transformAsync(reply, msg -> {
setMoverId(msg.getMoverId());
return immediateFuture(null);
});
}
use of diskCacheV111.vehicles.PoolAcceptFileMessage in project dcache by dCache.
the class PoolV4 method createMover.
// //////////////////////////////////////////////////////////////
//
// The io File Part
//
//
public Mover<?> createMover(CellMessage envelop, PoolIoFileMessage message) throws CacheException {
CellPath source = envelop.getSourcePath().revert();
FileAttributes attributes = message.getFileAttributes();
PnfsId pnfsId = attributes.getPnfsId();
ProtocolInfo pi = message.getProtocolInfo();
MoverFactory moverFactory = _transferServices.getMoverFactory(pi);
ReplicaDescriptor handle;
try {
if (message instanceof PoolAcceptFileMessage) {
OptionalLong maximumSize = ((PoolAcceptFileMessage) message).getMaximumSize();
List<StickyRecord> stickyRecords = _replicaStatePolicy.getStickyRecords(attributes);
ReplicaState targetState = _replicaStatePolicy.getTargetState(attributes);
handle = _repository.createEntry(attributes, ReplicaState.FROM_CLIENT, targetState, stickyRecords, moverFactory.getChannelCreateOptions(), maximumSize);
} else {
Set<? extends OpenOption> openFlags = message.isPool2Pool() ? EnumSet.of(Repository.OpenFlags.NOATIME) : EnumSet.noneOf(Repository.OpenFlags.class);
handle = _repository.openEntry(pnfsId, openFlags);
}
} catch (FileNotInCacheException e) {
throw new FileNotInCacheException("File " + pnfsId + " does not exist in " + _poolName, e);
} catch (FileInCacheException e) {
throw new FileInCacheException("File " + pnfsId + " already exists in " + _poolName, e);
}
try {
return moverFactory.createMover(handle, message, source);
} catch (Throwable t) {
handle.close();
throw t;
}
}
use of diskCacheV111.vehicles.PoolAcceptFileMessage in project dcache by dCache.
the class TransferManagerHandler method startMoverOnThePool.
public void startMoverOnThePool() {
PoolIoFileMessage poolMessage = store ? new PoolAcceptFileMessage(pool.getName(), protocol_info, fileAttributes, pool.getAssumption(), OptionalLong.empty()) : new PoolDeliverFileMessage(pool.getName(), protocol_info, fileAttributes, pool.getAssumption());
poolMessage.setBillingPath(info.getBillingPath());
poolMessage.setTransferPath(info.getTransferPath());
poolMessage.setSubject(transferRequest.getSubject());
if (manager.getIoQueueName() != null) {
poolMessage.setIoQueueName(manager.getIoQueueName());
}
poolMessage.setInitiator(info.getTransaction());
poolMessage.setId(id);
setState(WAITING_FIRST_POOL_REPLY_STATE);
manager.persist(this);
CellStub.addCallback(manager.getPoolManagerStub().startAsync(pool.getAddress(), poolMessage), this, executor);
}
Aggregations