/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.plugin.maven.server.core; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.LinkedList; import java.util.Queue; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; /** * Executor for {@link MavenProjectTask}. Uses {@link MavenExecutorService} as executor service. * * @author Evgen Vidolob */ public class MavenTaskExecutor { private static final Logger LOG = LoggerFactory.getLogger(MavenTaskExecutor.class); private final MavenExecutorService service; private final MavenProgressNotifier notifier; private final Queue<MavenProjectTask> queue = new LinkedList<>(); private boolean isWorking; public MavenTaskExecutor(MavenExecutorService service, MavenProgressNotifier notifier) { this.service = service; this.notifier = notifier; } public void submitTask(MavenProjectTask task) { synchronized (queue) { //if no running tasks, start immediately if (!isWorking) { isWorking = true; runTask(task); } else { if (!queue.contains(task)) { queue.add(task); } } } } public void removeTask(MavenProjectTask task) { synchronized (queue) { queue.remove(task); } } public void stop() { synchronized (queue) { queue.clear(); } } private void runTask(MavenProjectTask task) { service.submit(() -> doRunTasks(task)); } private void doRunTasks(MavenProjectTask task) { int taskDone = 0; notifier.start(); while (true) { taskDone++; int restTasks; synchronized (queue) { restTasks = queue.size(); } notifier.setPercent((double)taskDone / (double)(restTasks + taskDone)); try { task.perform(); } catch (Throwable throwable) { LOG.error(throwable.getMessage(), throwable); //TODO need to notify user some how } synchronized (queue) { task = queue.poll(); if (task == null) { isWorking = false; notifier.stop(); return; } } } } public void waitForEndAllTasks() { if(!isWorking){ return; } Semaphore semaphore = new Semaphore(1); try { semaphore.acquire(); submitTask(semaphore::release); while (true) { if (!isWorking || semaphore.tryAcquire(1, TimeUnit.SECONDS)) { return; } } } catch (InterruptedException e) { LOG.debug(e.getMessage(), e); } } }