feat: remove & retry queue jobs

This commit is contained in:
tdurieux
2021-09-23 18:45:39 +02:00
parent 046d0c65cf
commit ad49eedebc
3 changed files with 88 additions and 33 deletions
+18 -10
View File
@@ -6,9 +6,7 @@
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary" class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
ng-repeat="job in downloadJobs as filteredDownloadJobs" ng-repeat="job in downloadJobs as filteredDownloadJobs"
> >
<div class="w-100"> <div class="w-100">{{job}}</div>
{{job}}
</div>
<div class="d-flex"> <div class="d-flex">
<div class="dropdown"> <div class="dropdown">
<button <button
@@ -25,11 +23,17 @@
<a <a
class="dropdown-item" class="dropdown-item"
href="#" href="#"
ng-show="job.status != 'removed'" ng-click="removeJob('download', job)"
ng-click="removeJob(job)"
> >
<i class="fas fa-trash-alt"></i> Remove <i class="fas fa-trash-alt"></i> Remove
</a> </a>
<a
class="dropdown-item"
href="#"
ng-click="retryJob('download', job)"
>
<i class="fas fa-sync"></i> Retry
</a>
</div> </div>
</div> </div>
</div> </div>
@@ -47,9 +51,7 @@
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary" class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
ng-repeat="job in removeJobs as filteredRemoveJobs" ng-repeat="job in removeJobs as filteredRemoveJobs"
> >
<div class="w-100"> <div class="w-100">{{job}}</div>
{{job}}
</div>
<div class="d-flex"> <div class="d-flex">
<div class="dropdown"> <div class="dropdown">
<button <button
@@ -66,11 +68,17 @@
<a <a
class="dropdown-item" class="dropdown-item"
href="#" href="#"
ng-show="job.status != 'removed'" ng-click="removeJob('remove', job)"
ng-click="removeJob(job)"
> >
<i class="fas fa-trash-alt"></i> Remove <i class="fas fa-trash-alt"></i> Remove
</a> </a>
<a
class="dropdown-item"
href="#"
ng-click="retryJob('remove', job)"
>
<i class="fas fa-sync"></i> Retry
</a>
</div> </div>
</div> </div>
</div> </div>
+32 -20
View File
@@ -126,7 +126,7 @@ angular
page: 1, page: 1,
limit: 25, limit: 25,
sort: "name", sort: "name",
search: "" search: "",
}; };
function getConferences() { function getConferences() {
@@ -154,7 +154,8 @@ angular
true true
); );
}, },
]).controller("queuesAdminController", [ ])
.controller("queuesAdminController", [
"$scope", "$scope",
"$http", "$http",
"$location", "$location",
@@ -170,21 +171,12 @@ angular
$scope.downloadJobs = []; $scope.downloadJobs = [];
$scope.removeJobs = []; $scope.removeJobs = [];
$scope.total = -1;
$scope.totalPage = 0;
$scope.query = {
page: 1,
limit: 25,
sort: "name",
search: ""
};
function getQueues() { function getQueues() {
$http.get("/api/admin/queues", { params: $scope.query }).then( $http.get("/api/admin/queues", { params: $scope.query }).then(
(res) => { (res) => {
$scope.downloadJobs = res.data.downloadQueue; $scope.downloadJobs = res.data.downloadQueue;
$scope.removeJobs = res.data.removeQueue; $scope.removeJobs = res.data.removeQueue;
$scope.$apply();
}, },
(err) => { (err) => {
console.error(err); console.error(err);
@@ -193,14 +185,34 @@ angular
} }
getQueues(); getQueues();
let timeClear = null; $scope.removeJob = function (queue, job) {
$scope.$watch( $http
"query", .delete(`/api/admin/queue/${queue}/${job.id}`, {
() => { params: $scope.query,
clearTimeout(timeClear); })
timeClear = setTimeout(getQueues, 500); .then(
}, (res) => {
true getQueues();
); },
(err) => {
console.error(err);
}
);
};
$scope.retryJob = function (queue, job) {
$http
.post(`/api/admin/queue/${queue}/${job.id}`, {
params: $scope.query,
})
.then(
(res) => {
getQueues();
},
(err) => {
console.error(err);
}
);
};
}, },
]); ]);
+38 -3
View File
@@ -1,10 +1,9 @@
import { Queue } from "bull";
import * as express from "express"; import * as express from "express";
import AnonymizedRepositoryModel from "../database/anonymizedRepositories/anonymizedRepositories.model"; import AnonymizedRepositoryModel from "../database/anonymizedRepositories/anonymizedRepositories.model";
import ConferenceModel from "../database/conference/conferences.model"; import ConferenceModel from "../database/conference/conferences.model";
import RepositoryModel from "../database/repositories/repositories.model";
import UserModel from "../database/users/users.model"; import UserModel from "../database/users/users.model";
import { downloadQueue, removeQueue } from "../queue"; import { downloadQueue, removeQueue } from "../queue";
import Repository from "../Repository";
import { ensureAuthenticated } from "./connection"; import { ensureAuthenticated } from "./connection";
import { handleError, getUser, isOwnerOrAdmin } from "./route-utils"; import { handleError, getUser, isOwnerOrAdmin } from "./route-utils";
@@ -29,6 +28,40 @@ router.use(
} }
); );
router.post("/queue/:name/:repo_id", async (req, res) => {
let queue: Queue;
if (req.params.name == "download") {
queue = downloadQueue;
} else if (req.params.name == "remove") {
queue = removeQueue;
} else {
return res.status(404).json({ error: "queue_not_found" });
}
const job = await queue.getJob(req.params.repo_id);
if (!job) {
return res.status(404).json({ error: "job_not_found" });
}
job.retry();
res.send("ok");
});
router.delete("/queue/:name/:repo_id", async (req, res) => {
let queue: Queue;
if (req.params.name == "download") {
queue = downloadQueue;
} else if (req.params.name == "remove") {
queue = removeQueue;
} else {
return res.status(404).json({ error: "queue_not_found" });
}
const job = await queue.getJob(req.params.repo_id);
if (!job) {
return res.status(404).json({ error: "job_not_found" });
}
await job.remove();
res.send("ok");
});
router.get("/queues", async (req, res) => { router.get("/queues", async (req, res) => {
const out = await Promise.all([ const out = await Promise.all([
downloadQueue.getJobs([ downloadQueue.getJobs([
@@ -94,7 +127,9 @@ router.get("/repos", async (req, res) => {
res.json({ res.json({
query: { $and: query }, query: { $and: query },
page, page,
total: await AnonymizedRepositoryModel.find({ $and: query }).estimatedDocumentCount(), total: await AnonymizedRepositoryModel.find({
$and: query,
}).estimatedDocumentCount(),
sort, sort,
results: await AnonymizedRepositoryModel.find({ $and: query }) results: await AnonymizedRepositoryModel.find({ $and: query })
.sort(sort) .sort(sort)