org.infrastructurebuilder.util.MutableProcessExecutionResultBag Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ibexecutor Show documentation
Show all versions of ibexecutor Show documentation
Standard interfaces for running applications as a heavyweight process
/**
* Copyright © 2019 admin ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.infrastructurebuilder.util;
import static java.time.Duration.between;
import static java.time.Instant.now;
import static java.util.Objects.requireNonNull;
import static java.util.Optional.ofNullable;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
import org.infrastructurebuilder.util.execution.model.v1_0_0.DefaultProcessExecutionResult;
import org.zeroturnaround.exec.ProcessExecutor;
import org.zeroturnaround.exec.ProcessResult;
import org.zeroturnaround.exec.listener.ProcessListener;
public class MutableProcessExecutionResultBag extends ProcessListener {
private final ConcurrentMap endTimes = new ConcurrentHashMap<>();
private final ConcurrentMap exceptions = new ConcurrentHashMap<>();
private final List executedIds = new ArrayList<>();
// private final ConcurrentMap executors = new ConcurrentHashMap<>();
private final Vector executors2 = new Vector<>();
private final ConcurrentMap exitCodes = new ConcurrentHashMap<>();
private final ConcurrentMap> futures = new ConcurrentHashMap<>();
private final ConcurrentMap processes = new ConcurrentHashMap<>();
private final ConcurrentMap startTimes = new ConcurrentHashMap<>();
public void addExecution(final ProcessExecution pe, final ProcessExecutor pExecutor) {
synchronized (executedIds) {
executors2.add(pe);
// executors.put(requireNonNull(pe), requireNonNull(pExecutor));
executedIds.add(pe.getId());
}
}
public MutableProcessExecutionResultBag addFuture(final ProcessExecution pe, final Future future) {
futures.put(requireNonNull(pe).getId(), requireNonNull(future));
return this;
}
public void addProcess(final ProcessExecution pe, final Process process) {
processes.put(requireNonNull(pe).getId(), requireNonNull(process));
}
@Override
public void afterFinish(final Process process, final ProcessResult result) {
afterStop(process);
processes.entrySet().stream().filter(e -> e.getValue() == process).map(ee -> ee.getKey()).findFirst()
.ifPresent(pe -> {
endTimes.put(pe, now());
exitCodes.put(pe, result.getExitValue());
});
}
@Override
public void afterStart(final Process process, final ProcessExecutor executor) {
super.afterStart(process, executor);
}
@Override
public void afterStop(final Process process) {
processes.entrySet().stream().filter(e -> e.getValue() == process).map(ee -> ee.getKey()).findFirst()
.ifPresent(pe -> {
endTimes.put(pe, now());
exitCodes.put(pe, process.exitValue());
});
}
@Override
public void beforeStart(final ProcessExecutor executor) {
requireNonNull(executor);
// executors.entrySet().stream().filter(e -> e.getValue() == executor).map(e -> e.getKey()).findFirst()
// .ifPresent(ee -> {
// startTimes.put(ee.getId(), now());
// });
executors2.stream().filter(e -> e.getProcessExecutor() == executor).findFirst()
.ifPresent(ee -> {
startTimes.put(ee.getId(), now());
});
}
public boolean destroyRemainingSleepers(final Optional sleepAfter) {
requireNonNull(sleepAfter);
for (final String p : getRunningFutures().keySet()) {
processes.get(p).destroy();
}
for (final Future p : getRunningFutures().values()) {
p.cancel(false);
}
final long sleep = sleepAfter.orElse(0L);
try {
Thread.sleep(sleep);
} catch (final InterruptedException e) {
}
boolean retVal = false;
for (final Future p : getRunningFutures().values()) {
retVal |= p.cancel(true);
}
return retVal;
}
public List getExecutedIds() {
return executedIds;
}
public Map getExecutionResults() {
synchronized (executedIds) {
final Map m = new HashMap<>();
for (final ProcessExecution pe : executors2) {
// for (final ProcessExecution pe : executors.keySet()) {
final String id = pe.getId();
final Instant startTime = ofNullable(startTimes.get(id)).orElse(null);
final Instant endTime = ofNullable(endTimes.get(id)).orElse(Instant.MAX);
final Optional exitCode = ofNullable(exitCodes.get(id));
final Optional exception = ofNullable(exceptions.get(id));
m.put(id, new DefaultProcessExecutionResult(pe, exitCode, exception, startTime,
between(startTime, endTime)));
}
return m;
}
}
public Map> getFutures() {
return futures;
}
public DefaultProcessExecutionResultBag lock() {
return new DefaultProcessExecutionResultBag(this);
}
public void setException(final ProcessExecution pe, final Throwable t) {
exceptions.put(requireNonNull(pe).getId(), requireNonNull(t));
}
public boolean stillRunning() {
return getRunningFutures().values().stream().findAny().isPresent();
}
Map> getRunningFutures() {
return getFutures().entrySet().stream().filter(e -> !e.getValue().isDone())
.collect(Collectors.toMap(k -> k.getKey(), v -> v.getValue()));
}
}