From 86e549e50d8e77a01f701940979a631eec1d82c5 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 22 Oct 2024 17:48:48 +0300 Subject: Implement CI common API changes --- mod/ci-common.cxx | 122 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 89 insertions(+), 33 deletions(-) (limited to 'mod/ci-common.cxx') diff --git a/mod/ci-common.cxx b/mod/ci-common.cxx index b3fc432..5191d46 100644 --- a/mod/ci-common.cxx +++ b/mod/ci-common.cxx @@ -534,7 +534,7 @@ namespace brep s.next ("", ""); // End of manifest. } - pair, ci_start::duplicate_tenant_result> ci_start:: + optional> ci_start:: create (const basic_mark& error, const basic_mark&, const basic_mark* trace, @@ -542,10 +542,62 @@ namespace brep tenant_service&& service, duration notify_interval, duration notify_delay, - duplicate_tenant_mode) const + duplicate_tenant_mode mode) const { using namespace odb::core; + assert (mode == duplicate_tenant_mode::fail || !service.id.empty ()); + assert (!transaction::has_current ()); + + duplicate_tenant_result r (duplicate_tenant_result::created); + + transaction tr (db.begin ()); + + // Unless we are in the 'fail on duplicate' mode, check if this service + // type/id pair is already in use and, if that's the case, either ignore + // it or reassign this service to a new tenant, canceling the old one. + // + if (mode != duplicate_tenant_mode::fail) + { + using query = query; + + shared_ptr t ( + db.query_one (query::service.id == service.id && + query::service.type == service.type)); + if (t != nullptr) + { + // Reduce the replace_archived mode to the replace or ignore mode. + // + if (mode == duplicate_tenant_mode::replace_archived) + { + mode = (t->archived + ? duplicate_tenant_mode::replace + : duplicate_tenant_mode::ignore); + } + + // Bail out in the ignore mode and cancel the tenant in the replace + // mode. + // + if (mode == duplicate_tenant_mode::ignore) + return make_pair (move (t->id), duplicate_tenant_result::ignored); + + assert (mode == duplicate_tenant_mode::replace); + + if (t->unloaded_timestamp) + { + db.erase (t); + } + else + { + t->service = nullopt; + t->archived = true; + db.update (t); + } + + r = duplicate_tenant_result::replaced; + } + } + // Generate the request id. // string request_id; @@ -557,7 +609,7 @@ namespace brep catch (const system_error& e) { error << "unable to generate request id: " << e; - return {nullopt, duplicate_tenant_result::ignored}; // @@ TODO HACKED AROUND + return nullopt; } // Use the generated request id if the tenant service id is not specified. @@ -569,43 +621,37 @@ namespace brep move (service), system_clock::now () - notify_interval + notify_delay, notify_interval); - { - assert (!transaction::has_current ()); - - transaction tr (db.begin ()); - - // Note that in contrast to brep-load, we know that the tenant id is - // unique and thus we don't try to remove a tenant with such an id. - // There is also not much reason to assume that we may have switched - // from the single-tenant mode here and remove the respective tenant, - // unless we are in the tenant-service functionality development mode. - // + // Note that in contrast to brep-load, we know that the tenant id is + // unique and thus we don't try to remove a tenant with such an id. + // There is also not much reason to assume that we may have switched + // from the single-tenant mode here and remove the respective tenant, + // unless we are in the tenant-service functionality development mode. + // #ifdef BREP_CI_TENANT_SERVICE_UNLOADED - cstrings ts ({""}); + cstrings ts ({""}); - db.erase_query ( - query::id.tenant.in_range (ts.begin (), ts.end ())); + db.erase_query ( + query::id.tenant.in_range (ts.begin (), ts.end ())); - db.erase_query ( - query::id.tenant.in_range (ts.begin (), ts.end ())); + db.erase_query ( + query::id.tenant.in_range (ts.begin (), ts.end ())); - db.erase_query ( - query::id.tenant.in_range (ts.begin (), ts.end ())); + db.erase_query ( + query::id.tenant.in_range (ts.begin (), ts.end ())); - db.erase_query ( - query::id.in_range (ts.begin (), ts.end ())); + db.erase_query ( + query::id.in_range (ts.begin (), ts.end ())); #endif - db.persist (t); + db.persist (t); - tr.commit (); - } + tr.commit (); if (trace != nullptr) *trace << "unloaded CI request " << t.id << " for service " << t.service->id << ' ' << t.service->type << " is created"; - return {move (t.id), duplicate_tenant_result::created}; // @@ TODO HACKED AROUND + return make_pair (move (t.id), r); } optional ci_start:: @@ -708,12 +754,18 @@ namespace brep if (t == nullptr) return nullopt; - // @@ Why not remove it if unloaded (and below)? - optional r (move (t->service)); - t->service = nullopt; - t->archived = true; - db.update (t); + + if (t->unloaded_timestamp) + { + db.erase (t); + } + else + { + t->service = nullopt; + t->archived = true; + db.update (t); + } tr.commit (); @@ -743,7 +795,11 @@ namespace brep if (t == nullptr) return false; - if (!t->archived) + if (t->unloaded_timestamp) + { + db.erase (t); + } + else if (!t->archived) { t->archived = true; db.update (t); -- cgit v1.1