use of com.b2international.snowowl.core.internal.locks.DatastoreLockContext in project snow-owl by b2ihealthcare.
the class RepositoryRestService method unlockGlobal.
@Operation(summary = "Unlock all repositories", description = "Releases a previously acquired global lock.")
@ApiResponses({ @ApiResponse(responseCode = "204", description = "Unlock successful"), @ApiResponse(responseCode = "400", description = "Unspecified unlock-related issue") })
@ResponseStatus(HttpStatus.NO_CONTENT)
@PostMapping("/unlock")
public void unlockGlobal() {
final DatastoreLockContext context = new DatastoreLockContext(User.SYSTEM.getUsername(), DatastoreLockContextDescriptions.CREATE_BACKUP);
final DatastoreLockTarget target = DatastoreLockTarget.ALL;
doUnlock(context, target);
}
use of com.b2international.snowowl.core.internal.locks.DatastoreLockContext in project snow-owl by b2ihealthcare.
the class DefaultOperationLockManager method buildMessage.
private String buildMessage(String message, final DatastoreLockContext requestRootContext, final Map<DatastoreLockTarget, DatastoreLockContext> targetMap) {
final FluentIterable<DatastoreLockContext> contexts = FluentIterable.from(targetMap.values());
DatastoreLockContext lockRootContext = null;
final Optional<DatastoreLockContext> currentLockRootContext = contexts.firstMatch(input -> DatastoreLockContextDescriptions.ROOT.equals(input.getParentDescription()));
if (currentLockRootContext.isPresent()) {
lockRootContext = currentLockRootContext.get();
} else {
if (contexts.first().isPresent()) {
lockRootContext = contexts.first().get();
}
}
if (lockRootContext != null) {
return String.join(" ", message, "while", requestRootContext.getDescription(), "because", lockRootContext.getUserId(), "is", lockRootContext.getDescription());
} else {
return message;
}
}
use of com.b2international.snowowl.core.internal.locks.DatastoreLockContext in project snow-owl by b2ihealthcare.
the class DefaultOperationLockManager method canContextLockTargets.
@OverridingMethodsMustInvokeSuper
protected void canContextLockTargets(final DatastoreLockContext context, final Iterable<DatastoreLockTarget> targets, final Map<DatastoreLockTarget, DatastoreLockContext> alreadyLockedTargets) throws LockedException {
if (!isDisposed()) {
for (final DatastoreLockTarget newTarget : targets) {
for (final IOperationLock existingLock : getExistingLocks()) {
if (existingLock.targetConflicts(newTarget) && !canContextLock(context, existingLock)) {
alreadyLockedTargets.put(newTarget, existingLock.getContext());
}
}
}
} else {
final DatastoreLockContext disposedContext = createLockContext(User.SYSTEM.getUsername(), DatastoreLockContextDescriptions.DISPOSE_LOCK_MANAGER, null);
for (final DatastoreLockTarget target : targets) {
alreadyLockedTargets.put(target, disposedContext);
}
throwLockedException(ACQUIRE_FAILED_MESSAGE, context, alreadyLockedTargets);
}
}
use of com.b2international.snowowl.core.internal.locks.DatastoreLockContext in project snow-owl by b2ihealthcare.
the class DefaultOperationLockManager method lock.
@Override
public void lock(final DatastoreLockContext context, final long timeoutMillis, final Iterable<DatastoreLockTarget> targets) throws LockedException {
final Map<DatastoreLockTarget, DatastoreLockContext> alreadyLockedTargets = Maps.newHashMap();
final long startTimeMillis = getCurrentTimeMillis();
try {
synchronized (syncObject) {
while (true) {
alreadyLockedTargets.clear();
canContextLockTargets(context, targets, alreadyLockedTargets);
if (alreadyLockedTargets.isEmpty()) {
for (final DatastoreLockTarget newTarget : targets) {
final IOperationLock existingLock = getOrCreateLock(context, newTarget);
fireTargetAcquired(existingLock.getTarget(), context);
}
syncObject.notifyAll();
return;
}
if (NO_TIMEOUT == timeoutMillis) {
syncObject.wait();
} else {
final long remainingTimeoutMillis = timeoutMillis - (getCurrentTimeMillis() - startTimeMillis);
if (remainingTimeoutMillis < 1L) {
throwLockedException(ACQUIRE_FAILED_MESSAGE, context, alreadyLockedTargets);
} else {
syncObject.wait(remainingTimeoutMillis);
}
}
}
}
} catch (InterruptedException e) {
throw new SnowowlRuntimeException(e);
}
}
use of com.b2international.snowowl.core.internal.locks.DatastoreLockContext in project snow-owl by b2ihealthcare.
the class RepositoryTransactionContext method commit.
@Override
public Optional<Commit> commit(String author, String commitComment, String parentLockContext) {
if (!isDirty()) {
return Optional.empty();
}
// fall back to the current lock context or ROOT if none is present
if (Strings.isNullOrEmpty(parentLockContext)) {
parentLockContext = optionalService(Locks.class).map(Locks::lockContext).orElse(DatastoreLockContextDescriptions.ROOT);
}
final DatastoreLockContext lockContext = createLockContext(service(User.class).getUsername(), parentLockContext);
final DatastoreLockTarget lockTarget = createLockTarget(info().id(), path());
IOperationLockManager locks = service(IOperationLockManager.class);
Commit commit = null;
try {
locks.lock(lockContext, 1000L, lockTarget);
final long timestamp = service(TimestampProvider.class).getTimestamp();
log().info("Persisting changes to {}@{}", path(), timestamp);
commit = staging.commit(null, timestamp, author, commitComment);
log().info("Changes have been successfully persisted to {}@{}.", path(), timestamp);
return Optional.ofNullable(commit);
} catch (final IndexException e) {
Throwable rootCause = Throwables.getRootCause(e);
if (rootCause instanceof CycleDetectedException) {
throw (CycleDetectedException) rootCause;
}
throw new SnowowlRuntimeException(e.getMessage(), e);
} finally {
locks.unlock(lockContext, lockTarget);
if (commit != null && isNotificationEnabled()) {
service(RepositoryCommitNotificationSender.class).publish(this, commit);
}
clear();
}
}
Aggregations