All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.mike10004.nativehelper.subprocess.ProcessTracker Maven / Gradle / Ivy

There is a newer version: 10.0.0
Show newest version
package com.github.mike10004.nativehelper.subprocess;

import com.google.common.collect.ImmutableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Interface that represents a process context. A process context tracks the creation
 * and destruction of processes.
 */
public interface ProcessTracker {

    /**
     * Adds a process to this context instance.
     * @param process the process
     */
    void add(Process process);

    /**
     * Removes a process from this context instance.
     * @param process the process to remove
     * @return true iff the process existed in this process and was removed
     * @throws RuntimeException if process exists in this context and removing it failed
     */
    @SuppressWarnings("UnusedReturnValue")
    boolean remove(Process process);

    /**
     * Gets the count of process that have been added to this context but not removed.
     * @return the count of active processes
     */
    int activeCount();

    /**
     * Creates a process context instance. The default implementation is used.
     * @return a new process context instance
     */
    static ProcessTracker create() {
        return new ShutdownHookProcessTracker();
    }

    /**
     * Attempts to destroy multiple processes. For each process, {@link Process#destroy()} is invoked,
     * and then {@link Process#waitFor(long, TimeUnit) waitFor()} is invoked, blocking on the current
     * thread until the process terminates or the timeout elapses. If the process is still alive
     * after that wait, {@link Process#destroyForcibly() destroyForcibly()} is invoked, and the wait
     * is repeated.
     * @param processes the processes to destroy
     * @param timeoutPerProcess the timeout per process (total wait time is potentially twice this duration)
     * @param unit the timeout unit
     * @return a list of processes that are still alive
     */
    static List destroyAll(Iterable processes, long timeoutPerProcess, TimeUnit unit) {
        Logger log = LoggerFactory.getLogger(ProcessTracker.class);
        List undestroyed = new ArrayList<>();
        for (Process p : ImmutableList.copyOf(processes)) {
            p.destroy();
            boolean terminated = false;
            try {
                terminated = p.waitFor(timeoutPerProcess, unit);
            } catch (InterruptedException e) {
                log.warn("interrupted while waiting for process to terminate by destroy()");
            }
            if (!terminated) {
                p.destroyForcibly();
                try {
                    p.waitFor(timeoutPerProcess, unit);
                } catch (InterruptedException e) {
                    log.warn("interrupted while waiting for process to terminate by destroyForcibly()");
                }
            }
            if (p.isAlive()) {
                LoggerFactory.getLogger(ProcessTracker.class).error("failed to terminated process " + p);
                undestroyed.add(p);
            }
        }
        return undestroyed;

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy