1
0
mirror of https://github.com/ohwgiles/laminar.git synced 2026-03-02 03:40:21 +00:00

job leader process

Implement a separate process, the "leader", which runs all the
scripts for a job run, instead of directly from the main laminard
process. This makes for a cleaner process tree view, where the
owning job for a given script is clear; also the leader process
acts as a subreaper to clean up any wayward descendent processes.

Resolves #78.
This commit is contained in:
Oliver Giles
2019-12-21 15:29:37 +02:00
parent 304ef797b8
commit 3fde38c6b8
16 changed files with 600 additions and 409 deletions

View File

@@ -26,6 +26,7 @@
#include "tempdir.h"
#include "laminar.h"
#include "server.h"
#include "conf.h"
class LaminarFixture : public ::testing::Test {
public:
@@ -38,7 +39,7 @@ public:
settings.bind_rpc = bind_rpc.c_str();
settings.bind_http = bind_http.c_str();
settings.archive_url = "/test-archive/";
server = new Server(ioContext);
server = new Server(*ioContext);
laminar = new Laminar(*server, settings);
}
~LaminarFixture() noexcept(true) {
@@ -47,7 +48,7 @@ public:
}
kj::Own<EventSource> eventSource(const char* path) {
return kj::heap<EventSource>(ioContext, bind_http.c_str(), path);
return kj::heap<EventSource>(*ioContext, bind_http.c_str(), path);
}
void defineJob(const char* name, const char* scriptContent) {
@@ -57,9 +58,61 @@ public:
}
}
struct RunExec {
LaminarCi::JobResult result;
kj::String log;
};
RunExec runJob(const char* name, kj::Maybe<StringMap> params = nullptr) {
auto req = client().runRequest();
req.setJobName(name);
KJ_IF_MAYBE(p, params) {
auto params = req.initParams(p->size());
int i = 0;
for(auto kv : *p) {
params[i].setName(kv.first);
params[i].setValue(kv.second);
i++;
}
}
auto res = req.send().wait(ioContext->waitScope);
std::string path = std::string{"/log/"} + name + "/" + std::to_string(res.getBuildNum());
kj::HttpHeaderTable headerTable;
kj::String log = kj::newHttpClient(ioContext->lowLevelProvider->getTimer(), headerTable,
*ioContext->provider->getNetwork().parseAddress(bind_http.c_str()).wait(ioContext->waitScope))
->request(kj::HttpMethod::GET, path, kj::HttpHeaders(headerTable)).response.wait(ioContext->waitScope).body
->readAllText().wait(ioContext->waitScope);
return { res.getResult(), kj::mv(log) };
}
kj::String stripLaminarLogLines(const kj::String& str) {
auto out = kj::heapString(str.size());
char *o = out.begin();
for(const char *p = str.cStr(), *e = p + str.size(); p < e;) {
const char *nl = strchrnul(p, '\n');
if(!kj::StringPtr{p}.startsWith("[laminar]")) {
memcpy(o, p, nl - p + 1);
o += nl - p + 1;
}
p = nl + 1;
}
*o = '\0';
return out;
}
StringMap parseFromString(kj::StringPtr content) {
char tmp[16] = "/tmp/lt.XXXXXX";
int fd = mkstemp(tmp);
write(fd, content.begin(), content.size());
close(fd);
StringMap map = parseConfFile(tmp);
unlink(tmp);
return map;
}
LaminarCi::Client client() {
if(!rpc) {
auto stream = ioContext.provider->getNetwork().parseAddress(bind_rpc).wait(ioContext.waitScope)->connect().wait(ioContext.waitScope);
auto stream = ioContext->provider->getNetwork().parseAddress(bind_rpc).wait(ioContext->waitScope)->connect().wait(ioContext->waitScope);
auto net = kj::heap<capnp::TwoPartyVatNetwork>(*stream, capnp::rpc::twoparty::Side::CLIENT);
rpc = kj::heap<capnp::RpcSystem<capnp::rpc::twoparty::VatId>>(*net, nullptr).attach(kj::mv(net), kj::mv(stream));
}
@@ -76,7 +129,7 @@ public:
Settings settings;
Server* server;
Laminar* laminar;
static kj::AsyncIoContext ioContext;
static kj::AsyncIoContext* ioContext;
};
#endif // LAMINAR_FIXTURE_H_