aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2021-08-09 21:10:11 +0200
committerStefan Boberg <[email protected]>2021-08-09 21:10:11 +0200
commit8f05d82714650d200f353b466a6a8328a691a6f7 (patch)
treeb048031314560f29b7abe09c9050d2b9a4959bcd
parentChanged logic so that the shutdown monitoring thread is spun up in non-test m... (diff)
downloadzen-8f05d82714650d200f353b466a6a8328a691a6f7.tar.xz
zen-8f05d82714650d200f353b466a6a8328a691a6f7.zip
Extended ZenServerInstance life cycle management
-rw-r--r--TODO.md34
-rw-r--r--zenutil/include/zenserverprocess.h18
-rw-r--r--zenutil/zenserverprocess.cpp41
3 files changed, 84 insertions, 9 deletions
diff --git a/TODO.md b/TODO.md
index f1520d2d4..9ea5862f2 100644
--- a/TODO.md
+++ b/TODO.md
@@ -42,3 +42,37 @@
* nodejs/http_parser
* all the rest (do we need TPS for vcpkg packages?)
+
+
+
+# Productization
+
+* Incremental cook
+* Windows feature complete
+* Mac / Linux support
+* Non-elevated execution
+* State management strategy
+
+# Cache
+
+* M7
+ * Cleanup
+ * Jupiter upstream configuration
+
+# Editor Domain
+
+
+
+
+# Daemon Notes
+
+When operating in background daemon (Windows Service) mode, there are a few
+additional things to consider:
+
+* Install and uninstall (this will vary by platform)
+ * Where is the service installed? How is it uninstalled?
+* Servicing
+ * How is the server versioned? I would suggest going with a single release
+ number to keep things simple. There should not be any tight coupling with
+ different engine branches (new releases should be backwards compatible) etc
+ and any service development should take place on a single stream
diff --git a/zenutil/include/zenserverprocess.h b/zenutil/include/zenserverprocess.h
index d2101c8e8..d0093537e 100644
--- a/zenutil/include/zenserverprocess.h
+++ b/zenutil/include/zenserverprocess.h
@@ -2,9 +2,11 @@
#pragma once
+#include <zencore/enumflags.h>
#include <zencore/thread.h>
#include <spdlog/spdlog.h>
+#include <gsl/gsl-lite.hpp>
#include <atomic>
#include <filesystem>
@@ -36,7 +38,8 @@ struct ZenServerInstance
ZenServerInstance(ZenServerEnvironment& TestEnvironment);
~ZenServerInstance();
- void SignalShutdown() { m_ShutdownEvent.Set(); }
+ void Shutdown();
+ void SignalShutdown();
void WaitUntilReady();
[[nodiscard]] bool WaitUntilReady(int Timeout);
void EnableTermination() { m_Terminate = true; }
@@ -49,6 +52,7 @@ struct ZenServerInstance
}
void SpawnServer(int BasePort = 0);
+
void AttachToRunningServer(int BasePort = 0);
private:
@@ -59,6 +63,8 @@ private:
bool m_Terminate = false;
std::filesystem::path m_TestDir;
bool m_MeshEnabled = false;
+
+ void CreateShutdownEvent(int BasePort);
};
/** Shared system state
@@ -79,11 +85,19 @@ public:
{
std::atomic<uint32_t> Pid;
std::atomic<uint16_t> ListenPort;
- uint16_t Flags;
+ std::atomic<uint16_t> Flags;
uint8_t SessionId[12];
uint8_t Padding[12];
+ enum class FlagsEnum : uint16_t
+ {
+ kShutdownPlease = 1 << 0
+ };
+
+ FRIEND_ENUM_CLASS_FLAGS(FlagsEnum);
+
void Reset();
+ void SignalShutdownRequest();
};
static_assert(sizeof(ZenServerEntry) == 32);
diff --git a/zenutil/zenserverprocess.cpp b/zenutil/zenserverprocess.cpp
index 73b8d01f1..112c10dff 100644
--- a/zenutil/zenserverprocess.cpp
+++ b/zenutil/zenserverprocess.cpp
@@ -17,7 +17,6 @@
//////////////////////////////////////////////////////////////////////////
namespace zenutil {
-
class SecurityAttributes
{
public:
@@ -197,7 +196,8 @@ ZenServerState::Register(int ListenPort)
m_OurEntry = &Entry;
- Entry.Pid = Pid;
+ Entry.Pid = Pid;
+ Entry.Flags = 0;
return &Entry;
}
@@ -255,6 +255,13 @@ ZenServerState::ZenServerEntry::Reset()
{
Pid = 0;
ListenPort = 0;
+ Flags = 0;
+}
+
+void
+ZenServerState::ZenServerEntry::SignalShutdownRequest()
+{
+ Flags |= uint16_t(FlagsEnum::kShutdownPlease);
}
//////////////////////////////////////////////////////////////////////////
@@ -331,6 +338,18 @@ ZenServerInstance::ZenServerInstance(ZenServerEnvironment& TestEnvironment) : m_
ZenServerInstance::~ZenServerInstance()
{
+ Shutdown();
+}
+
+void
+ZenServerInstance::SignalShutdown()
+{
+ m_ShutdownEvent.Set();
+}
+
+void
+ZenServerInstance::Shutdown()
+{
if (m_Process.IsValid())
{
if (m_Terminate)
@@ -342,6 +361,7 @@ ZenServerInstance::~ZenServerInstance()
{
SignalShutdown();
m_Process.Wait();
+ m_Process.Reset();
}
}
}
@@ -361,10 +381,7 @@ ZenServerInstance::SpawnServer(int BasePort)
ChildEventName << "Zen_Child_" << ChildId;
zen::NamedEvent ChildEvent{ChildEventName};
- zen::ExtendableStringBuilder<32> ChildShutdownEventName;
- ChildShutdownEventName << "Zen_" << BasePort;
- ChildShutdownEventName << "_Shutdown";
- zen::NamedEvent ChildShutdownEvent{ChildShutdownEventName};
+ CreateShutdownEvent(BasePort);
zen::ExtendableStringBuilder<32> LogId;
LogId << "Zen" << ChildId;
@@ -480,7 +497,6 @@ ZenServerInstance::SpawnServer(int BasePort)
if (IsTest)
{
m_Process.Initialize(hProcess);
- m_ShutdownEvent = std::move(ChildShutdownEvent);
}
else
{
@@ -491,6 +507,16 @@ ZenServerInstance::SpawnServer(int BasePort)
}
void
+ZenServerInstance::CreateShutdownEvent(int BasePort)
+{
+ zen::ExtendableStringBuilder<32> ChildShutdownEventName;
+ ChildShutdownEventName << "Zen_" << BasePort;
+ ChildShutdownEventName << "_Shutdown";
+ zen::NamedEvent ChildShutdownEvent{ChildShutdownEventName};
+ m_ShutdownEvent = std::move(ChildShutdownEvent);
+}
+
+void
ZenServerInstance::AttachToRunningServer(int BasePort)
{
ZenServerState State;
@@ -518,6 +544,7 @@ ZenServerInstance::AttachToRunningServer(int BasePort)
}
m_Process.Initialize(Entry->Pid);
+ CreateShutdownEvent(BasePort);
}
void