use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal in project ignite by apache.
the class DataStructuresProcessor method removeDataStructure.
/**
* @param c Closure.
* @param name Data structure name.
* @param type Data structure type.
* @param afterRmv Optional closure to run after data structure removed.
* @throws IgniteCheckedException If failed.
*/
private <T> void removeDataStructure(final IgniteOutClosureX<T> c, String name, DataStructureType type, @Nullable final IgniteInClosureX<T> afterRmv) throws IgniteCheckedException {
Map<String, DataStructureInfo> dsMap = utilityCache.get(DATA_STRUCTURES_KEY);
if (dsMap == null || !dsMap.containsKey(name))
return;
final DataStructureInfo dsInfo = new DataStructureInfo(name, type, null);
IgniteCheckedException err = validateDataStructure(dsMap, dsInfo, false);
if (err != null)
throw err;
retryTopologySafe(new IgniteOutClosureX<Void>() {
@Override
public Void applyx() throws IgniteCheckedException {
try (GridNearTxLocal tx = utilityCache.txStartEx(PESSIMISTIC, REPEATABLE_READ)) {
T2<Boolean, IgniteCheckedException> res = utilityCache.invoke(DATA_STRUCTURES_KEY, new RemoveDataStructureProcessor(dsInfo)).get();
IgniteCheckedException err = res.get2();
if (err != null)
throw err;
assert res.get1() != null;
boolean exists = res.get1();
if (!exists)
return null;
T rmvInfo = c.applyx();
tx.commit();
if (afterRmv != null && rmvInfo != null)
afterRmv.applyx(rmvInfo);
return null;
}
}
});
}
use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal in project ignite by apache.
the class DataStructuresProcessor method removeCountDownLatch.
/**
* Removes count down latch from cache.
*
* @param name Name of the latch.
* @throws IgniteCheckedException If operation failed.
*/
public void removeCountDownLatch(final String name) throws IgniteCheckedException {
assert name != null;
assert dsCacheCtx != null;
awaitInitialization();
removeDataStructure(new IgniteOutClosureX<Void>() {
@Override
public Void applyx() throws IgniteCheckedException {
GridCacheInternal key = new GridCacheInternalKeyImpl(name);
dsCacheCtx.gate().enter();
try (GridNearTxLocal tx = CU.txStartInternal(dsCacheCtx, dsView, PESSIMISTIC, REPEATABLE_READ)) {
// Check correctness type of removable object.
GridCacheCountDownLatchValue val = cast(dsView.get(key), GridCacheCountDownLatchValue.class);
if (val != null) {
if (val.get() > 0) {
throw new IgniteCheckedException("Failed to remove count down latch " + "with non-zero count: " + val.get());
}
dsView.remove(key);
tx.commit();
} else
tx.setRollbackOnly();
return null;
} finally {
dsCacheCtx.gate().leave();
}
}
}, name, COUNT_DOWN_LATCH, null);
}
use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal in project ignite by apache.
the class GridCacheSemaphoreImpl method initializeSemaphore.
/**
* @throws IgniteCheckedException If operation failed.
*/
private void initializeSemaphore() throws IgniteCheckedException {
if (!initGuard.get() && initGuard.compareAndSet(false, true)) {
try {
sync = retryTopologySafe(new Callable<Sync>() {
@Override
public Sync call() throws Exception {
try (GridNearTxLocal tx = CU.txStartInternal(ctx, semView, PESSIMISTIC, REPEATABLE_READ)) {
GridCacheSemaphoreState val = semView.get(key);
if (val == null) {
if (log.isDebugEnabled())
log.debug("Failed to find semaphore with given name: " + name);
return null;
}
final int cnt = val.getCount();
Map<UUID, Integer> waiters = val.getWaiters();
final boolean failoverSafe = val.isFailoverSafe();
tx.commit();
Sync sync = new Sync(cnt, waiters, failoverSafe);
sync.setBroken(val.isBroken());
return sync;
}
}
});
if (log.isDebugEnabled())
log.debug("Initialized internal sync structure: " + sync);
} finally {
initLatch.countDown();
}
} else {
U.await(initLatch);
if (sync == null)
throw new IgniteCheckedException("Internal semaphore has not been properly initialized.");
}
}
use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal in project ignite by apache.
the class IgfsMetaManager method updateInfo.
/**
* Update file info in cache.
*
* @param fileId File ID to update information for.
* @param proc Entry processor to invoke.
* @return Updated file info or {@code null} if such file ID not found.
* @throws IgniteCheckedException If failed.
*/
@Nullable
public IgfsEntryInfo updateInfo(IgniteUuid fileId, EntryProcessor<IgniteUuid, IgfsEntryInfo, IgfsEntryInfo> proc) throws IgniteCheckedException {
validTxState(false);
assert fileId != null;
assert proc != null;
if (busyLock.enterBusy()) {
try {
if (log.isDebugEnabled())
log.debug("Update file info [fileId=" + fileId + ", proc=" + proc + ']');
try (GridNearTxLocal tx = startTx()) {
// Lock file ID for this transaction.
IgfsEntryInfo oldInfo = info(fileId);
if (oldInfo == null)
// File not found.
return null;
IgfsEntryInfo newInfo = invokeAndGet(fileId, proc);
if (newInfo == null)
throw fsException("Failed to update file info with null value" + " [oldInfo=" + oldInfo + ", newInfo=null, proc=" + proc + ']');
if (!oldInfo.id().equals(newInfo.id()))
throw fsException("Failed to update file info (file IDs differ)" + " [oldInfo=" + oldInfo + ", newInfo=" + newInfo + ", proc=" + proc + ']');
if (oldInfo.isDirectory() != newInfo.isDirectory())
throw fsException("Failed to update file info (file types differ)" + " [oldInfo=" + oldInfo + ", newInfo=" + newInfo + ", proc=" + proc + ']');
tx.commit();
return newInfo;
} catch (GridClosureException e) {
throw U.cast(e);
}
} finally {
busyLock.leaveBusy();
}
} else
throw new IllegalStateException("Failed to update file system entry info because Grid is stopping: " + fileId);
}
use of org.apache.ignite.internal.processors.cache.distributed.near.GridNearTxLocal in project ignite by apache.
the class IgfsMetaManager method softDelete.
/**
* Move path to the trash directory.
*
* @param path Path.
* @param recursive Recursive flag.
* @param secondaryFs Secondary file system (optional).
* @return ID of an entry located directly under the trash directory.
* @throws IgniteCheckedException If failed.
*/
IgfsDeleteResult softDelete(final IgfsPath path, final boolean recursive, @Nullable IgfsSecondaryFileSystem secondaryFs) throws IgniteCheckedException {
while (true) {
if (busyLock.enterBusy()) {
try {
validTxState(false);
IgfsPathIds pathIds = pathIds(path);
if (!pathIds.allExists() && secondaryFs == null)
return new IgfsDeleteResult(false, null);
IgniteUuid victimId = pathIds.lastId();
String victimName = pathIds.lastPart();
if (IgfsUtils.isRootId(victimId))
throw new IgfsException("Cannot remove root directory");
// Prepare IDs to lock.
SortedSet<IgniteUuid> allIds = new TreeSet<>(PATH_ID_SORTING_COMPARATOR);
pathIds.addExistingIds(allIds, relaxed);
IgniteUuid trashId = IgfsUtils.randomTrashId();
allIds.add(trashId);
try (GridNearTxLocal tx = startTx()) {
// Lock participants.
Map<IgniteUuid, IgfsEntryInfo> lockInfos = lockIds(allIds);
if (secondaryFs != null && isRetryForSecondary(pathIds, lockInfos))
continue;
// Ensure that all participants are still in place.
if (!pathIds.allExists() || !pathIds.verifyIntegrity(lockInfos, relaxed)) {
// For DUAL mode we will try to update the underlying FS still. Note we do that inside TX.
if (secondaryFs != null) {
boolean res = secondaryFs.delete(path, recursive);
return new IgfsDeleteResult(res, null);
} else
return new IgfsDeleteResult(false, null);
}
IgfsEntryInfo victimInfo = lockInfos.get(victimId);
// Cannot delete non-empty directory if recursive flag is not set.
if (!recursive && victimInfo.hasChildren())
throw new IgfsDirectoryNotEmptyException("Failed to remove directory (directory is not " + "empty and recursive flag is not set).");
// Prepare trash data.
IgfsEntryInfo trashInfo = lockInfos.get(trashId);
final String trashName = IgfsUtils.composeNameForTrash(path, victimId);
assert !trashInfo.hasChild(trashName) : "Failed to add file name into the " + "destination directory (file already exists) [destName=" + trashName + ']';
IgniteUuid parentId = pathIds.lastParentId();
IgfsEntryInfo parentInfo = lockInfos.get(parentId);
// Propagate call to the secondary file system.
if (secondaryFs != null && !secondaryFs.delete(path, recursive))
return new IgfsDeleteResult(false, null);
transferEntry(parentInfo.listing().get(victimName), parentId, victimName, trashId, trashName);
tx.commit();
signalDeleteWorker();
return new IgfsDeleteResult(true, victimInfo);
}
} finally {
busyLock.leaveBusy();
}
} else
throw new IllegalStateException("Failed to perform soft delete because Grid is " + "stopping [path=" + path + ']');
}
}
Aggregations