mirror of
https://github.com/ohwgiles/laminar.git
synced 2024-10-27 20:34:20 +00:00
resolves #30: job execution timeout
Add the ability to configure a timeout in seconds after which a job run will be automatically aborted
This commit is contained in:
parent
ce81be85c7
commit
649caee297
@ -361,6 +361,14 @@ make -j4
|
||||
|
||||
Laminar will automatically create the workspace for a job if it doesn't exist when a job is executed. In this case, the `/var/lib/laminar/cfg/jobs/JOBNAME.init` will be executed if it exists. This is an excellent place to prepare the workspace to a state where subsequent builds can rely on its content.
|
||||
|
||||
### Abort on timeout
|
||||
|
||||
To configure a maximum execution time in seconds for a job, add a line to `/var/lib/laminar/cfg/jobs/JOBNAME.conf`:
|
||||
|
||||
```
|
||||
TIMEOUT=120
|
||||
```
|
||||
|
||||
### Nodes and Tags
|
||||
|
||||
In Laminar, a *node* is an abstract concept allowing more fine-grained control over job execution scheduling. Each node can be defined to support an integer number of *executors*, which defines how many runs can be executed simultaneously.
|
||||
|
@ -1,5 +1,5 @@
|
||||
///
|
||||
/// Copyright 2015-2017 Oliver Giles
|
||||
/// Copyright 2015-2018 Oliver Giles
|
||||
///
|
||||
/// This file is part of Laminar
|
||||
///
|
||||
@ -655,6 +655,20 @@ void Laminar::assignNewJobs() {
|
||||
if(fs::exists(cfgDir/"jobs"/run->name+".env"))
|
||||
run->addEnv((cfgDir/"jobs"/run->name+".env").string());
|
||||
|
||||
// add job timeout if specified
|
||||
if(fs::exists(cfgDir/"jobs"/run->name+".conf")) {
|
||||
int timeout = parseConfFile(fs::path(cfgDir/"jobs"/run->name+".conf").string().c_str()).get<int>("TIMEOUT", 0);
|
||||
if(timeout > 0) {
|
||||
// A raw pointer to run is used here so as not to have a circular reference.
|
||||
// The captured raw pointer is safe because if the Run is destroyed the Promise
|
||||
// will be cancelled and the callback never called.
|
||||
Run* r = run.get();
|
||||
r->timeout = srv->addTimeout(timeout, [r](){
|
||||
r->abort();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// start the job
|
||||
node->busyExecutors++;
|
||||
run->node = node;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <ostream>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <kj/async.h>
|
||||
|
||||
enum class RunState {
|
||||
UNKNOWN,
|
||||
@ -90,6 +91,7 @@ public:
|
||||
pid_t pid;
|
||||
int fd;
|
||||
std::unordered_map<std::string, std::string> params;
|
||||
kj::Promise<void> timeout = kj::NEVER_DONE;
|
||||
|
||||
time_t queuedAt;
|
||||
time_t startedAt;
|
||||
|
@ -1,5 +1,5 @@
|
||||
///
|
||||
/// Copyright 2015-2017 Oliver Giles
|
||||
/// Copyright 2015-2018 Oliver Giles
|
||||
///
|
||||
/// This file is part of Laminar
|
||||
///
|
||||
@ -469,6 +469,12 @@ void Server::addDescriptor(int fd, std::function<void(const char*,size_t)> cb) {
|
||||
childTasks.add(handleFdRead(event, buffer.asPtr().begin(), cb).attach(std::move(event)).attach(std::move(buffer)));
|
||||
}
|
||||
|
||||
kj::Promise<void> Server::addTimeout(int seconds, std::function<void ()> cb) {
|
||||
return ioContext.lowLevelProvider->getTimer().afterDelay(seconds * kj::SECONDS).then([cb](){
|
||||
cb();
|
||||
}).eagerlyEvaluate(nullptr);
|
||||
}
|
||||
|
||||
void Server::addWatchPath(const char* dpath) {
|
||||
inotify_add_watch(inotify_fd, dpath, IN_ONLYDIR | IN_CLOSE_WRITE | IN_CREATE | IN_DELETE);
|
||||
}
|
||||
|
@ -43,6 +43,9 @@ public:
|
||||
// invoked with the read data
|
||||
void addDescriptor(int fd, std::function<void(const char*,size_t)> cb);
|
||||
|
||||
// add a one-shot timer callback
|
||||
kj::Promise<void> addTimeout(int seconds, std::function<void()> cb);
|
||||
|
||||
// add a path to be watched for changes
|
||||
void addWatchPath(const char* dpath);
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
|
||||
class RunTest : public ::testing::Test {
|
||||
protected:
|
||||
virtual ~RunTest() noexcept override {}
|
||||
|
||||
void SetUp() override {
|
||||
run.node = node;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user