aboutsummaryrefslogtreecommitdiff
path: root/mod/ci-common.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2024-11-20 15:17:26 +0200
committerKaren Arutyunov <karen@codesynthesis.com>2024-11-26 10:39:50 +0200
commitf7f899aabfa43515ae645d16b9b94738eed4d07d (patch)
tree4e08c4fa6f62311f7476fbf86fca61b8d86deb9d /mod/ci-common.cxx
parentae9c34d3256de0edb53d6965969ae740e63be82d (diff)
Add support for tenant service reference count
Diffstat (limited to 'mod/ci-common.cxx')
-rw-r--r--mod/ci-common.cxx64
1 files changed, 53 insertions, 11 deletions
diff --git a/mod/ci-common.cxx b/mod/ci-common.cxx
index 4b9f9f9..cba421b 100644
--- a/mod/ci-common.cxx
+++ b/mod/ci-common.cxx
@@ -553,7 +553,11 @@ namespace brep
assert (!transaction::has_current ());
build_tenant t;
+
+ // Set the reference count to 1 for the `created` result.
+ //
duplicate_tenant_result r (duplicate_tenant_result::created);
+ service.ref_count = 1;
for (string request_id;;)
{
@@ -584,14 +588,31 @@ namespace brep
: duplicate_tenant_mode::ignore);
}
+ // Shouldn't be here otherwise.
+ //
+ assert (t->service);
+
// Bail out in the ignore mode and cancel the tenant in the
// replace mode.
//
if (mode == duplicate_tenant_mode::ignore)
+ {
+ // Increment the reference count for the `ignored` result.
+ //
+ ++(t->service->ref_count);
+
+ db.update (t);
+ tr.commit ();
+
return make_pair (move (t->id), duplicate_tenant_result::ignored);
+ }
assert (mode == duplicate_tenant_mode::replace);
+ // Preserve the current reference count for the `replaced` result.
+ //
+ service.ref_count = t->service->ref_count;
+
if (t->unloaded_timestamp)
{
db.erase (t);
@@ -678,6 +699,7 @@ namespace brep
//
request_id = move (t.id);
service = move (*t.service);
+ service.ref_count = 1;
r = duplicate_tenant_result::created;
}
}
@@ -788,7 +810,8 @@ namespace brep
odb::core::database& db,
size_t retry,
const string& type,
- const string& id) const
+ const string& id,
+ bool ref_count) const
{
using namespace odb::core;
@@ -810,25 +833,44 @@ namespace brep
if (t == nullptr)
return nullopt;
- r = move (t->service);
+ // Shouldn't be here otherwise.
+ //
+ assert (t->service && t->service->ref_count != 0);
- if (t->unloaded_timestamp)
+ bool cancel (!ref_count || --(t->service->ref_count) == 0);
+
+ if (cancel)
{
- db.erase (t);
+ // Move out the service state before it is dropped from the tenant.
+ //
+ r = move (t->service);
+
+ if (t->unloaded_timestamp)
+ {
+ db.erase (t);
+ }
+ else
+ {
+ t->service = nullopt;
+ t->archived = true;
+ db.update (t);
+ }
+
+ if (trace != nullptr)
+ *trace << "CI request " << t->id << " for service " << id << ' '
+ << type << " is canceled";
}
else
{
- t->service = nullopt;
- t->archived = true;
- db.update (t);
+ db.update (t); // Update the service reference count.
+
+ // Move out the service state after the tenant is updated.
+ //
+ r = move (t->service);
}
tr.commit ();
- if (trace != nullptr)
- *trace << "CI request " << t->id << " for service " << id << ' '
- << type << " is canceled";
-
// Bail out if we have successfully updated or erased the tenant
// object.
//