From 67dd1243073e766178dd70dd2f45aa5bc77ec529 Mon Sep 17 00:00:00 2001
From: Kai Reinhard <K.Reinhard@micromata.de>
Date: Sat, 05 Jan 2019 22:03:29 +0000
Subject: [PATCH] Job monitor: Cancellation of jobs...
---
borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/AbstractCommandLineJob.java | 2
borgbutler-webapp/src/components/views/jobs/Job.jsx | 32 +++++++++-
borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/AbstractJob.java | 4
borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/JobQueue.java | 16 +++++
borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java | 8 +-
borgbutler-core/src/main/java/de/micromata/borgbutler/BorgJob.java | 1
borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/queue/JsonJob.java | 4 +
borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/JobsRest.java | 34 +++++++----
borgbutler-core/src/main/java/de/micromata/borgbutler/BorgQueueExecutor.java | 28 ++++++++
9 files changed, 104 insertions(+), 25 deletions(-)
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java
index 7f0a706..b525573 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgCommands.java
@@ -35,7 +35,7 @@
.setParams("--version")
.setDescription("Getting borg version.");
JobResult<String> jobResult = execute(command).getResult();
- if (jobResult.getStatus() != JobResult.Status.OK) {
+ if (jobResult == null || jobResult.getStatus() != JobResult.Status.OK) {
return null;
}
String version = jobResult.getResultObject();
@@ -56,7 +56,7 @@
.setParams("--json") // --progress has no effect.
.setDescription("Loading info of repo '" + repoConfig.getDisplayName() + "'.");
JobResult<String> jobResult = execute(command).getResult();
- if (jobResult.getStatus() != JobResult.Status.OK) {
+ if (jobResult == null || jobResult.getStatus() != JobResult.Status.OK) {
return null;
}
String result = jobResult.getResultObject();
@@ -89,7 +89,7 @@
.setParams("--json") // --progress has no effect.
.setDescription("Loading list of archives of repo '" + repoConfig.getDisplayName() + "'.");
JobResult<String> jobResult = execute(command).getResult();
- if (jobResult.getStatus() != JobResult.Status.OK) {
+ if (jobResult == null || jobResult.getStatus() != JobResult.Status.OK) {
log.error("Can't load archives from repo '" + repository.getName() + "'.");
return;
}
@@ -131,7 +131,7 @@
.setParams("--json", "--log-json", "--progress")
.setDescription("Loading info of archive '" + archive.getName() + "' of repo '" + repoConfig.getDisplayName() + "'.");
JobResult<String> jobResult = execute(command).getResult();
- if (jobResult.getStatus() != JobResult.Status.OK) {
+ if (jobResult == null || jobResult.getStatus() != JobResult.Status.OK) {
return;
}
String result = jobResult.getResultObject();
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgJob.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgJob.java
index 79e78ba..d5f057e 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgJob.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgJob.java
@@ -108,6 +108,7 @@
@Override
public BorgJob<?> clone() {
BorgJob<?> clone = new BorgJob<>();
+ clone.setUniqueJobNumber(getUniqueJobNumber());
clone.setTitle(getTitle());
clone.setExecuteStarted(isExecuteStarted());
clone.setCommandLineAsString(getCommandLineAsString());
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgQueueExecutor.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgQueueExecutor.java
index e4dc1a8..5e440fe 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgQueueExecutor.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/BorgQueueExecutor.java
@@ -28,11 +28,33 @@
*/
public List<String> getRepos() {
List<String> list = new ArrayList<>();
- list.addAll(queueMap.keySet());
+ synchronized (queueMap) {
+ list.addAll(queueMap.keySet());
+ }
Collections.sort(list);
return list;
}
+ public void cancelJob(long uniqueJobNumber) {
+ AbstractJob<?> job = getQueuedJobByUniqueJobNumber(uniqueJobNumber);
+ if (job == null) {
+ log.info("Can't cancel job #" + uniqueJobNumber + ". Not found as queued job (may-be already cancelled or finished). Nothing to do.");
+ return;
+ }
+ job.cancel();
+ }
+
+ private AbstractJob<?> getQueuedJobByUniqueJobNumber(long uniqueJobNumber) {
+ Iterator<JobQueue<String>> it = queueMap.values().iterator();
+ while (it.hasNext()) {
+ AbstractJob<?> job = it.next().getQueuedJobByUniqueJobNumber(uniqueJobNumber);
+ if (job != null) {
+ return job;
+ }
+ }
+ return null;
+ }
+
/**
* For displaying purposes.
*
@@ -56,7 +78,9 @@
}
private JobQueue<String> getQueue(String repo) {
- return queueMap.get(getQueueName(repo));
+ synchronized (queueMap) {
+ return queueMap.get(getQueueName(repo));
+ }
}
private JobQueue<String> ensureAndGetQueue(String repo) {
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/AbstractCommandLineJob.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/AbstractCommandLineJob.java
index aee1b4f..591980d 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/AbstractCommandLineJob.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/AbstractCommandLineJob.java
@@ -124,7 +124,7 @@
@Override
protected void cancelRunningProcess() {
if (watchdog != null) {
- log.info("Cancelling job: " + getId());
+ log.info("Cancelling job #" + getUniqueJobNumber() + ": " + getId());
watchdog.destroyProcess();
watchdog = null;
setCancelled();
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/AbstractJob.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/AbstractJob.java
index 8b6e8e8..df97791 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/AbstractJob.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/AbstractJob.java
@@ -27,8 +27,8 @@
@Setter(AccessLevel.PACKAGE)
private Future<JobResult<T>> future;
@Getter
- @Setter(AccessLevel.PACKAGE)
- private long uniqueJobNumber;
+ @Setter(AccessLevel.PROTECTED)
+ private long uniqueJobNumber = -1;
public void cancel() {
if (this.getStatus() == Status.QUEUED) {
diff --git a/borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/JobQueue.java b/borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/JobQueue.java
index 5e5a95c..819cb0e 100644
--- a/borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/JobQueue.java
+++ b/borgbutler-core/src/main/java/de/micromata/borgbutler/jobs/JobQueue.java
@@ -29,6 +29,22 @@
}
/**
+ * Searches only for queued jobs (not done jobs).
+ * @param uniqueJobNumber
+ * @return The job if any job with the given unique job number is queued, otherwise null.
+ */
+ public AbstractJob<T> getQueuedJobByUniqueJobNumber(long uniqueJobNumber) {
+ Iterator<AbstractJob<T>> it = queue.iterator();
+ while (it.hasNext()) {
+ AbstractJob<T> job = it.next();
+ if (job.getUniqueJobNumber() == uniqueJobNumber) {
+ return job;
+ }
+ }
+ return null;
+ }
+
+ /**
* Appends the job if not alread in the queue. Starts the execution if no execution thread is already running.
*
* @param job
diff --git a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/JobsRest.java b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/JobsRest.java
index 5991560..382b331 100644
--- a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/JobsRest.java
+++ b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/JobsRest.java
@@ -59,34 +59,43 @@
}
@Path("/cancel")
- @PUT
- @Produces(MediaType.APPLICATION_JSON)
+ @GET
/**
- * @param testMode If true, then a test job list is created.
- * @param prettyPrinter If true then the json output will be in pretty format.
- * @return Job queues as json string.
- * @see JsonUtils#toJson(Object, boolean)
+ * @param uniqueJobNumberString The id of the job to cancel.
*/
- public void cancelJob(@QueryParam("job") String job, @QueryParam("prettyPrinter") boolean prettyPrinter) {
- log.info("Cancelling job");
+ public void cancelJob(@QueryParam("uniqueJobNumber") String uniqueJobNumberString) {
+ Long uniqueJobNumber = null;
+ try {
+ uniqueJobNumber = Long.parseLong(uniqueJobNumberString);
+ } catch (NumberFormatException ex) {
+ log.error("Can't cancel job, because unique job number couln't be parsed (long value expected): " + uniqueJobNumberString);
+ return;
+ }
+ BorgQueueExecutor.getInstance().cancelJob(uniqueJobNumber);
}
/**
* Only for test purposes and development.
+ *
* @param prettyPrinter
* @return
*/
private String returnTestList(boolean prettyPrinter) {
if (testList == null) {
testList = new ArrayList<>();
+ long uniqueJobNumber = 100000;
JsonJobQueue queue = new JsonJobQueue().setRepo("My Computer");
- addTestJob(queue, "info", "my-macbook", 0, 2342);
- addTestJob(queue, "list", "my-macbook", -1, -1);
+ addTestJob(queue, "info", "my-macbook", 0, 2342)
+ .setUniqueJobNumber(uniqueJobNumber++);
+ addTestJob(queue, "list", "my-macbook", -1, -1)
+ .setUniqueJobNumber(uniqueJobNumber++);
testList.add(queue);
queue = new JsonJobQueue().setRepo("My Server");
- addTestJob(queue, "list", "my-server", 0, 1135821);
- addTestJob(queue, "info", "my-server", -1, -1);
+ addTestJob(queue, "list", "my-server", 0, 1135821)
+ .setUniqueJobNumber(uniqueJobNumber++);
+ addTestJob(queue, "info", "my-server", -1, -1)
+ .setUniqueJobNumber(uniqueJobNumber++);
testList.add(queue);
} else {
for (JsonJobQueue jobQueue : testList) {
@@ -117,6 +126,7 @@
/**
* Only for test purposes and development.
+ *
* @param queue
* @param operation
* @param host
diff --git a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/queue/JsonJob.java b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/queue/JsonJob.java
index 8430945..be2457f 100644
--- a/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/queue/JsonJob.java
+++ b/borgbutler-server/src/main/java/de/micromata/borgbutler/server/rest/queue/JsonJob.java
@@ -31,11 +31,15 @@
@Getter
@Setter
private String commandLineAsString;
+ @Getter
+ @Setter
+ private long uniqueJobNumber;
public JsonJob() {
}
public JsonJob(BorgJob<?> borgJob) {
+ this.uniqueJobNumber = borgJob.getUniqueJobNumber();
this.cancellationRequested = borgJob.isCancellationRequested();
this.status = borgJob.getStatus();
this.title = borgJob.getTitle();
diff --git a/borgbutler-webapp/src/components/views/jobs/Job.jsx b/borgbutler-webapp/src/components/views/jobs/Job.jsx
index 4b3ba06..5d45234 100644
--- a/borgbutler-webapp/src/components/views/jobs/Job.jsx
+++ b/borgbutler-webapp/src/components/views/jobs/Job.jsx
@@ -1,14 +1,22 @@
import React from 'react';
import {Button, Card, CardBody, Collapse, Progress} from 'reactstrap';
-import {IconCancelJob} from '../../general/IconComponents'
+import {IconCancel} from '../../general/IconComponents'
+import {getRestServiceUrl} from "../../../utilities/global";
class Job extends React.Component {
constructor(props) {
super(props);
this.toggle = this.toggle.bind(this);
+ this.cacnelJob = this.cancelJob.bind(this);
this.state = {collapse: false};
}
+ cancelJob = (jobId) => {
+ fetch(getRestServiceUrl('jobs/cancel', {
+ uniqueJobNumber: jobId
+ }));
+ };
+
toggle() {
this.setState({collapse: !this.state.collapse});
}
@@ -25,15 +33,31 @@
} else {
content = <Progress color={'info'} value={100}>{job.status}</Progress>
}
+ let cancelDisabled = undefined;
+ if (job.status !== 'RUNNING' && job.status !== 'QUEUED') {
+ cancelDisabled = true;
+ }
return (
<div>
<Button color="link" onClick={this.toggle}>{job.description}</Button>
- <div>{content}<IconCancelJob/></div>
+ <div>{content}
+ <Button color={'danger'} onClick={() => this.cancelJob(job.uniqueJobNumber)} disabled={cancelDisabled}><IconCancel/></Button>
+ </div>
<Collapse isOpen={this.state.collapse}>
<Card>
<CardBody>
- <table><tbody><tr><th>Status</th><td>{job.status}</td></tr>
- <tr><th>Command line</th><td>{job.commandLineAsString}</td></tr></tbody></table>
+ <table>
+ <tbody>
+ <tr>
+ <th>Status</th>
+ <td>{job.status}</td>
+ </tr>
+ <tr>
+ <th>Command line</th>
+ <td>{job.commandLineAsString}</td>
+ </tr>
+ </tbody>
+ </table>
</CardBody>
</Card>
</Collapse>
--
Gitblit v1.10.0