aboutsummaryrefslogtreecommitdiff
path: root/src/zenutil/include
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2026-03-11 09:45:31 +0100
committerGitHub Enterprise <[email protected]>2026-03-11 09:45:31 +0100
commite9d04250225a430cffed28e6a49299e3da542f97 (patch)
tree7f99594bd930c072e159458319e822bbb18794f7 /src/zenutil/include
parentminor zenstore/blockstore fixes (#821) (diff)
downloadzen-e9d04250225a430cffed28e6a49299e3da542f97.tar.xz
zen-e9d04250225a430cffed28e6a49299e3da542f97.zip
hub consul integration (#820)
- Feature: Basic consul integration for zenserver hub mode, restricted to host local consul agent and register/deregister of services - Feature: Added new options to zenserver hub mode - `consul-endpoint` - Consul endpoint URL for service registration (empty = disabled) - `hub-base-port-number` - Base port number for provisioned instances - `hub-instance-limit` - Maximum number of provisioned instances for this hub - `hub-use-job-object` - Enable the use of a Windows Job Object for child process management (Windows only)
Diffstat (limited to 'src/zenutil/include')
-rw-r--r--src/zenutil/include/zenutil/consul.h62
-rw-r--r--src/zenutil/include/zenutil/zenserverprocess.h25
2 files changed, 87 insertions, 0 deletions
diff --git a/src/zenutil/include/zenutil/consul.h b/src/zenutil/include/zenutil/consul.h
index 08871fa66..b5bfa42d1 100644
--- a/src/zenutil/include/zenutil/consul.h
+++ b/src/zenutil/include/zenutil/consul.h
@@ -5,11 +5,26 @@
#include <zenbase/zenbase.h>
#include <zenhttp/httpclient.h>
+#include <atomic>
+#include <cstdint>
#include <string>
#include <string_view>
+#include <thread>
namespace zen::consul {
+struct ServiceRegistrationInfo
+{
+ std::string ServiceId;
+ std::string ServiceName;
+ std::string Address;
+ uint16_t Port = 0;
+ std::string HealthEndpoint;
+ std::vector<std::pair<std::string, std::string>> Tags;
+ int HealthIntervalSeconds = 10;
+ int DeregisterAfterSeconds = 30;
+};
+
class ConsulClient
{
public:
@@ -23,7 +38,22 @@ public:
std::string GetKeyValue(std::string_view Key);
void DeleteKey(std::string_view Key);
+ bool RegisterService(const ServiceRegistrationInfo& Info);
+ bool DeregisterService(std::string_view ServiceId);
+
+ // Query methods for testing
+ bool HasService(std::string_view ServiceId);
+ std::string GetAgentServicesJson();
+
+ // Blocking query on v1/agent/services. Blocks until the service list changes or
+ // the wait period expires. InOutIndex must be 0 for the first call; it is updated
+ // to the new X-Consul-Index value on success (left unchanged on error).
+ // Returns true if ServiceId is present in the response.
+ bool WatchService(std::string_view ServiceId, uint64_t& InOutIndex, int WaitSeconds);
+
private:
+ static bool FindServiceInJson(std::string_view Json, std::string_view ServiceId);
+
HttpClient m_HttpClient;
};
@@ -44,4 +74,36 @@ private:
std::unique_ptr<Impl> m_Impl;
};
+/**
+ * RAII wrapper for Consul service registration.
+ *
+ * Manages the lifecycle of a Consul service registration with:
+ * - Async registration in a background thread
+ * - Exponential backoff retry on failure (100ms, 200ms, 400ms)
+ * - Continuous background retry every 5 seconds after initial failures until registration succeeds
+ * - Automatic deregistration on destruction
+ */
+class ServiceRegistration
+{
+public:
+ ServiceRegistration(ConsulClient* Client, const ServiceRegistrationInfo& Info);
+ ~ServiceRegistration();
+
+ ServiceRegistration(const ServiceRegistration&) = delete;
+ ServiceRegistration& operator=(const ServiceRegistration&) = delete;
+
+ bool IsRegistered() const { return m_IsRegistered.load(); }
+ void WaitForReadyEvent(int MaxWaitMS);
+
+private:
+ ConsulClient* m_Client;
+ ServiceRegistrationInfo m_Info;
+ std::atomic<bool> m_IsRegistered{false};
+ std::thread m_RegistrationThread;
+ Event m_ReadyWakeupEvent;
+ Event m_StopEvent;
+
+ void RegistrationLoop();
+};
+
} // namespace zen::consul
diff --git a/src/zenutil/include/zenutil/zenserverprocess.h b/src/zenutil/include/zenutil/zenserverprocess.h
index 2a8617162..1b8750628 100644
--- a/src/zenutil/include/zenutil/zenserverprocess.h
+++ b/src/zenutil/include/zenutil/zenserverprocess.h
@@ -29,9 +29,34 @@ class CbObject;
class ZenServerEnvironment
{
public:
+ enum EStorageTag
+ {
+ Storage
+ };
+ enum EHubTag
+ {
+ Hub
+ };
+ enum ETestTag
+ {
+ Test
+ };
+
ZenServerEnvironment();
~ZenServerEnvironment();
+ ZenServerEnvironment(ZenServerEnvironment&&);
+
+ ZenServerEnvironment(EStorageTag, std::filesystem::path ProgramBaseDir);
+ ZenServerEnvironment(EHubTag,
+ std::filesystem::path ProgramBaseDir,
+ std::filesystem::path TestBaseDir,
+ std::string_view ServerClass = "");
+ ZenServerEnvironment(ETestTag,
+ std::filesystem::path ProgramBaseDir,
+ std::filesystem::path TestBaseDir,
+ std::string_view ServerClass = "");
+
void Initialize(std::filesystem::path ProgramBaseDir);
void InitializeForTest(std::filesystem::path ProgramBaseDir, std::filesystem::path TestBaseDir, std::string_view ServerClass = "");
void InitializeForHub(std::filesystem::path ProgramBaseDir, std::filesystem::path TestBaseDir, std::string_view ServerClass = "");