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

com.carrotsearch.procfork.ForkedProcess Maven / Gradle / Ivy

/*
 * procfork
 *
 * Copyright (C) 2019, Dawid Weiss.
 * All rights reserved.
 */
package com.carrotsearch.procfork;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

public class ForkedProcess implements Closeable {
  private final Process p;
  private final Path processOutput;

  public ForkedProcess(Process p, Path processOutput) {
    this.p = p;
    this.processOutput = processOutput;
  }

  public Process getProcess() {
    return p;
  }

  public List destroyForcibly() {
    ArrayList procList = getProcessHandles();

    for (ProcessHandle ph : procList) {
      if (ph.isAlive()) {
        ph.destroyForcibly();
      }
    }

    return procList;
  }

  public Path getProcessOutputFile() {
    return processOutput;
  }

  public InputStream getProcessOutputAsStream() throws IOException {
    return new TailInputStream(processOutput, () -> !p.isAlive());
  }

  public int waitFor() throws InterruptedException {
    return getProcess().waitFor();
  }

  @Override
  public void close() throws IOException {
    List handles = destroyForcibly();

    try {
      for (ProcessHandle handle : handles) {
        handle.onExit().get();
      }
    } catch (ExecutionException | InterruptedException e) {
      throw new IOException(e);
    }

    Instant deadline = Instant.now().plusSeconds(2);
    try {
      while (true) {
        try {
          Files.deleteIfExists(processOutput);
          break;
        } catch (IOException e) {
          if (Instant.now().isAfter(deadline)) {
            throw e;
          } else {
            // Fall-through.
          }
        }

        // Linger a bit before retrying to delete this file.
        Thread.sleep(250);
      }
    } catch (InterruptedException e) {
      throw new IOException(e);
    }
  }

  private ArrayList getProcessHandles() {
    ArrayList procList =
        p.descendants().collect(Collectors.toCollection(ArrayList::new));
    procList.add(p.toHandle());
    return procList;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy