From 10ab5a9bdc0e27691ec2d09772c8e62587b779a7 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 15 Feb 2024 13:37:31 +0300 Subject: Cleanup build queries in monitor --- libbrep/build.hxx | 35 ++++++++++++++++++++++++ libbrep/common.hxx | 37 ++++++++++++++++++-------- monitor/monitor.cxx | 76 ++++++++++++++++++++--------------------------------- 3 files changed, 90 insertions(+), 58 deletions(-) diff --git a/libbrep/build.hxx b/libbrep/build.hxx index 236f73c..1e9a9fc 100644 --- a/libbrep/build.hxx +++ b/libbrep/build.hxx @@ -127,6 +127,41 @@ namespace brep compare_version_ne (x.toolchain_version, y.toolchain_version, true); } + // Allow comparing the query members with the query parameters bound by + // reference to variables of the build id type (in particular in the + // prepared queries). + // + // Note that it is not operator==() since the query template parameter type + // can not be deduced from the function parameter types and needs to be + // specified explicitly. + // + template + inline auto + equal (const ID& x, const build_id& y, bool toolchain_version = true) + -> decltype (x.package.tenant == odb::query::_ref (y.package.tenant) && + x.package.name == odb::query::_ref (y.package.name) && + x.package.version.epoch == + odb::query::_ref (y.package.version.epoch) && + x.target_config_name == + odb::query::_ref (y.target_config_name) && + x.toolchain_name == odb::query::_ref (y.toolchain_name) && + x.toolchain_version.epoch == + odb::query::_ref (y.toolchain_version.epoch)) + { + using query = odb::query; + + query r (equal (x.package, y.package) && + x.target == query::_ref (y.target) && + x.target_config_name == query::_ref (y.target_config_name) && + x.package_config_name == query::_ref (y.package_config_name) && + x.toolchain_name == query::_ref (y.toolchain_name)); + + if (toolchain_version) + r = r && equal (x.toolchain_version, y.toolchain_version); + + return r; + } + // build_state // // The queued build state is semantically equivalent to a non-existent diff --git a/libbrep/common.hxx b/libbrep/common.hxx index 11aae67..04d8453 100644 --- a/libbrep/common.hxx +++ b/libbrep/common.hxx @@ -737,6 +737,27 @@ namespace brep } // Allow comparing the query members with the query parameters bound by + // reference to variables of the canonical version type (in particular in + // the prepared queries). + // + // Note that it is not operator==() since the query template parameter type + // can not be deduced from the function parameter types and needs to be + // specified explicitly. + // + template + inline auto + equal (const V& x, const canonical_version& y) + -> decltype (x.epoch == odb::query::_ref (y.epoch)) + { + using query = odb::query; + + return x.epoch == query::_ref (y.epoch) && + x.canonical_upstream == query::_ref (y.canonical_upstream) && + x.canonical_release == query::_ref (y.canonical_release) && + x.revision == query::_ref (y.revision); + } + + // Allow comparing the query members with the query parameters bound by // reference to variables of the package id type (in particular in the // prepared queries). // @@ -747,21 +768,15 @@ namespace brep template inline auto equal (const ID& x, const package_id& y) - -> decltype (x.tenant == odb::query::_ref (y.tenant) && - x.name == odb::query::_ref (y.name) && + -> decltype (x.tenant == odb::query::_ref (y.tenant) && + x.name == odb::query::_ref (y.name) && x.version.epoch == odb::query::_ref (y.version.epoch)) { using query = odb::query; - const auto& qv (x.version); - const canonical_version& v (y.version); - - return x.tenant == query::_ref (y.tenant) && - x.name == query::_ref (y.name) && - qv.epoch == query::_ref (v.epoch) && - qv.canonical_upstream == query::_ref (v.canonical_upstream) && - qv.canonical_release == query::_ref (v.canonical_release) && - qv.revision == query::_ref (v.revision); + return x.tenant == query::_ref (y.tenant) && + x.name == query::_ref (y.name) && + equal (x.version, y.version); } // Repository id comparison operators. diff --git a/monitor/monitor.cxx b/monitor/monitor.cxx index 77f387b..27e8b84 100644 --- a/monitor/monitor.cxx +++ b/monitor/monitor.cxx @@ -655,8 +655,13 @@ namespace brep conn->prepare_query ("buildable-package-query", pq)); - // Prepare the package configuration build prepared query. + // Prepare the package configuration build prepared queries. // + using bquery = query; + using prep_bquery = prepared_query; + + build_id id; + // This query will only be used for toolchains that have no version // specified on the command line to obtain the latest completed build // across all toolchain versions, if present, and the latest incomplete @@ -667,29 +672,26 @@ namespace brep // toolchain that built the package last and if there are none, pick the // one for which the build task was issued last. // - using bquery = query; - using prep_bquery = prepared_query; - - build_id id; - string package_config_name; - - const auto& bid (bquery::build::id); - - bquery bq ((bquery::build::state != "queued" && - equal (bid.package, id.package) && - bid.target == bquery::_ref (id.target) && - bid.target_config_name == - bquery::_ref (id.target_config_name) && - bid.package_config_name == - bquery::_ref (package_config_name) && - bid.toolchain_name == bquery::_ref (id.toolchain_name)) + - "ORDER BY" + - bquery::build::soft_timestamp + "DESC, " + - bquery::build::timestamp + "DESC" + - "LIMIT 1"); - - prep_bquery pbq ( - conn->prepare_query ("package-build-query", bq)); + // @@ TMP Check if we can optimize this query by adding index for + // soft_timestamp and/or by setting enable_nestloop=off (or some + // such) as we do in mod/mod-builds.cxx. + // + bquery lbq ((equal (bquery::id, + id, + false /* toolchain_version */) && + bquery::state != "queued") + + "ORDER BY" + + bquery::soft_timestamp + "DESC, " + + bquery::timestamp + "DESC" + + "LIMIT 1"); + + prep_bquery plbq ( + conn->prepare_query ("package-latest-build-query", lbq)); + + // This query will only be used to retrieve a specific build by id. + // + bquery bq (equal (bquery::id, id) && bquery::state != "queued"); + prep_bquery pbq (conn->prepare_query ("package-build-query", bq)); timestamp now (system_clock::now ()); @@ -848,29 +850,9 @@ namespace brep // the latest build across all toolchain versions and search // for a specific build otherwise. // - shared_ptr b; - - if (id.toolchain_version.empty ()) - { - package_config_name = pc.name; - - // @@ TMP Check if we can optimize this query by adding - // index for soft_timestamp and/or by setting - // enable_nestloop=off (or some such) as we do in - // mod/mod-builds.cxx. - // - auto pbs (pbq.execute ()); - - if (!pbs.empty ()) - b = move (pbs.begin ()->build); - } - else - { - b = db.find (id); - - if (b->state == build_state::queued) - b = nullptr; - } + shared_ptr b (id.toolchain_version.empty () + ? plbq.execute_one () + : pbq.execute_one ()); // Note that we consider a build as delayed if it is not // completed in the expected timeframe. So even if the build -- cgit v1.1