Search in sources :

Example 11 with DatastoreLockContext

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);
}
Also used : DatastoreLockTarget(com.b2international.snowowl.core.internal.locks.DatastoreLockTarget) DatastoreLockContext(com.b2international.snowowl.core.internal.locks.DatastoreLockContext) Operation(io.swagger.v3.oas.annotations.Operation) ApiResponses(io.swagger.v3.oas.annotations.responses.ApiResponses)

Example 12 with DatastoreLockContext

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;
    }
}
Also used : DatastoreLockContext(com.b2international.snowowl.core.internal.locks.DatastoreLockContext)

Example 13 with DatastoreLockContext

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);
    }
}
Also used : DatastoreLockTarget(com.b2international.snowowl.core.internal.locks.DatastoreLockTarget) DatastoreLockContext(com.b2international.snowowl.core.internal.locks.DatastoreLockContext) OverridingMethodsMustInvokeSuper(javax.annotation.OverridingMethodsMustInvokeSuper)

Example 14 with DatastoreLockContext

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);
    }
}
Also used : DatastoreLockTarget(com.b2international.snowowl.core.internal.locks.DatastoreLockTarget) DatastoreLockContext(com.b2international.snowowl.core.internal.locks.DatastoreLockContext) SnowowlRuntimeException(com.b2international.snowowl.core.api.SnowowlRuntimeException)

Example 15 with DatastoreLockContext

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();
    }
}
Also used : IndexException(com.b2international.index.IndexException) CycleDetectedException(com.b2international.commons.exceptions.CycleDetectedException) Locks(com.b2international.snowowl.core.locks.Locks) IOperationLockManager(com.b2international.snowowl.core.locks.IOperationLockManager) DatastoreLockTarget(com.b2international.snowowl.core.internal.locks.DatastoreLockTarget) DatastoreLockContext(com.b2international.snowowl.core.internal.locks.DatastoreLockContext) SnowowlRuntimeException(com.b2international.snowowl.core.api.SnowowlRuntimeException)

Aggregations

DatastoreLockContext (com.b2international.snowowl.core.internal.locks.DatastoreLockContext)15 DatastoreLockTarget (com.b2international.snowowl.core.internal.locks.DatastoreLockTarget)14 Test (org.junit.Test)5 Operation (io.swagger.v3.oas.annotations.Operation)4 ApiResponses (io.swagger.v3.oas.annotations.responses.ApiResponses)4 SnowowlRuntimeException (com.b2international.snowowl.core.api.SnowowlRuntimeException)2 IOperationLockManager (com.b2international.snowowl.core.locks.IOperationLockManager)2 CycleDetectedException (com.b2international.commons.exceptions.CycleDetectedException)1 IndexException (com.b2international.index.IndexException)1 Locks (com.b2international.snowowl.core.locks.Locks)1 OverridingMethodsMustInvokeSuper (javax.annotation.OverridingMethodsMustInvokeSuper)1