diff --git a/.travis.yml b/.travis.yml index a6828f8..c668c78 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,12 +14,13 @@ addons: - python3 - python3-pip - python3-setuptools + - python3-venv - nodejs - docker before_install: - gem install fpm --version 1.10.0 -- pip3 install --user --upgrade pip virtualenv -- virtualenv -p python3 venv +- pip3 install --user --upgrade pip +- python3 -m venv venv/ - source venv/bin/activate - pip3 install -r jobson-docs/requirements.txt script: mvn package diff --git a/README.md b/README.md index 12aa03a..3d65993 100644 --- a/README.md +++ b/README.md @@ -48,9 +48,9 @@ Requires java (8+): ```bash # install and add to PATH -wget https://github.com/adamkewley/jobson/releases/download/1.0.10/jobson-nix-1.0.10.tar.gz -tar xvf jobson-nix-1.0.10.tar.gz -export PATH=$PATH:jobson-nix-1.0.10/bin +wget https://github.com/adamkewley/jobson/releases/download/1.0.11/jobson-nix-1.0.11.tar.gz +tar xvf jobson-nix-1.0.11.tar.gz +export PATH=$PATH:jobson-nix-1.0.11/bin # create demo workspace jobson new --demo diff --git a/jobson-deb/pom.xml b/jobson-deb/pom.xml index 1311f8b..73644a9 100644 --- a/jobson-deb/pom.xml +++ b/jobson-deb/pom.xml @@ -7,7 +7,7 @@ com.github.jobson jobson-project - 1.0.10 + 1.0.11 jobson-deb @@ -17,7 +17,7 @@ com.github.jobson jobson-nix - 1.0.10 + 1.0.11 tar.gz diff --git a/jobson-docker/pom.xml b/jobson-docker/pom.xml index 37d5640..26adfd7 100644 --- a/jobson-docker/pom.xml +++ b/jobson-docker/pom.xml @@ -7,7 +7,7 @@ com.github.jobson jobson-project - 1.0.10 + 1.0.11 jobson-docker @@ -17,7 +17,7 @@ com.github.jobson jobson-deb - 1.0.10 + 1.0.11 deb diff --git a/jobson-docs/pom.xml b/jobson-docs/pom.xml index 2fd70fd..f4bf10b 100644 --- a/jobson-docs/pom.xml +++ b/jobson-docs/pom.xml @@ -7,11 +7,11 @@ com.github.jobson jobson-project - 1.0.10 + 1.0.11 jobson-docs - 1.0.10 + 1.0.11 pom diff --git a/jobson-nix/pom.xml b/jobson-nix/pom.xml index 3a89e49..a21bda0 100644 --- a/jobson-nix/pom.xml +++ b/jobson-nix/pom.xml @@ -7,7 +7,7 @@ com.github.jobson jobson-project - 1.0.10 + 1.0.11 jobson-nix @@ -17,18 +17,18 @@ com.github.jobson jobson - 1.0.10 + 1.0.11 com.github.jobson jobson-docs - 1.0.10 + 1.0.11 tar.gz com.github.jobson jobson-ui - 1.0.10 + 1.0.11 tar.gz diff --git a/jobson-swagger-ui/pom.xml b/jobson-swagger-ui/pom.xml index b0d4328..0f1e82d 100644 --- a/jobson-swagger-ui/pom.xml +++ b/jobson-swagger-ui/pom.xml @@ -7,11 +7,11 @@ com.github.jobson jobson-project - 1.0.10 + 1.0.11 jobson-swagger-ui - 1.0.10 + 1.0.11 pom diff --git a/jobson-swagger/pom.xml b/jobson-swagger/pom.xml index 81e8bec..f266fa1 100644 --- a/jobson-swagger/pom.xml +++ b/jobson-swagger/pom.xml @@ -7,18 +7,18 @@ com.github.jobson jobson-project - 1.0.10 + 1.0.11 jobson-swagger - 1.0.10 + 1.0.11 pom com.github.jobson jobson - 1.0.10 + 1.0.11 com.fasterxml diff --git a/jobson-ui/pom.xml b/jobson-ui/pom.xml index 5021f9b..82d5dd6 100644 --- a/jobson-ui/pom.xml +++ b/jobson-ui/pom.xml @@ -7,11 +7,11 @@ com.github.jobson jobson-project - 1.0.10 + 1.0.11 jobson-ui - 1.0.10 + 1.0.11 pom diff --git a/jobson/pom.xml b/jobson/pom.xml index c42fab3..8d74c2e 100644 --- a/jobson/pom.xml +++ b/jobson/pom.xml @@ -7,11 +7,11 @@ com.github.jobson jobson-project - 1.0.10 + 1.0.11 jobson - 1.0.10 + 1.0.11 jar diff --git a/jobson/src/main/java/com/github/jobson/jobs/LocalJobExecutor.java b/jobson/src/main/java/com/github/jobson/jobs/LocalJobExecutor.java index ea797a0..65c5a8a 100644 --- a/jobson/src/main/java/com/github/jobson/jobs/LocalJobExecutor.java +++ b/jobson/src/main/java/com/github/jobson/jobs/LocalJobExecutor.java @@ -160,6 +160,15 @@ public CancelablePromise execute(PersistedJob req, JobEventL final Process runningProcess = processBuilder.start(); + // close process's stdin stream. If this isn't done, the + // child process will block if it tries to read from stdin + // (because it's connected to jobson's stdin, which isn't + // being used) + // + // see https://github.com/adamkewley/jobson/issues/67 for + // a breakdown of the kinds of problems this can create + runningProcess.getOutputStream().close(); + log.info(req.getId() + ": launched: " + String.join(" ", argList)); final SimpleCancelablePromise ret = new SimpleCancelablePromise<>(); diff --git a/jobson/src/test/java/com/github/jobson/jobs/execution/JobExecutorTest.java b/jobson/src/test/java/com/github/jobson/jobs/execution/JobExecutorTest.java index 1435856..e161a6f 100644 --- a/jobson/src/test/java/com/github/jobson/jobs/execution/JobExecutorTest.java +++ b/jobson/src/test/java/com/github/jobson/jobs/execution/JobExecutorTest.java @@ -184,8 +184,7 @@ public void testExecutePromiseResolvesWithFatalErrorForFailingCommand() throws T @Test public void testExecutePromiseResolvesWithAbortedIfPromiseIsCancelled() throws Throwable { final JobExecutor jobExecutor = getInstance(); - final PersistedJob req = - standardRequestWithCommand("cat"); // Long-running, because it blocks on an STDIN read. + final PersistedJob req = standardRequestWithCommand("sleep", "100"); final CancelablePromise ret = jobExecutor.execute(req, createNullListeners()); @@ -195,6 +194,28 @@ public void testExecutePromiseResolvesWithAbortedIfPromiseIsCancelled() throws T () -> ret.cancel(true)); } + @Test + public void testExecutePromiseResolvesCompletedIfApplicationReadsFromStdin() throws Throwable { + // jobson should close `stdin`, so that any application + // attempting to read from stdin reads nothing (rather than + // deadlocking indefinitely on content Jobson will never + // write) + // + // see: https://github.com/adamkewley/jobson/issues/67 + // + // (abstract): user ran an application that reads from stdin + // in certain circumstances and Jobson was deadlocking on that + final JobExecutor jobExecutor = getInstance(); + final PersistedJob req = standardRequestWithCommand("cat"); // reads from stdin + final CancelablePromise ret = + jobExecutor.execute(req, createNullListeners()); + + promiseAssert( + ret, + result -> assertThat(result.getFinalStatus()).isEqualTo(JobStatus.FINISHED), + () -> ret.cancel(true)); + } + @Test public void testExecutePromiseResolvesWithTheOutputsWrittenByTheApplication() throws Throwable { final JobExecutor jobExecutor = getInstance(); diff --git a/jobson/src/test/resources/fixtures/systemtests/jobspecs.yml b/jobson/src/test/resources/fixtures/systemtests/jobspecs.yml index 020cf8c..3213f9c 100644 --- a/jobson/src/test/resources/fixtures/systemtests/jobspecs.yml +++ b/jobson/src/test/resources/fixtures/systemtests/jobspecs.yml @@ -71,8 +71,8 @@ expectedInputs: [] execution: - application: cat - arguments: [] + application: sleep + arguments: ['100'] - id: fourth-spec name: Spec that creates an output diff --git a/pom.xml b/pom.xml index b24fb97..3fd8d76 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.jobson jobson-project - 1.0.10 + 1.0.11 pom jobson project @@ -48,8 +48,8 @@ - 1.0.10 - 1.0.10 + 1.0.11 + 1.0.11 2.0.10 UTF-8