aboutsummaryrefslogtreecommitdiff
path: root/mod/ci-common.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'mod/ci-common.cxx')
-rw-r--r--mod/ci-common.cxx75
1 files changed, 59 insertions, 16 deletions
diff --git a/mod/ci-common.cxx b/mod/ci-common.cxx
index d750b1b..e720914 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.
//
@@ -913,7 +955,8 @@ namespace brep
rebuild (odb::core::database& db,
size_t retry,
const build_id& id,
- function<optional<string> (const tenant_service&,
+ function<optional<string> (const string& tenant_id,
+ const tenant_service&,
build_state)> uf) const
{
using namespace odb::core;
@@ -960,7 +1003,7 @@ namespace brep
tenant_service& ts (*t->service);
- if (optional<string> data = uf (ts, s))
+ if (optional<string> data = uf (t->id, ts, s))
{
ts.data = move (*data);
db.update (t);
@@ -988,7 +1031,7 @@ namespace brep
return s;
}
- optional<pair<tenant_service, bool>> ci_start::
+ optional<ci_start::tenant_data> ci_start::
find (odb::core::database& db,
const string& type,
const string& id) const
@@ -1007,9 +1050,9 @@ namespace brep
tr.commit ();
- if (t == nullptr)
+ if (t == nullptr || !t->service)
return nullopt;
- return pair<tenant_service, bool> (move (t->service), t->archived);
+ return tenant_data {move (t->id), move (*t->service), t->archived};
}
}