display run number for queued jobs

in the frontend and in laminarc queue/show-queued. This makes
it much easier to abort/unqueue runs which have not yet started.

resolves #155
pull/167/head
Oliver Giles 2 years ago
parent 549f49052a
commit e1686d454b

@ -1,5 +1,5 @@
/// ///
/// Copyright 2015-2020 Oliver Giles /// Copyright 2015-2021 Oliver Giles
/// ///
/// This file is part of Laminar /// This file is part of Laminar
/// ///
@ -233,7 +233,7 @@ int main(int argc, char** argv) {
} }
auto queued = laminar.listQueuedRequest().send().wait(waitScope); auto queued = laminar.listQueuedRequest().send().wait(waitScope);
for(auto it : queued.getResult()) { for(auto it : queued.getResult()) {
printf("%s\n", it.cStr()); printf("%s:%d\n", it.getJob().cStr(), it.getBuildNum());
} }
} else if(strcmp(argv[1], "show-running") == 0) { } else if(strcmp(argv[1], "show-running") == 0) {
if(argc != 2) { if(argc != 2) {

@ -5,7 +5,7 @@ interface LaminarCi {
queue @0 (jobName :Text, params :List(JobParam)) -> (result :MethodResult, buildNum :UInt32); queue @0 (jobName :Text, params :List(JobParam)) -> (result :MethodResult, buildNum :UInt32);
start @1 (jobName :Text, params :List(JobParam)) -> (result :MethodResult, buildNum :UInt32); start @1 (jobName :Text, params :List(JobParam)) -> (result :MethodResult, buildNum :UInt32);
run @2 (jobName :Text, params :List(JobParam)) -> (result :JobResult, buildNum :UInt32); run @2 (jobName :Text, params :List(JobParam)) -> (result :JobResult, buildNum :UInt32);
listQueued @3 () -> (result :List(Text)); listQueued @3 () -> (result :List(Run));
listRunning @4 () -> (result :List(Run)); listRunning @4 () -> (result :List(Run));
listKnown @5 () -> (result :List(Text)); listKnown @5 () -> (result :List(Text));
abort @6 (run :Run) -> (result :MethodResult); abort @6 (run :Run) -> (result :MethodResult);

@ -306,13 +306,17 @@ std::string Laminar::getStatus(MonitorScope scope) {
j.EndObject(); j.EndObject();
} }
j.EndArray(); j.EndArray();
int nQueued = 0; j.startArray("queued");
for(const auto& run : queuedJobs) { for(const auto& run : queuedJobs) {
if (run->name == scope.job) { if (run->name == scope.job) {
nQueued++; j.StartObject();
j.set("number", run->build);
j.set("result", to_string(RunState::QUEUED));
j.set("reason", run->reason());
j.EndObject();
} }
} }
j.set("nQueued", nQueued); j.EndArray();
db->stmt("SELECT number,startedAt FROM builds WHERE name = ? AND result = ? " db->stmt("SELECT number,startedAt FROM builds WHERE name = ? AND result = ? "
"ORDER BY completedAt DESC LIMIT 1") "ORDER BY completedAt DESC LIMIT 1")
.bind(scope.job, int(RunState::SUCCESS)) .bind(scope.job, int(RunState::SUCCESS))
@ -399,6 +403,8 @@ std::string Laminar::getStatus(MonitorScope scope) {
for(const auto& run : queuedJobs) { for(const auto& run : queuedJobs) {
j.StartObject(); j.StartObject();
j.set("name", run->name); j.set("name", run->name);
j.set("number", run->build);
j.set("result", to_string(RunState::QUEUED));
j.EndObject(); j.EndObject();
} }
j.EndArray(); j.EndArray();
@ -602,6 +608,8 @@ std::shared_ptr<Run> Laminar::queueJob(std::string name, ParamMap params) {
.startObject("data") .startObject("data")
.set("name", name) .set("name", name)
.set("number", run->build) .set("number", run->build)
.set("result", to_string(RunState::QUEUED))
.set("reason", run->reason())
.EndObject(); .EndObject();
http->notifyEvent(j.str(), name.c_str()); http->notifyEvent(j.str(), name.c_str());

@ -22,7 +22,12 @@
<nav> <nav>
<table class="table striped"> <table class="table striped">
<tr v-for="job in jobsQueued"> <tr v-for="job in jobsQueued">
<td><router-link :to="'jobs/'+job.name">{{job.name}}</router-link> <i>queued</i></td> <td>
<span v-html="runIcon(job.result)"></span>
<router-link :to="'jobs/'+job.name">{{job.name}}</router-link>
<router-link :to="'jobs/'+job.name+'/'+job.number">#{{job.number}}</router-link>
<i>queued</i>
</td>
</tr> </tr>
<tr v-for="job in jobsRunning"> <tr v-for="job in jobsRunning">
<td> <td>
@ -134,15 +139,11 @@
<th class="text-center">Duration <a class="sort" :class="(sort.field=='duration'?sort.order:'')" v-on:click="do_sort('duration')">&nbsp;</a></th> <th class="text-center">Duration <a class="sort" :class="(sort.field=='duration'?sort.order:'')" v-on:click="do_sort('duration')">&nbsp;</a></th>
<th class="text-center vp-sm-hide">Reason <a class="sort" :class="(sort.field=='reason'?sort.order:'')" v-on:click="do_sort('reason')">&nbsp;</a></th> <th class="text-center vp-sm-hide">Reason <a class="sort" :class="(sort.field=='reason'?sort.order:'')" v-on:click="do_sort('reason')">&nbsp;</a></th>
</tr></thead> </tr></thead>
<tr v-show="nQueued"> <tr v-for="job in jobsQueued.concat(jobsRunning).concat(jobsRecent)" track-by="$index">
<td style="width:1px"><span v-html="runIcon('queued')"></span></td>
<td colspan="4"><i>{{nQueued}} run(s) queued</i></td>
</tr>
<tr v-for="job in jobsRunning.concat(jobsRecent)" track-by="$index">
<td style="width:1px"><span v-html="runIcon(job.result)"></span></td> <td style="width:1px"><span v-html="runIcon(job.result)"></span></td>
<td><router-link :to="'jobs/'+route.params.name+'/'+job.number">#{{job.number}}</router-link></td> <td><router-link :to="'jobs/'+route.params.name+'/'+job.number">#{{job.number}}</router-link></td>
<td class="text-center">{{formatDate(job.started)}}</td> <td class="text-center"><span v-if="job.result!='queued'">{{formatDate(job.started)}}</span></td>
<td class="text-center">{{formatDuration(job.started, job.completed)}}</td> <td class="text-center"><span v-if="job.result!='queued'">{{formatDuration(job.started, job.completed)}}</span></td>
<td class="text-center vp-sm-hide">{{job.reason}}</td> <td class="text-center vp-sm-hide">{{job.reason}}</td>
</tr> </tr>
</table> </table>

@ -397,8 +397,8 @@ const Home = templateId => {
data: () => state, data: () => state,
methods: { methods: {
status: function(msg) { status: function(msg) {
state.jobsQueued = msg.queued; state.jobsQueued = msg.queued.reverse();
state.jobsRunning = msg.running; state.jobsRunning = msg.running.reverse();
state.jobsRecent = msg.recent; state.jobsRecent = msg.recent;
state.resultChanged = msg.resultChanged; state.resultChanged = msg.resultChanged;
state.lowPassRates = msg.lowPassRates; state.lowPassRates = msg.lowPassRates;
@ -559,11 +559,11 @@ const All = templateId => {
const Job = templateId => { const Job = templateId => {
const state = { const state = {
description: '', description: '',
jobsQueued: [],
jobsRunning: [], jobsRunning: [],
jobsRecent: [], jobsRecent: [],
lastSuccess: null, lastSuccess: null,
lastFailed: null, lastFailed: null,
nQueued: 0,
pages: 0, pages: 0,
sort: {} sort: {}
}; };
@ -575,11 +575,11 @@ const Job = templateId => {
methods: { methods: {
status: function(msg) { status: function(msg) {
state.description = msg.description; state.description = msg.description;
state.jobsRunning = msg.running; state.jobsQueued = msg.queued.reverse();
state.jobsRunning = msg.running.reverse();
state.jobsRecent = msg.recent; state.jobsRecent = msg.recent;
state.lastSuccess = msg.lastSuccess; state.lastSuccess = msg.lastSuccess;
state.lastFailed = msg.lastFailed; state.lastFailed = msg.lastFailed;
state.nQueued = msg.nQueued;
state.pages = msg.pages; state.pages = msg.pages;
state.sort = msg.sort; state.sort = msg.sort;
@ -593,11 +593,12 @@ const Job = templateId => {
chtBuildTime = Charts.createRunTimeChart("chartBt", msg.recent, msg.averageRuntime); chtBuildTime = Charts.createRunTimeChart("chartBt", msg.recent, msg.averageRuntime);
}); });
}, },
job_queued: function() { job_queued: function(data) {
state.nQueued++; state.jobsQueued.splice(0, 0, data);
this.$forceUpdate();
}, },
job_started: function(data) { job_started: function(data) {
state.nQueued--; state.jobsQueued.splice(state.jobsQueued.length - data.queueIndex - 1, 1);
state.jobsRunning.splice(0, 0, data); state.jobsRunning.splice(0, 0, data);
this.$forceUpdate(); this.$forceUpdate();
}, },

@ -101,7 +101,9 @@ public:
auto res = context.getResults().initResult(queue.size()); auto res = context.getResults().initResult(queue.size());
int i = 0; int i = 0;
for(auto it : queue) { for(auto it : queue) {
res.set(i++, it->name); res[i].setJob(it->name);
res[i].setBuildNum(it->build);
i++;
} }
return kj::READY_NOW; return kj::READY_NOW;
} }

Loading…
Cancel
Save