Search in sources :

Example 6 with Unlocker

use of org.eclipse.che.commons.lang.concurrent.Unlocker in project che by eclipse.

the class CheEnvironmentEngine method start.

/**
     * Starts provided environment.
     *
     * <p>Environment starts if and only all machines in environment definition start successfully.<br/>
     * Otherwise exception is thrown by this method.<br/>
     * It is not defined whether environment start fails right after first failure or in the end of the process.<br/>
     * Starting order of machines is not guarantied. Machines can start sequentially or in parallel.
     *
     * @param workspaceId
     *         ID of workspace that owns provided environment
     * @param envName
     *         name of environment
     * @param env
     *         environment to start
     * @param recover
     *         whether machines from environment should be recovered or not
     * @param messageConsumer
     *         consumer of log messages from machines in the environment
     * @param startedHandler
     *         handler for started machines
     * @return list of running machines of this environment
     * @throws ServerException
     *         if other error occurs
     */
public List<Instance> start(String workspaceId, String envName, Environment env, boolean recover, MessageConsumer<MachineLogMessage> messageConsumer, MachineStartedHandler startedHandler) throws ServerException, EnvironmentException, ConflictException {
    EnvironmentImpl environment = new EnvironmentImpl(env);
    // TODO move to machines provider
    // add random chars to ensure that old environments that weren't removed by some reason won't prevent start
    String networkId = NameGenerator.generate(workspaceId + "_", 16);
    String namespace = EnvironmentContext.getCurrent().getSubject().getUserName();
    initializeEnvironment(namespace, workspaceId, envName, environment, networkId, messageConsumer);
    String devMachineName = getDevMachineName(environment);
    if (devMachineName == null) {
        throw new ServerException("Agent 'org.eclipse.che.ws-agent' is not found in any of environment machines");
    }
    startEnvironmentQueue(namespace, workspaceId, devMachineName, networkId, recover, startedHandler);
    try (@SuppressWarnings("unused") Unlocker u = stripedLocks.writeLock(workspaceId)) {
        EnvironmentHolder environmentHolder = environments.get(workspaceId);
        // possible only if environment was stopped during its start
        if (environmentHolder == null) {
            throw new ServerException("Environment start was interrupted by environment stopping");
        }
        environmentHolder.status = EnvStatus.RUNNING;
        // prevent list modification
        return new ArrayList<>(environmentHolder.machines);
    }
}
Also used : ServerException(org.eclipse.che.api.core.ServerException) Unlocker(org.eclipse.che.commons.lang.concurrent.Unlocker) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) EnvironmentImpl(org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl) CheServicesEnvironmentImpl(org.eclipse.che.api.environment.server.model.CheServicesEnvironmentImpl)

Example 7 with Unlocker

use of org.eclipse.che.commons.lang.concurrent.Unlocker in project che by eclipse.

the class WorkspaceRuntimes method shutdown.

/**
     * Terminates workspace runtimes service, so no more workspaces are allowed to start
     * or to be stopped directly, all the running workspaces are going to be stopped,
     * all the starting tasks will be eventually interrupted.
     *
     * @throws IllegalStateException
     *         if component shutdown is already called
     */
