mirror of
https://github.com/ohwgiles/laminar.git
synced 2026-10-18 09:04:42 +00:00
refactor: remove transport knowledge from Laminar class
Improve the boundary between RpcImpl and LaminarInterface such that the Laminar class doesn't require any types from kj/async.h. The necessary logic moved from Laminar to RpcImpl and the notification now happens by abstract virtual callback instead of kj::Promise. Also remove the fairly useless 'wait' RPC call and drop the wrappers around kj::PromiseFulfillerPair
This commit is contained in:
@@ -74,24 +74,17 @@ LaminarCi::JobResult fromRunState(RunState state) {
|
||||
// This is the implementation of the Laminar Cap'n Proto RPC interface.
|
||||
// As such, it implements the pure virtual interface generated from
|
||||
// laminar.capnp with calls to the LaminarInterface
|
||||
class RpcImpl : public LaminarCi::Server {
|
||||
private:
|
||||
struct Lock {
|
||||
Lock() : paf(kj::newPromiseAndFulfiller<void>()) {}
|
||||
void release() {
|
||||
paf.fulfiller->fulfill();
|
||||
}
|
||||
kj::Promise<void> takePromise() { return std::move(paf.promise); }
|
||||
private:
|
||||
kj::PromiseFulfillerPair<void> paf;
|
||||
};
|
||||
|
||||
|
||||
class RpcImpl : public LaminarCi::Server, public LaminarWaiter {
|
||||
public:
|
||||
RpcImpl(LaminarInterface& l) :
|
||||
LaminarCi::Server(),
|
||||
laminar(l)
|
||||
{
|
||||
laminar.registerWaiter(this);
|
||||
}
|
||||
|
||||
~RpcImpl() {
|
||||
laminar.deregisterWaiter(this);
|
||||
}
|
||||
|
||||
// Start a job, without waiting for it to finish
|
||||
@@ -118,8 +111,9 @@ public:
|
||||
params[p.getName().cStr()] = p.getValue().cStr();
|
||||
}
|
||||
std::shared_ptr<Run> run = laminar.queueJob(jobName, params);
|
||||
if(run.get()) {
|
||||
return laminar.waitForRun(run.get()).then([context](RunState state) mutable {
|
||||
if(const Run* r = run.get()) {
|
||||
runWaiters[r].emplace_back(kj::newPromiseAndFulfiller<RunState>());
|
||||
return runWaiters[r].back().promise.then([context](RunState state) mutable {
|
||||
context.getResults().setResult(fromRunState(state));
|
||||
});
|
||||
} else {
|
||||
@@ -128,19 +122,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for an already-running job to complete, returning the result
|
||||
kj::Promise<void> pend(PendContext context) override {
|
||||
std::string jobName = context.getParams().getJobName();
|
||||
int buildNum = context.getParams().getBuildNum();
|
||||
LLOG(INFO, "RPC pend", jobName, buildNum);
|
||||
|
||||
kj::Promise<RunState> promise = laminar.waitForRun(jobName, buildNum);
|
||||
|
||||
return promise.then([context](RunState state) mutable {
|
||||
context.getResults().setResult(fromRunState(state));
|
||||
});
|
||||
}
|
||||
|
||||
// Set a parameter on a running build
|
||||
kj::Promise<void> set(SetContext context) override {
|
||||
std::string jobName = context.getParams().getJobName();
|
||||
@@ -160,10 +141,10 @@ public:
|
||||
std::string lockName = context.getParams().getLockName();
|
||||
LLOG(INFO, "RPC lock", lockName);
|
||||
auto& lockList = locks[lockName];
|
||||
lockList.emplace_back(Lock{});
|
||||
lockList.emplace_back(kj::newPromiseAndFulfiller<void>());
|
||||
if(lockList.size() == 1)
|
||||
lockList.front().release();
|
||||
return lockList.back().takePromise();
|
||||
lockList.front().fulfiller->fulfill();
|
||||
return std::move(lockList.back().promise);
|
||||
}
|
||||
|
||||
// Release a named lock
|
||||
@@ -177,14 +158,21 @@ public:
|
||||
}
|
||||
lockList.erase(lockList.begin());
|
||||
if(lockList.size() > 0)
|
||||
lockList.front().release();
|
||||
lockList.front().fulfiller->fulfill();
|
||||
return kj::READY_NOW;
|
||||
}
|
||||
|
||||
private:
|
||||
// Implements LaminarWaiter::complete
|
||||
void complete(const Run* r) override {
|
||||
for(kj::PromiseFulfillerPair<RunState>& w : runWaiters[r])
|
||||
w.fulfiller->fulfill(RunState(r->result));
|
||||
runWaiters.erase(r);
|
||||
}
|
||||
private:
|
||||
LaminarInterface& laminar;
|
||||
kj::LowLevelAsyncIoProvider* asyncio;
|
||||
std::unordered_map<std::string, std::list<Lock>> locks;
|
||||
std::unordered_map<std::string, std::list<kj::PromiseFulfillerPair<void>>> locks;
|
||||
std::unordered_map<const Run*, std::list<kj::PromiseFulfillerPair<RunState>>> runWaiters;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user