forked from lix-project/hydra
Load the queue in order of global priority
This commit is contained in:
parent
97f11baa8d
commit
b7965df928
|
@ -59,12 +59,17 @@ void State::getQueuedBuilds(Connection & conn, std::shared_ptr<StoreAPI> store,
|
||||||
|
|
||||||
/* Grab the queued builds from the database, but don't process
|
/* Grab the queued builds from the database, but don't process
|
||||||
them yet (since we don't want a long-running transaction). */
|
them yet (since we don't want a long-running transaction). */
|
||||||
std::multimap<Path, Build::ptr> newBuilds;
|
std::vector<BuildID> newIDs;
|
||||||
|
std::map<BuildID, Build::ptr> newBuildsByID;
|
||||||
|
std::multimap<Path, BuildID> newBuildsByPath;
|
||||||
|
|
||||||
{
|
{
|
||||||
pqxx::work txn(conn);
|
pqxx::work txn(conn);
|
||||||
|
|
||||||
auto res = txn.parameterized("select id, project, jobset, job, drvPath, maxsilent, timeout, timestamp, globalPriority from Builds where id > $1 and finished = 0 order by id")(lastBuildId).exec();
|
auto res = txn.parameterized
|
||||||
|
("select id, project, jobset, job, drvPath, maxsilent, timeout, timestamp, globalPriority from Builds "
|
||||||
|
"where id > $1 and finished = 0 order by globalPriority desc, id")
|
||||||
|
(lastBuildId).exec();
|
||||||
|
|
||||||
for (auto const & row : res) {
|
for (auto const & row : res) {
|
||||||
auto builds_(builds.lock());
|
auto builds_(builds.lock());
|
||||||
|
@ -85,7 +90,9 @@ void State::getQueuedBuilds(Connection & conn, std::shared_ptr<StoreAPI> store,
|
||||||
build->globalPriority = row["globalPriority"].as<int>();
|
build->globalPriority = row["globalPriority"].as<int>();
|
||||||
build->jobset = createJobset(txn, build->projectName, build->jobsetName);
|
build->jobset = createJobset(txn, build->projectName, build->jobsetName);
|
||||||
|
|
||||||
newBuilds.emplace(std::make_pair(build->drvPath, build));
|
newIDs.push_back(id);
|
||||||
|
newBuildsByID[id] = build;
|
||||||
|
newBuildsByPath.emplace(std::make_pair(build->drvPath, id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +103,7 @@ void State::getQueuedBuilds(Connection & conn, std::shared_ptr<StoreAPI> store,
|
||||||
createBuild = [&](Build::ptr build) {
|
createBuild = [&](Build::ptr build) {
|
||||||
printMsg(lvlTalkative, format("loading build %1% (%2%)") % build->id % build->fullJobName());
|
printMsg(lvlTalkative, format("loading build %1% (%2%)") % build->id % build->fullJobName());
|
||||||
nrAdded++;
|
nrAdded++;
|
||||||
|
newBuildsByID.erase(build->id);
|
||||||
|
|
||||||
if (!store->isValidPath(build->drvPath)) {
|
if (!store->isValidPath(build->drvPath)) {
|
||||||
/* Derivation has been GC'ed prematurely. */
|
/* Derivation has been GC'ed prematurely. */
|
||||||
|
@ -124,13 +132,11 @@ void State::getQueuedBuilds(Connection & conn, std::shared_ptr<StoreAPI> store,
|
||||||
if build A depends on build B with top-level step X, then X
|
if build A depends on build B with top-level step X, then X
|
||||||
will be "accounted" to B in doBuildStep(). */
|
will be "accounted" to B in doBuildStep(). */
|
||||||
for (auto & r : newSteps) {
|
for (auto & r : newSteps) {
|
||||||
while (true) {
|
auto i = newBuildsByPath.find(r->drvPath);
|
||||||
auto i = newBuilds.find(r->drvPath);
|
if (i == newBuildsByPath.end()) continue;
|
||||||
if (i == newBuilds.end()) break;
|
auto j = newBuildsByID.find(i->second);
|
||||||
Build::ptr b = i->second;
|
if (j == newBuildsByID.end()) continue;
|
||||||
newBuilds.erase(i);
|
createBuild(j->second);
|
||||||
createBuild(b);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we didn't get a step, it means the step's outputs are
|
/* If we didn't get a step, it means the step's outputs are
|
||||||
|
@ -219,9 +225,10 @@ void State::getQueuedBuilds(Connection & conn, std::shared_ptr<StoreAPI> store,
|
||||||
/* Now instantiate build steps for each new build. The builder
|
/* Now instantiate build steps for each new build. The builder
|
||||||
threads can start building the runnable build steps right away,
|
threads can start building the runnable build steps right away,
|
||||||
even while we're still processing other new builds. */
|
even while we're still processing other new builds. */
|
||||||
while (!newBuilds.empty()) {
|
for (auto id : newIDs) {
|
||||||
auto build = newBuilds.begin()->second;
|
auto i = newBuildsByID.find(id);
|
||||||
newBuilds.erase(newBuilds.begin());
|
if (i == newBuildsByID.end()) continue;
|
||||||
|
auto build = i->second;
|
||||||
|
|
||||||
newRunnable.clear();
|
newRunnable.clear();
|
||||||
nrAdded = 0;
|
nrAdded = 0;
|
||||||
|
|
Loading…
Reference in a new issue