/** * Gets all locks for ids and then after having acquired them executes the action. */ private void acquireLocksAndExecute(final Iterable<Long> ids, final WorkflowAction lockType, final Runnable action) { if (Iterables.isEmpty(ids)) { action.run(); } else { final Set<Long> sortedIds = Sets.newTreeSet(ids); ManagedLocks.manage(getLock(Iterables.getFirst(sortedIds, null), lockType)).withLock(new Runnable() { @Override public void run() { acquireLocksAndExecute(Iterables.skip(sortedIds, 1), lockType, action); } }); } }
@Override public void deleteScheme(final Long id) { if (id == null) { return; } ManagedLocks.manage(getLock(id, DELETE_SCHEME)).withLock(new Runnable() { @Override public void run() { final AssignableWorkflowScheme scheme = getWorkflowSchemeObj(id); doDeleteScheme(scheme); } }); }
@Override public <T> T waitForUpdatesToFinishAndExecute(AssignableWorkflowScheme scheme, Callable<T> task) throws Exception { if (scheme == null || scheme.getId() == null) { return task.call(); } final Collection<Lock> locks = Lists.newArrayList(); try { for (final WorkflowAction action : WorkflowAction.values()) { final ClusterLock lock = getLock(scheme.getId(), action); lock.lock(); locks.add(lock); } return task.call(); } finally { unlockAll(locks); } }
@Override public void updateScheme(final Scheme scheme) throws DataAccessException { ManagedLocks.manage(getLock(scheme.getId(), UPDATE_SCHEME)).withLock(new Runnable() { @Override public void run() { final AssignableWorkflowScheme schemeObj = toWorkflowScheme(getScheme(scheme.getId())); checkMigration(schemeObj); doUpdateScheme(scheme); } }); }
@Override public AssignableWorkflowScheme updateWorkflowScheme(@Nonnull final AssignableWorkflowScheme workflowScheme) { notNull("scheme", workflowScheme); notNull("scheme.id", workflowScheme.getId()); final Lock lock = getLock(workflowScheme.getId(), UPDATE_WORKFLOW_SCHEME); return ManagedLocks.manage(lock).withLock(new com.atlassian.util.concurrent.Supplier<AssignableWorkflowScheme>() { @Override public AssignableWorkflowScheme get() { checkMigration(workflowScheme); Scheme scheme = getSchemeObject(workflowScheme.getId()); // Delete all existing entitites. Collection<SchemeEntity> entities = scheme.getEntities(); for (SchemeEntity entity : entities) { deleteEntity(entity.getId()); } scheme = new Scheme(workflowScheme.getId(), getSchemeEntityName(), workflowScheme.getName(), workflowScheme.getDescription(), Collections.<SchemeEntity>emptyList()); doUpdateScheme(scheme); createSchemeEntities(workflowScheme); return getWorkflowSchemeObj(workflowScheme.getId()); } }); }
@Override public DraftWorkflowScheme updateDraftWorkflowScheme(final ApplicationUser user, @Nonnull final DraftWorkflowScheme scheme) { notNull("scheme", scheme); notNull("scheme.id", scheme.getId()); // We lock the parent scheme in case of drafts final Lock lock = getLock(scheme.getParentScheme().getId(), UPDATE_DRAFT_WORKFLOW_SCHEME); return ManagedLocks.manage(lock).withLock(new com.atlassian.util.concurrent.Supplier<DraftWorkflowScheme>() { @Override public DraftWorkflowScheme get() { WorkflowSchemeMigrationTaskAccessor taskAccessor = getTaskAccessor(); if (taskAccessor.getActiveByProjects(scheme, true) != null) { throw new SchemeIsBeingMigratedException(); } DraftWorkflowSchemeStore.DraftState savedState = draftWorkflowSchemeStore.get(scheme.getId()); notNull(format("scheme with id %d does not exist.", scheme.getId()), savedState); DraftWorkflowSchemeStore.DraftState.Builder builder = savedState.builder(); builder.setMappings(scheme.getMappings()); builder.setLastModifiedUser(user == null ? null : user.getKey()); return toWorkflowScheme(draftWorkflowSchemeStore.update(builder.build())); } }); }
final Lock lock = getLock(lockSchemeId, DELETE_WORKFLOW_SCHEME); return ManagedLocks.manage(lock).withLock(new com.atlassian.util.concurrent.Supplier<Boolean>()