aboutsummaryrefslogtreecommitdiff
path: root/mod/mod-build-task.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'mod/mod-build-task.cxx')
-rw-r--r--mod/mod-build-task.cxx302
1 files changed, 131 insertions, 171 deletions
diff --git a/mod/mod-build-task.cxx b/mod/mod-build-task.cxx
index 86acbf6..1a7b272 100644
--- a/mod/mod-build-task.cxx
+++ b/mod/mod-build-task.cxx
@@ -27,8 +27,8 @@
#include <libbrep/build.hxx>
#include <libbrep/build-odb.hxx>
-#include <libbrep/package.hxx>
-#include <libbrep/package-odb.hxx>
+#include <libbrep/build-package.hxx>
+#include <libbrep/build-package-odb.hxx>
#include <mod/options.hxx>
@@ -57,9 +57,6 @@ init (scanner& s)
options_ = make_shared<options::build_task> (
s, unknown_mode::fail, unknown_mode::fail);
- database_module::init (static_cast<options::package_db> (*options_),
- options_->package_db_retry ());
-
if (options_->build_config_specified ())
{
database_module::init (static_cast<options::build> (*options_),
@@ -165,7 +162,7 @@ handle (request& rq, response& rs)
//
// While trying to find a non-built package configuration we will also
// collect the list of the built package configurations which it's time to
- // rebuilt. So if no unbuilt package is found, we will pickup one to
+ // rebuild. So if no unbuilt package is found, we will pickup one to
// rebuild. The rebuild preference is given in the following order: the
// greater force state, the greater overall status, the lower timestamp.
//
@@ -177,7 +174,7 @@ handle (request& rq, response& rs)
// repository loaded.
//
auto task = [this] (shared_ptr<build>&& b,
- shared_ptr<package>&& p,
+ shared_ptr<build_package>&& p,
const config_machine& cm) -> task_response_manifest
{
uint64_t ts (
@@ -192,11 +189,11 @@ handle (request& rq, response& rs)
string result_url (options_->host () + options_->root ().string () +
"?build-result");
- lazy_shared_ptr<repository> r (p->internal_repository);
+ lazy_shared_ptr<build_repository> r (p->internal_repository);
strings fp;
- if (r->certificate)
- fp.emplace_back (move (r->certificate->fingerprint));
+ if (r->certificate_fingerprint)
+ fp.emplace_back (move (*r->certificate_fingerprint));
task_manifest task (move (b->package_name),
move (b->package_version),
@@ -302,7 +299,7 @@ handle (request& rq, response& rs)
//
brep::version toolchain_version (tqm.toolchain_version.string ());
- // Prepare the package version prepared query.
+ // Prepare the buildable package prepared query.
//
// Note that the number of packages can be large and so, in order not to
// hold locks for too long, we will restrict the number of packages being
@@ -314,41 +311,36 @@ handle (request& rq, response& rs)
// harmful in that: updates are infrequent and missed packages will be
// picked up on the next request.
//
- using pkg_query = query<package_version>;
- using prep_pkg_query = prepared_query<package_version>;
-
- size_t offset (0); // See the package version query.
+ using pkg_query = query<buildable_package>;
+ using prep_pkg_query = prepared_query<buildable_package>;
- // Skip external and stub packages.
- //
- pkg_query pq (pkg_query::package::internal_repository.is_not_null () &&
- compare_version_ne (pkg_query::package::id.version,
- wildcard_version,
- false));
+ pkg_query pq (true);
- // Filter by repositories display names (if requested).
+ // Filter by repositories canonical names (if requested).
//
const vector<string>& rp (params.repository ());
if (!rp.empty ())
pq = pq &&
- pkg_query::repository::display_name.in_range (rp.begin (), rp.end ());
+ pkg_query::build_repository::name.in_range (rp.begin (), rp.end ());
// Specify the portion.
//
+ size_t offset (0);
+
pq += "ORDER BY" +
- pkg_query::package::id.name + "," +
- pkg_query::package::id.version.epoch + "," +
- pkg_query::package::id.version.canonical_upstream + "," +
- pkg_query::package::id.version.canonical_release + "," +
- pkg_query::package::id.version.revision +
+ pkg_query::build_package::id.name + "," +
+ pkg_query::build_package::id.version.epoch + "," +
+ pkg_query::build_package::id.version.canonical_upstream + "," +
+ pkg_query::build_package::id.version.canonical_release + "," +
+ pkg_query::build_package::id.version.revision +
"OFFSET" + pkg_query::_ref (offset) + "LIMIT 50";
- connection_ptr pkg_conn (package_db_->connection ());
+ connection_ptr conn (build_db_->connection ());
prep_pkg_query pkg_prep_query (
- pkg_conn->prepare_query<package_version> (
- "mod-build-task-package-version-query", pq));
+ conn->prepare_query<buildable_package> (
+ "mod-build-task-package-query", pq));
// Prepare the build prepared query.
//
@@ -364,8 +356,7 @@ handle (request& rq, response& rs)
using bld_query = query<build>;
using prep_bld_query = prepared_query<build>;
- package_id id; // See the build query.
-
+ package_id id;
const auto& qv (bld_query::id.package.version);
bld_query bq (
@@ -390,169 +381,147 @@ handle (request& rq, response& rs)
(bld_query::force != "forcing" && // Unforced or forced.
bld_query::timestamp > normal_result_expiration_ns))));
- connection_ptr bld_conn (build_db_->connection ());
-
prep_bld_query bld_prep_query (
- bld_conn->prepare_query<build> (
- "mod-build-task-package-build-query", bq));
+ conn->prepare_query<build> ("mod-build-task-build-query", bq));
while (tsm.session.empty ())
{
- // Start the package database transaction.
- //
- transaction pt (pkg_conn->begin ());
+ transaction t (conn->begin ());
- // Query package versions.
+ // Query (and cache) buildable packages.
//
- auto package_versions (pkg_prep_query.execute ());
+ auto packages (pkg_prep_query.execute ());
// Bail out if there is nothing left.
//
- if (package_versions.empty ())
+ if (packages.empty ())
{
- pt.commit ();
+ t.commit ();
break;
}
- offset += package_versions.size ();
+ offset += packages.size ();
- // Start the build database transaction.
+ // Iterate over packages until we find one that needs building.
//
+ for (auto& bp: packages)
{
- transaction bt (bld_conn->begin (), false);
- transaction::current (bt);
+ id = move (bp.id);
- // Iterate over packages until we find one that needs building.
+ // Iterate through the package configurations and erase those that
+ // don't need building from the build configuration map. All those
+ // configurations that remained can be built. We will take the first
+ // one, if present.
//
- for (auto& pv: package_versions)
+ // Also save the built package configurations for which it's time to be
+ // rebuilt.
+ //
+ config_machines configs (cfg_machines); // Make a copy for this pkg.
+ auto pkg_builds (bld_prep_query.execute ());
+
+ for (auto i (pkg_builds.begin ()); i != pkg_builds.end (); ++i)
{
- id = move (pv.id);
+ auto j (configs.find (i->id.configuration.c_str ()));
- // Iterate through the package configurations and erase those that
- // don't need building from the build configuration map. All those
- // configurations that remained can be built. We will take the first
- // one, if present.
+ // Outdated configurations are already excluded with the database
+ // query.
//
- // Also save the built package configurations for which it's time
- // to be rebuilt.
- //
- config_machines configs (cfg_machines); // Make a copy for this pkg.
- auto pkg_builds (bld_prep_query.execute ());
+ assert (j != configs.end ());
+ configs.erase (j);
- for (auto i (pkg_builds.begin ()); i != pkg_builds.end (); ++i)
+ if (i->state == build_state::built)
{
- auto j (configs.find (i->id.configuration.c_str ()));
-
- // Outdated configurations are already excluded with the database
- // query.
- //
- assert (j != configs.end ());
- configs.erase (j);
-
- if (i->state == build_state::built)
- {
- assert (i->force != force_state::forcing);
+ assert (i->force != force_state::forcing);
- if (i->timestamp <= (i->force == force_state::forced
- ? forced_rebuild_expiration
- : normal_rebuild_expiration))
- rebuilds.emplace_back (i.load ());
- }
+ if (i->timestamp <= (i->force == force_state::forced
+ ? forced_rebuild_expiration
+ : normal_rebuild_expiration))
+ rebuilds.emplace_back (i.load ());
}
+ }
- if (!configs.empty ())
+ if (!configs.empty ())
+ {
+ config_machine& cm (configs.begin ()->second);
+ machine_header_manifest& mh (*cm.machine);
+ build_id bid (move (id), cm.config->name, toolchain_version);
+ shared_ptr<build> b (build_db_->find<build> (bid));
+ optional<string> cl (challenge ());
+
+ // If build configuration doesn't exist then create the new one and
+ // persist. Otherwise put it into the building state, refresh the
+ // timestamp and update.
+ //
+ if (b == nullptr)
{
- config_machine& cm (configs.begin ()->second);
- machine_header_manifest& mh (*cm.machine);
- build_id bid (move (id), cm.config->name, toolchain_version);
- shared_ptr<build> b (build_db_->find<build> (bid));
- optional<string> cl (challenge ());
-
- // If build configuration doesn't exist then create the new one
- // and persist. Otherwise put it into the building state, refresh
- // the timestamp and update.
+ b = make_shared<build> (move (bid.package.name),
+ move (bp.version),
+ move (bid.configuration),
+ move (tqm.toolchain_name),
+ move (toolchain_version),
+ move (agent_fp),
+ move (cl),
+ mh.name,
+ move (mh.summary),
+ cm.config->target);
+
+ build_db_->persist (b);
+ }
+ else
+ {
+ // The package configuration is in the building state, and there
+ // are no results.
//
- if (b == nullptr)
- {
- b = make_shared<build> (move (bid.package.name),
- move (pv.version),
- move (bid.configuration),
- move (tqm.toolchain_name),
- move (toolchain_version),
- move (agent_fp),
- move (cl),
- mh.name,
- move (mh.summary),
- cm.config->target);
-
- build_db_->persist (b);
- }
- else
- {
- // The package configuration is in the building state, and there
- // are no results.
- //
- // Note that in both cases we keep the status intact to be able
- // to compare it with the final one in the result request
- // handling in order to decide if to send the notification email.
- // The same is true for the forced flag (in the sense that we
- // don't set the force state to unforced).
- //
- // Load the section to assert the above statement.
- //
- build_db_->load (*b, b->results_section);
-
- assert (b->state == build_state::building &&
- b->results.empty ());
-
- b->state = build_state::building;
-
- // Switch the force state not to reissue the task after the
- // forced rebuild timeout. Note that the result handler will
- // still recognize that the rebuild was forced.
- //
- if (b->force == force_state::forcing)
- b->force = force_state::forced;
-
- b->toolchain_name = move (tqm.toolchain_name);
- b->agent_fingerprint = move (agent_fp);
- b->agent_challenge = move (cl);
- b->machine = mh.name;
- b->machine_summary = move (mh.summary);
- b->target = cm.config->target;
- b->timestamp = timestamp::clock::now ();
-
- build_db_->update (b);
- }
-
- // Finally, prepare the task response manifest.
+ // Note that in both cases we keep the status intact to be able to
+ // compare it with the final one in the result request handling in
+ // order to decide if to send the notification email. The same is
+ // true for the forced flag (in the sense that we don't set the
+ // force state to unforced).
//
- // Switch to the package database transaction to load the package.
+ // Load the section to assert the above statement.
//
- transaction::current (pt);
+ build_db_->load (*b, b->results_section);
- shared_ptr<package> p (package_db_->load<package> (b->id.package));
- p->internal_repository.load ();
+ assert (b->state == build_state::building && b->results.empty ());
- // Switch back to the build database transaction.
- //
- transaction::current (bt);
+ b->state = build_state::building;
- tsm = task (move (b), move (p), cm);
+ // Switch the force state not to reissue the task after the forced
+ // rebuild timeout. Note that the result handler will still
+ // recognize that the rebuild was forced.
+ //
+ if (b->force == force_state::forcing)
+ b->force = force_state::forced;
+
+ b->toolchain_name = move (tqm.toolchain_name);
+ b->agent_fingerprint = move (agent_fp);
+ b->agent_challenge = move (cl);
+ b->machine = mh.name;
+ b->machine_summary = move (mh.summary);
+ b->target = cm.config->target;
+ b->timestamp = timestamp::clock::now ();
+
+ build_db_->update (b);
}
- // If the task response manifest is prepared, then bail out from the
- // package loop, commit transactions and respond.
+ // Finally, prepare the task response manifest.
//
- if (!tsm.session.empty ())
- break;
+ shared_ptr<build_package> p (
+ build_db_->load<build_package> (b->id.package));
+
+ p->internal_repository.load ();
+
+ tsm = task (move (b), move (p), cm);
}
- bt.commit (); // Commit the build database transaction.
+ // If the task response manifest is prepared, then bail out from the
+ // package loop, commit transactions and respond.
+ //
+ if (!tsm.session.empty ())
+ break;
}
- transaction::current (pt); // Switch to the package database transaction.
- pt.commit ();
+ t.commit ();
}
// If we don't have an unbuilt package, then let's see if we have a
@@ -598,7 +567,7 @@ handle (request& rq, response& rs)
{
try
{
- transaction bt (build_db_->begin ());
+ transaction t (build_db_->begin ());
b = build_db_->find<build> (b->id);
@@ -617,19 +586,8 @@ handle (request& rq, response& rs)
// Load the package (if still present).
//
- transaction pt (package_db_->begin (), false);
- transaction::current (pt);
-
- shared_ptr<package> p (package_db_->find<package> (b->id.package));
-
- if (p != nullptr)
- p->internal_repository.load ();
-
- // Commit the package database transaction and switch back to the
- // build database transaction.
- //
- pt.commit ();
- transaction::current (bt);
+ shared_ptr<build_package> p (
+ build_db_->find<build_package> (b->id.package));
if (p != nullptr)
{
@@ -656,11 +614,13 @@ handle (request& rq, response& rs)
build_db_->update (b);
+ p->internal_repository.load ();
+
tsm = task (move (b), move (p), cm);
}
}
- bt.commit ();
+ t.commit ();
}
catch (const odb::deadlock&) {} // Just try with the next rebuild.