aboutsummaryrefslogtreecommitdiff
path: root/mod
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2024-03-29 21:13:23 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2024-04-01 17:45:55 +0300
commit6cb77d97d659441036fac18af6479eeac4127dcb (patch)
tree47e43d9919a0b90b45e76da1f46e0b736e1a3633 /mod
parent2b5bea3871d0ccc1b7da32929f195dc161bcc1ec (diff)
Stash build toolchain in tenant object
Diffstat (limited to 'mod')
-rw-r--r--mod/mod-build-task.cxx93
-rw-r--r--mod/mod-builds.cxx29
-rw-r--r--mod/page.cxx14
-rw-r--r--mod/page.hxx13
4 files changed, 112 insertions, 37 deletions
diff --git a/mod/mod-build-task.cxx b/mod/mod-build-task.cxx
index e2f69f7..773d041 100644
--- a/mod/mod-build-task.cxx
+++ b/mod/mod-build-task.cxx
@@ -231,7 +231,7 @@ handle (request& rq, response& rs)
// The resulting task manifest and the related build, package, and
// configuration objects. Note that the latter 3 are only meaningful if the
- // session in the task manifest is not empty.
+ // the task manifest is present.
//
task_response_manifest task_response;
shared_ptr<build> task_build;
@@ -1344,9 +1344,9 @@ handle (request& rq, response& rs)
//
bool unforced (true);
- for (bool done (false); task_response.session.empty () && !done; )
+ for (bool done (false); !task_response.task && !done; )
{
- transaction t (conn->begin ());
+ transaction tr (conn->begin ());
// We need to be careful in the random package ordering mode not to
// miss the end after having wrapped around.
@@ -1381,7 +1381,7 @@ handle (request& rq, response& rs)
//
if (chunk_size == 0)
{
- t.commit ();
+ tr.commit ();
if (start_offset != 0 && offset >= start_offset)
offset = 0;
@@ -1398,12 +1398,24 @@ handle (request& rq, response& rs)
// to bail out in the random package ordering mode for some reason (no
// more untried positions, need to restart, etc).
//
+ // Note that it is not uncommon for the sequentially examined packages
+ // to belong to the same tenant (single tenant mode, etc). Thus, we
+ // will cache the loaded tenant objects.
+ //
+ shared_ptr<build_tenant> t;
+
for (auto& bp: packages)
{
shared_ptr<build_package>& p (bp.package);
id = p->id;
+ // Reset the tenant cache if the current package belongs to a
+ // different tenant.
+ //
+ if (t != nullptr && t->id != id.tenant)
+ t = nullptr;
+
// If we are in the random package ordering mode, then cache the
// tenant the start offset refers to, if not cached yet, and check
// if we are still iterating over packages from this tenant
@@ -1463,8 +1475,6 @@ handle (request& rq, response& rs)
//
if (bp.interactive)
{
- shared_ptr<build_tenant> t;
-
// Note that the tenant can be archived via some other package on
// some previous iteration. Skip the package if that's the case.
//
@@ -1473,7 +1483,9 @@ handle (request& rq, response& rs)
//
if (!bp.archived)
{
- t = build_db_->load<build_tenant> (id.tenant);
+ if (t == nullptr)
+ t = build_db_->load<build_tenant> (id.tenant);
+
bp.archived = t->archived;
}
@@ -1583,6 +1595,14 @@ handle (request& rq, response& rs)
}
}
+ // If true, then the package is (being) built for some
+ // configurations.
+ //
+ // Note that since we only query the built and forced rebuild
+ // objects there can be false negatives.
+ //
+ bool package_built (false);
+
for (const build_package_config& pc: p->configs)
{
pkg_config = pc.name;
@@ -1597,6 +1617,9 @@ handle (request& rq, response& rs)
config_machines configs (conf_machines); // Make copy for this pkg.
auto pkg_builds (bld_prep_query.execute ());
+ if (!package_built && !pkg_builds.empty ())
+ package_built = true;
+
for (auto i (pkg_builds.begin ()); i != pkg_builds.end (); ++i)
{
auto j (
@@ -1750,8 +1773,8 @@ handle (request& rq, response& rs)
build_db_->update (b);
}
- shared_ptr<build_tenant> t (
- build_db_->load<build_tenant> (b->tenant));
+ if (t == nullptr)
+ t = build_db_->load<build_tenant> (b->tenant);
// Archive an interactive tenant.
//
@@ -1798,7 +1821,7 @@ handle (request& rq, response& rs)
}
if (tsb != nullptr || tsq != nullptr)
- tss = make_pair (move (*t->service), b);
+ tss = make_pair (*t->service, b);
}
}
@@ -1814,25 +1837,51 @@ handle (request& rq, response& rs)
task_package = move (p);
task_config = &pc;
+ package_built = true;
+
break; // Bail out from the package configurations loop.
}
}
}
- // If the task response manifest is prepared, then bail out from the
- // package loop, commit the transaction and respond.
+ // If the task manifest is prepared, then bail out from the package
+ // loop, commit the transaction and respond. Otherwise, stash the
+ // build toolchain into the tenant, unless it is already stashed or
+ // the current package already has some configurations (being)
+ // built.
//
- if (!task_response.session.empty ())
+ if (!task_response.task)
+ {
+ // Note that since there can be false negatives for the
+ // package_built flag (see above), there can be redundant tenant
+ // queries which, however, seems harmless (query uses the primary
+ // key and the object memory footprint is small).
+ //
+ if (!package_built)
+ {
+ if (t == nullptr)
+ t = build_db_->load<build_tenant> (p->id.tenant);
+
+ if (!t->toolchain)
+ {
+ t->toolchain = build_toolchain {toolchain_name,
+ toolchain_version};
+
+ build_db_->update (t);
+ }
+ }
+ }
+ else
break;
}
- t.commit ();
+ tr.commit ();
}
// If we don't have an unbuilt package, then let's see if we have a
// build configuration to rebuild.
//
- if (task_response.session.empty () && !rebuilds.empty ())
+ if (!task_response.task && !rebuilds.empty ())
{
// Sort the configuration rebuild list with the following sort
// priority:
@@ -2047,15 +2096,15 @@ handle (request& rq, response& rs)
catch (const odb::deadlock&)
{
// Just try with the next rebuild. But first, reset the task
- // response manifest that we may have prepared.
+ // manifest and the session that we may have prepared.
//
task_response = task_response_manifest ();
}
- // If the task response manifest is prepared, then bail out from the
- // package configuration rebuilds loop and respond.
+ // If the task manifest is prepared, then bail out from the package
+ // configuration rebuilds loop and respond.
//
- if (!task_response.session.empty ())
+ if (task_response.task)
break;
}
}
@@ -2135,9 +2184,9 @@ handle (request& rq, response& rs)
update_tenant_service_state (conn, b.tenant, f);
}
- // If the task response manifest is prepared, then check that the number
- // of the build auxiliary machines is less than 10. If that's not the
- // case, then turn the build into the built state with the abort status.
+ // If the task manifest is prepared, then check that the number of the
+ // build auxiliary machines is less than 10. If that's not the case,
+ // then turn the build into the built state with the abort status.
//
if (task_response.task &&
task_response.task->auxiliary_machines.size () > 9)
diff --git a/mod/mod-builds.cxx b/mod/mod-builds.cxx
index b0de618..30562f3 100644
--- a/mod/mod-builds.cxx
+++ b/mod/mod-builds.cxx
@@ -393,8 +393,11 @@ handle (request& rq, response& rs)
if (!tenant.empty ())
tn = tenant;
- // Return the list of distinct toolchain name/version pairs. The build db
- // transaction must be started.
+ // Return the list of distinct toolchain name/version pairs. If no builds
+ // are present for the tenant, then fallback to the toolchain recorded in
+ // the tenant object, if present.
+ //
+ // Note: the build db transaction must be started.
//
using toolchains = vector<pair<string, version>>;
@@ -410,11 +413,19 @@ handle (request& rq, response& rs)
false /* first */)))
r.emplace_back (move (t.name), move (t.version));
+ if (r.empty ())
+ {
+ shared_ptr<build_tenant> t (build_db_->find<build_tenant> (tenant));
+
+ if (t != nullptr && t->toolchain)
+ r.emplace_back (t->toolchain->name, t->toolchain->version);
+ }
+
return r;
};
auto print_form = [&s, &params, this] (const toolchains& toolchains,
- size_t build_count)
+ optional<size_t> build_count)
{
// Print the package builds filter form on the first page only.
//
@@ -525,7 +536,7 @@ handle (request& rq, response& rs)
conf_ids.push_back (c.first);
}
- size_t count;
+ optional<size_t> count;
size_t page (params.page ());
if (params.result () != "unbuilt") // Print package build configurations.
@@ -656,7 +667,7 @@ handle (request& rq, response& rs)
--print;
}
- ++count;
+ ++(*count);
}
}
@@ -937,7 +948,7 @@ handle (request& rq, response& rs)
count = npos - ncur;
}
else
- count = 0;
+ count = nullopt; // Unknown count.
}
// Print the filter form.
@@ -1148,7 +1159,11 @@ handle (request& rq, response& rs)
add_filter ("pc", pkg_cfg);
add_filter ("rs", params.result (), "*");
- s << DIV_PAGER (page, count, page_configs, options_->build_pages (), u)
+ s << DIV_PAGER (page,
+ count ? *count : 0,
+ page_configs,
+ options_->build_pages (),
+ u)
<< ~DIV
<< ~BODY
<< ~HTML;
diff --git a/mod/page.cxx b/mod/page.cxx
index 5483183..bc2e42d 100644
--- a/mod/page.cxx
+++ b/mod/page.cxx
@@ -137,9 +137,17 @@ namespace brep
void DIV_COUNTER::
operator() (serializer& s) const
{
- s << DIV(ID="count")
- << count_ << " "
- << (count_ % 10 == 1 && count_ % 100 != 11 ? singular_ : plural_)
+ s << DIV(ID="count");
+
+ if (count_)
+ s << *count_;
+ else
+ s << '?';
+
+ s << ' '
+ << (count_ && *count_ % 10 == 1 && *count_ % 100 != 11
+ ? singular_
+ : plural_)
<< ~DIV;
}
diff --git a/mod/page.hxx b/mod/page.hxx
index cac2b8b..7329e2d 100644
--- a/mod/page.hxx
+++ b/mod/page.hxx
@@ -82,21 +82,24 @@ namespace brep
// Generate counter element.
//
- // It could be redunant to distinguish between singular and plural word forms
- // if it wouldn't be so cheap in English, and phrase '1 Packages' wouldn't
- // look that ugly.
+ // If the count argument is nullopt, then it is assumed that the count is
+ // unknown and the '?' character is printed instead of the number.
+ //
+ // Note that it could be redunant to distinguish between singular and plural
+ // word forms if it wouldn't be so cheap in English, and phrase '1 Packages'
+ // wouldn't look that ugly.
//
class DIV_COUNTER
{
public:
- DIV_COUNTER (size_t c, const char* s, const char* p)
+ DIV_COUNTER (optional<size_t> c, const char* s, const char* p)
: count_ (c), singular_ (s), plural_ (p) {}
void
operator() (xml::serializer&) const;
private:
- size_t count_;
+ optional<size_t> count_;
const char* singular_;
const char* plural_;
};