public void shutdown() throws InterruptedException {
    if (!isShutdown.compareAndSet(false, true)) {
        throw new IllegalStateException("Workspace runtimes service shutdown has been already called");
    }
    List<String> idsToStop;
    try (@SuppressWarnings("unused") Unlocker u = locks.writeAllLock()) {
        idsToStop = states.entrySet().stream().filter(e -> e.getValue().status != WorkspaceStatus.STOPPING).map(Map.Entry::getKey).collect(Collectors.toList());
        states.clear();
    }
    if (!idsToStop.isEmpty()) {
        LOG.info("Shutdown running environments, environments to stop: '{}'", idsToStop.size());
        ExecutorService executor = Executors.newFixedThreadPool(2 * Runtime.getRuntime().availableProcessors(), new ThreadFactoryBuilder().setNameFormat("StopEnvironmentsPool-%d").setDaemon(false).build());
        for (String id : idsToStop) {
            executor.execute(() -> {
                try {
                    envEngine.stop(id);
                } catch (EnvironmentNotRunningException ignored) {
                // might be already stopped
                } catch (Exception x) {
                    LOG.error(x.getMessage(), x);
                }
            });
        }
        executor.shutdown();
        try {
            if (!executor.awaitTermination(30, TimeUnit.SECONDS)) {
                executor.shutdownNow();
                if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                    LOG.error("Unable to stop runtimes termination pool");
                }
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
}
Also used : ENVIRONMENT_OUTPUT_CHANNEL_TEMPLATE(org.eclipse.che.api.machine.shared.Constants.ENVIRONMENT_OUTPUT_CHANNEL_TEMPLATE) AgentLauncher(org.eclipse.che.api.agent.server.launcher.AgentLauncher) Agent(org.eclipse.che.api.agent.shared.model.Agent) EnvironmentImpl(org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl) StripedLocks(org.eclipse.che.commons.lang.concurrent.StripedLocks) AgentException(org.eclipse.che.api.agent.server.exception.AgentException) RUNNING(org.eclipse.che.api.core.model.workspace.WorkspaceStatus.RUNNING) Unlocker(org.eclipse.che.commons.lang.concurrent.Unlocker) Future(java.util.concurrent.Future) WorkspaceStatusEvent(org.eclipse.che.api.workspace.shared.dto.event.WorkspaceStatusEvent) EnvironmentStartInterruptedException(org.eclipse.che.api.environment.server.exception.EnvironmentStartInterruptedException) Map(java.util.Map) EnvironmentNotRunningException(org.eclipse.che.api.environment.server.exception.EnvironmentNotRunningException) EventService(org.eclipse.che.api.core.notification.EventService) CancellationException(java.util.concurrent.CancellationException) MachineConfig(org.eclipse.che.api.core.model.machine.MachineConfig) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) Collectors(java.util.stream.Collectors) Nullable(org.eclipse.che.commons.annotation.Nullable) Executors(java.util.concurrent.Executors) String.format(java.lang.String.format) CountDownLatch(java.util.concurrent.CountDownLatch) STARTING(org.eclipse.che.api.core.model.workspace.WorkspaceStatus.STARTING) EnvironmentException(org.eclipse.che.api.environment.server.exception.EnvironmentException) List(java.util.List) Environment(org.eclipse.che.api.core.model.workspace.Environment) CheEnvironmentEngine(org.eclipse.che.api.environment.server.CheEnvironmentEngine) AgentKey(org.eclipse.che.api.agent.shared.model.AgentKey) EventType(org.eclipse.che.api.workspace.shared.dto.event.WorkspaceStatusEvent.EventType) AgentLauncherFactory(org.eclipse.che.api.agent.server.launcher.AgentLauncherFactory) WorkspaceImpl(org.eclipse.che.api.workspace.server.model.impl.WorkspaceImpl) AgentRegistry(org.eclipse.che.api.agent.server.AgentRegistry) ThreadFactoryBuilder(com.google.common.util.concurrent.ThreadFactoryBuilder) Workspace(org.eclipse.che.api.core.model.workspace.Workspace) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Callable(java.util.concurrent.Callable) CompletableFuture(java.util.concurrent.CompletableFuture) Singleton(javax.inject.Singleton) SnapshotImpl(org.eclipse.che.api.machine.server.model.impl.SnapshotImpl) ArrayList(java.util.ArrayList) ConcurrentMap(java.util.concurrent.ConcurrentMap) Inject(javax.inject.Inject) HashSet(java.util.HashSet) WebsocketMessageConsumer(org.eclipse.che.api.core.util.WebsocketMessageConsumer) WorkspaceRuntimeImpl(org.eclipse.che.api.workspace.server.model.impl.WorkspaceRuntimeImpl) Objects.requireNonNull(java.util.Objects.requireNonNull) ConflictException(org.eclipse.che.api.core.ConflictException) Comparator.comparing(java.util.Comparator.comparing) Instance(org.eclipse.che.api.machine.server.spi.Instance) SnapshotDao(org.eclipse.che.api.machine.server.spi.SnapshotDao) DtoFactory(org.eclipse.che.dto.server.DtoFactory) ExecutorService(java.util.concurrent.ExecutorService) MachineException(org.eclipse.che.api.machine.server.exception.MachineException) Logger(org.slf4j.Logger) ExtendedMachine(org.eclipse.che.api.core.model.workspace.ExtendedMachine) SNAPSHOTTING(org.eclipse.che.api.core.model.workspace.WorkspaceStatus.SNAPSHOTTING) WorkspaceStatus(org.eclipse.che.api.core.model.workspace.WorkspaceStatus) NotFoundException(org.eclipse.che.api.core.NotFoundException) TimeUnit(java.util.concurrent.TimeUnit) SnapshotException(org.eclipse.che.api.machine.server.exception.SnapshotException) MachineImpl(org.eclipse.che.api.machine.server.model.impl.MachineImpl) AgentSorter(org.eclipse.che.api.agent.server.impl.AgentSorter) ServerException(org.eclipse.che.api.core.ServerException) MachineConfigImpl(org.eclipse.che.api.machine.server.model.impl.MachineConfigImpl) LoggerFactory.getLogger(org.slf4j.LoggerFactory.getLogger) VisibleForTesting(com.google.common.annotations.VisibleForTesting) MachineStartedHandler(org.eclipse.che.api.environment.server.MachineStartedHandler) Collections(java.util.Collections) Unlocker(org.eclipse.che.commons.lang.concurrent.Unlocker) ExecutorService(java.util.concurrent.ExecutorService) EnvironmentNotRunningException(org.eclipse.che.api.environment.server.exception.EnvironmentNotRunningException) ThreadFactoryBuilder(com.google.common.util.concurrent.ThreadFactoryBuilder) EnvironmentStartInterruptedException(org.eclipse.che.api.environment.server.exception.EnvironmentStartInterruptedException) AgentException(org.eclipse.che.api.agent.server.exception.AgentException) EnvironmentStartInterruptedException(org.eclipse.che.api.environment.server.exception.EnvironmentStartInterruptedException) EnvironmentNotRunningException(org.eclipse.che.api.environment.server.exception.EnvironmentNotRunningException) CancellationException(java.util.concurrent.CancellationException) EnvironmentException(org.eclipse.che.api.environment.server.exception.EnvironmentException) ConflictException(org.eclipse.che.api.core.ConflictException) MachineException(org.eclipse.che.api.machine.server.exception.MachineException) NotFoundException(org.eclipse.che.api.core.NotFoundException) SnapshotException(org.eclipse.che.api.machine.server.exception.SnapshotException) ServerException(org.eclipse.che.api.core.ServerException)

Example 8 with Unlocker

use of org.eclipse.che.commons.lang.concurrent.Unlocker in project che by eclipse.

the class WorkspaceRuntimes method injectRuntime.

/**
     * Injects runtime information such as status and {@link WorkspaceRuntimeImpl}
     * into the workspace object, if the workspace doesn't have runtime sets the
     * status to {@link WorkspaceStatus#STOPPED}.
     *
     * @param workspace
     *         the workspace to inject runtime into
     */
public void injectRuntime(WorkspaceImpl workspace) {
    requireNonNull(workspace, "Required non-null workspace");
    RuntimeState state = null;
    try (@SuppressWarnings("unused") Unlocker u = locks.readLock(workspace.getId())) {
        if (states.containsKey(workspace.getId())) {
            state = new RuntimeState(states.get(workspace.getId()));
        }
    }
    if (state == null) {
        workspace.setStatus(WorkspaceStatus.STOPPED);
    } else {
        workspace.setStatus(state.status);
        try {
            workspace.setRuntime(new WorkspaceRuntimeImpl(state.envName, envEngine.getMachines(workspace.getId())));
        } catch (Exception x) {
            workspace.setRuntime(new WorkspaceRuntimeImpl(state.envName, Collections.emptyList()));
        }
    }
}
Also used : Unlocker(org.eclipse.che.commons.lang.concurrent.Unlocker) WorkspaceRuntimeImpl(org.eclipse.che.api.workspace.server.model.impl.WorkspaceRuntimeImpl) AgentException(org.eclipse.che.api.agent.server.exception.AgentException) EnvironmentStartInterruptedException(org.eclipse.che.api.environment.server.exception.EnvironmentStartInterruptedException) EnvironmentNotRunningException(org.eclipse.che.api.environment.server.exception.EnvironmentNotRunningException) CancellationException(java.util.concurrent.CancellationException) EnvironmentException(org.eclipse.che.api.environment.server.exception.EnvironmentException) ConflictException(org.eclipse.che.api.core.ConflictException) MachineException(org.eclipse.che.api.machine.server.exception.MachineException) NotFoundException(org.eclipse.che.api.core.NotFoundException) SnapshotException(org.eclipse.che.api.machine.server.exception.SnapshotException) ServerException(org.eclipse.che.api.core.ServerException)

Example 9 with Unlocker

use of org.eclipse.che.commons.lang.concurrent.Unlocker in project che by eclipse.

the class WorkspaceRuntimes method startAsync.

/**
     * Asynchronously starts the environment of the workspace.
     * Before executing start task checks whether all conditions
     * are met and throws appropriate exceptions if not, so
     * there is no way to start the same workspace twice.
     *
     * <p>Note that cancellation of resulting future won't
     * interrupt workspace start, call {@link #stop(String)} directly instead.
     *
     * <p>If starting process is interrupted let's say within call
     * to {@link #stop(String)} method, resulting future will
     * be exceptionally completed(eventually) with an instance of
     * {@link EnvironmentStartInterruptedException}. Note that clients
     * don't have to cleanup runtime resources, the component
     * will do necessary cleanup when interrupted.
     *
     * <p>Implementation notes:
     * if thread which executes the task is interrupted, then the
     * task is also eventually(depends on the environment engine implementation)
     * interrupted as if {@link #stop(String)} is called directly.
     * That helps to shutdown gracefully when thread pool is asked
     * to {@link ExecutorService#shutdownNow()} and also reduces
     * shutdown time when there are starting workspaces.
     *
     * @param workspace
     *         workspace containing target environment
     * @param envName
     *         the name of the environment to start
     * @param recover
     *         whether to recover from the snapshot
     * @return completable future describing the instance of running environment
     * @throws ConflictException
     *         when the workspace is already started
     * @throws ConflictException
     *         when workspaces start refused {@link #refuseWorkspacesStart()} was called
     * @throws ServerException
     *         when any other error occurs
     * @throws IllegalArgumentException
     *         when the workspace doesn't contain the environment
     * @throws NullPointerException
     *         when either {@code workspace} or {@code envName} is null
     */
public CompletableFuture<WorkspaceRuntimeImpl> startAsync(Workspace workspace, String envName, boolean recover) throws ConflictException, ServerException {
    requireNonNull(workspace, "Non-null workspace required");
    requireNonNull(envName, "Non-null environment name required");
    EnvironmentImpl environment = copyEnv(workspace, envName);
    String workspaceId = workspace.getId();
    CompletableFuture<WorkspaceRuntimeImpl> cmpFuture;
    StartTask startTask;
    try (@SuppressWarnings("unused") Unlocker u = locks.writeLock(workspaceId)) {
        checkIsNotTerminated("start the workspace");
        if (isStartRefused.get()) {
            throw new ConflictException(format("Start of the workspace '%s' is rejected by the system, " + "no more workspaces are allowed to start", workspace.getConfig().getName()));
        }
        RuntimeState state = states.get(workspaceId);
        if (state != null) {
            throw new ConflictException(format("Could not start workspace '%s' because its status is '%s'", workspace.getConfig().getName(), state.status));
        }
        startTask = new StartTask(workspaceId, envName, environment, recover, cmpFuture = new CompletableFuture<>());
        states.put(workspaceId, new RuntimeState(WorkspaceStatus.STARTING, envName, startTask, sharedPool.submit(startTask)));
    }
    // publish event synchronously as the task may not be executed by
    // executors service(due to legal cancellation), clients still have
    // to receive STOPPED -> STARTING event
    eventsService.publish(DtoFactory.newDto(WorkspaceStatusEvent.class).withWorkspaceId(workspaceId).withStatus(WorkspaceStatus.STARTING).withEventType(EventType.STARTING).withPrevStatus(WorkspaceStatus.STOPPED));
    // so the start thread is free to go and start the environment
    startTask.unlockStart();
    return cmpFuture;
}
Also used : ConflictException(org.eclipse.che.api.core.ConflictException) Unlocker(org.eclipse.che.commons.lang.concurrent.Unlocker) WorkspaceStatusEvent(org.eclipse.che.api.workspace.shared.dto.event.WorkspaceStatusEvent) EnvironmentImpl(org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl) WorkspaceRuntimeImpl(org.eclipse.che.api.workspace.server.model.impl.WorkspaceRuntimeImpl)

Example 10 with Unlocker

use of org.eclipse.che.commons.lang.concurrent.Unlocker in project che by eclipse.

the class WorkspaceRuntimes method getRuntime.

/**
     * Gets workspace runtime descriptor.
     *
     * @param workspaceId
     *         the id of the workspace to get its runtime
     * @return descriptor which describes current state of the workspace runtime
     * @throws NotFoundException
     *         when workspace with given {@code workspaceId} is not found
     * @throws ServerException
     *         if any error occurs while getting machines runtime information
     */
public WorkspaceRuntimeImpl getRuntime(String workspaceId) throws NotFoundException, ServerException {
    requireNonNull(workspaceId, "Required non-null workspace id");
    RuntimeState state;
    try (@SuppressWarnings("unused") Unlocker u = locks.readLock(workspaceId)) {
        state = new RuntimeState(getExistingState(workspaceId));
    }
    return new WorkspaceRuntimeImpl(state.envName, envEngine.getMachines(workspaceId));
}
Also used : Unlocker(org.eclipse.che.commons.lang.concurrent.Unlocker) WorkspaceRuntimeImpl(org.eclipse.che.api.workspace.server.model.impl.WorkspaceRuntimeImpl)

Aggregations

Unlocker (org.eclipse.che.commons.lang.concurrent.Unlocker)18 ServerException (org.eclipse.che.api.core.ServerException)11 ConflictException (org.eclipse.che.api.core.ConflictException)10 NotFoundException (org.eclipse.che.api.core.NotFoundException)8 EnvironmentNotRunningException (org.eclipse.che.api.environment.server.exception.EnvironmentNotRunningException)8 Instance (org.eclipse.che.api.machine.server.spi.Instance)8 EnvironmentStartInterruptedException (org.eclipse.che.api.environment.server.exception.EnvironmentStartInterruptedException)5 MachineException (org.eclipse.che.api.machine.server.exception.MachineException)5 AgentException (org.eclipse.che.api.agent.server.exception.AgentException)4 EnvironmentException (org.eclipse.che.api.environment.server.exception.EnvironmentException)4 MachineConfigImpl (org.eclipse.che.api.machine.server.model.impl.MachineConfigImpl)4 EnvironmentImpl (org.eclipse.che.api.workspace.server.model.impl.EnvironmentImpl)4 WorkspaceRuntimeImpl (org.eclipse.che.api.workspace.server.model.impl.WorkspaceRuntimeImpl)4 ArrayList (java.util.ArrayList)3 CancellationException (java.util.concurrent.CancellationException)3 MachineConfig (org.eclipse.che.api.core.model.machine.MachineConfig)3 ExtendedMachine (org.eclipse.che.api.core.model.workspace.ExtendedMachine)3 CheServicesEnvironmentImpl (org.eclipse.che.api.environment.server.model.CheServicesEnvironmentImpl)3 SnapshotException (org.eclipse.che.api.machine.server.exception.SnapshotException)3 SourceNotFoundException (org.eclipse.che.api.machine.server.exception.SourceNotFoundException)3