aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2024-10-17 09:05:04 +0200
committerFrancois Kritzinger <francois@codesynthesis.com>2024-12-10 16:34:15 +0200
commit1105538dd56dbb1b261d8b0ce8652f1dd719eaee (patch)
tree677c299c7c7aeec1e89f672a9079373bb7abd6b3
parent24415b406a6457638fc4e5435bab9fed987d01ba (diff)
Sketch CI common API changes
-rw-r--r--libbrep/common.hxx2
-rw-r--r--mod/ci-common.cxx11
-rw-r--r--mod/ci-common.hxx41
3 files changed, 48 insertions, 6 deletions
diff --git a/libbrep/common.hxx b/libbrep/common.hxx
index 8312b61..d2009f5 100644
--- a/libbrep/common.hxx
+++ b/libbrep/common.hxx
@@ -541,6 +541,8 @@ namespace brep
// Third-party service state which may optionally be associated with a
// tenant (see also mod/tenant-service.hxx for background).
//
+ // Note that the {id, type} pair must be unique.
+ //
#pragma db value
struct tenant_service
{
diff --git a/mod/ci-common.cxx b/mod/ci-common.cxx
index c0ef89f..b3fc432 100644
--- a/mod/ci-common.cxx
+++ b/mod/ci-common.cxx
@@ -534,14 +534,15 @@ namespace brep
s.next ("", ""); // End of manifest.
}
- optional<string> ci_start::
+ pair<optional<string>, ci_start::duplicate_tenant_result> ci_start::
create (const basic_mark& error,
const basic_mark&,
const basic_mark* trace,
odb::core::database& db,
tenant_service&& service,
duration notify_interval,
- duration notify_delay) const
+ duration notify_delay,
+ duplicate_tenant_mode) const
{
using namespace odb::core;
@@ -556,7 +557,7 @@ namespace brep
catch (const system_error& e)
{
error << "unable to generate request id: " << e;
- return nullopt;
+ return {nullopt, duplicate_tenant_result::ignored}; // @@ TODO HACKED AROUND
}
// Use the generated request id if the tenant service id is not specified.
@@ -604,7 +605,7 @@ namespace brep
*trace << "unloaded CI request " << t.id << " for service "
<< t.service->id << ' ' << t.service->type << " is created";
- return move (t.id);
+ return {move (t.id), duplicate_tenant_result::created}; // @@ TODO HACKED AROUND
}
optional<ci_start::start_result> ci_start::
@@ -707,6 +708,8 @@ namespace brep
if (t == nullptr)
return nullopt;
+ // @@ Why not remove it if unloaded (and below)?
+
optional<tenant_service> r (move (t->service));
t->service = nullopt;
t->archived = true;
diff --git a/mod/ci-common.hxx b/mod/ci-common.hxx
index 6a07154..d01e251 100644
--- a/mod/ci-common.hxx
+++ b/mod/ci-common.hxx
@@ -72,16 +72,39 @@ namespace brep
// created tenant and set the initial delay for the first notification.
// See also the build_unloaded() tenant services notification.
//
+ // The duplicate_tenant_mode argument specifies the behavior in case of
+ // the duplicate tenant_service type/id pair. The default is to fail by
+ // throwing an exception. Alternatively, this can be ignored or the
+ // previous tenant can be canceled (thus freeing the type/id pair; see
+ // below) and a new tenant with the same type/id created. In both these
+ // modes (ignore and replace), the second half of the returned pair
+ // indicates whether there was a duplicate. If there were, then for the
+ // ignore mode the returned reference corresponds to the old tenant and
+ // for the replace mode -- to the new tenant.
+ //
+ // The replace_archived mode is a variant of replace that replaces if the
+ // tenant is already archived and ignores it otherwise (with the result
+ // having the same semantics as in the replace and ignore modes).
+ //
+ // Note also that the duplicate_tenant_mode::replace modes are not the
+ // same as separate calls to create() and then to cancel() since the
+ // latter would happen in two separate transactions and will thus be
+ // racy. @@@ TODO
+ //
// Note: should be called out of the database transaction.
//
- optional<string>
+ enum class duplicate_tenant_mode {fail, ignore, replace, replace_archived};
+ enum class duplicate_tenant_result {created, ignored, replaced};
+
+ pair<optional<string>, duplicate_tenant_result>
create (const basic_mark& error,
const basic_mark& warn,
const basic_mark* trace,
odb::core::database&,
tenant_service&&,
duration notify_interval,
- duration notify_delay) const;
+ duration notify_delay,
+ duplicate_tenant_mode = duplicate_tenant_mode::fail) const;
// Load (and start) previously created (as unloaded) CI request. Similarly
// to the start() function, return nullopt on an internal error.
@@ -101,6 +124,12 @@ namespace brep
// Cancel previously created or started CI request. Return the service
// state or nullopt if there is no tenant for such a type/id pair.
//
+ // Specifically, this function clears the tenant service state (thus
+ // allowing reusing the same service type/id pair in another tenant) and
+ // archives the tenant, unless the tenant is unloaded, in which case it is
+ // dropped (@@@ TODO). Note that the latter allow using unloaded tenants
+ // as a relatively cheap asynchronous execution mechanism.
+ //
// Note: should be called out of the database transaction.
//
optional<tenant_service>
@@ -115,6 +144,14 @@ namespace brep
// is no tenant for the specified tenant id. Note that the reason argument
// is only used for tracing.
//
+ // @@@ Is tenant id here and reference above the same thing? Maybe use
+ // "tenant id" and "service id" terminology throughout?
+ //
+ // Similarly to above, this function archives the tenant, unless the
+ // tenant is unloaded, in which case it is dropped (@@@ TODO). Note,
+ // however, that this version does not touch the service state (use the
+ // above version if you want to clear it).
+ //
// Note: should be called out of the database transaction.
//
bool