aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/storage/zenstorageserver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zenserver/storage/zenstorageserver.cpp')
-rw-r--r--src/zenserver/storage/zenstorageserver.cpp140
1 files changed, 122 insertions, 18 deletions
diff --git a/src/zenserver/storage/zenstorageserver.cpp b/src/zenserver/storage/zenstorageserver.cpp
index 3d81db656..44291395a 100644
--- a/src/zenserver/storage/zenstorageserver.cpp
+++ b/src/zenserver/storage/zenstorageserver.cpp
@@ -13,6 +13,8 @@
#include <zencore/iobuffer.h>
#include <zencore/jobqueue.h>
#include <zencore/logging.h>
+#include <zencore/logging/broadcastsink.h>
+#include <zencore/logging/registry.h>
#include <zencore/scopeguard.h>
#include <zencore/sentryintegration.h>
#include <zencore/session.h>
@@ -30,7 +32,9 @@
#include <zenstore/vfsimpl.h>
#include <zenstore/workspaces.h>
#include <zentelemetry/otlptrace.h>
+#include <zenutil/logging.h>
#include <zenutil/service.h>
+#include <zenutil/sessionsclient.h>
#include <zenutil/workerpools.h>
#include <zenutil/zenserverprocess.h>
@@ -133,7 +137,6 @@ void
ZenStorageServer::RegisterServices()
{
m_Http->RegisterService(*m_AuthService);
- m_Http->RegisterService(m_StatsService);
m_Http->RegisterService(m_TestService); // NOTE: this is intentionally not limited to test mode as it's useful for diagnostics
#if ZEN_WITH_TESTS
@@ -160,7 +163,7 @@ ZenStorageServer::RegisterServices()
m_Http->RegisterService(*m_HttpWorkspacesService);
}
- m_FrontendService = std::make_unique<HttpFrontendService>(m_ContentRoot, m_StatusService);
+ m_FrontendService = std::make_unique<HttpFrontendService>(m_ContentRoot, m_StatsService, m_StatusService);
if (m_FrontendService)
{
@@ -183,10 +186,15 @@ ZenStorageServer::RegisterServices()
m_Http->RegisterService(*m_AdminService);
+ if (m_ApiService)
+ {
+ m_Http->RegisterService(*m_ApiService);
+ }
+
#if ZEN_WITH_COMPUTE_SERVICES
- if (m_HttpFunctionService)
+ if (m_HttpComputeService)
{
- m_Http->RegisterService(*m_HttpFunctionService);
+ m_Http->RegisterService(*m_HttpComputeService);
}
#endif
}
@@ -208,12 +216,22 @@ ZenStorageServer::InitializeServices(const ZenStorageServerConfig& ServerOptions
ZEN_INFO("instantiating project service");
+ m_LocalRefPolicy = std::make_unique<DataRootLocalRefPolicy>(m_DataRoot);
m_JobQueue = MakeJobQueue(8, "bgjobs");
m_OpenProcessCache = std::make_unique<OpenProcessCache>();
m_ProjectStore = new ProjectStore(*m_CidStore, m_DataRoot / "projects", m_GcManager, ProjectStore::Configuration{});
- m_HttpProjectService.reset(
- new HttpProjectService{*m_CidStore, m_ProjectStore, m_StatusService, m_StatsService, *m_AuthMgr, *m_OpenProcessCache, *m_JobQueue});
+ m_HttpProjectService.reset(new HttpProjectService{*m_CidStore,
+ m_ProjectStore.Get(),
+ m_StatusService,
+ m_StatsService,
+ *m_AuthMgr,
+ *m_OpenProcessCache,
+ *m_JobQueue,
+ ServerOptions.RestrictContentTypes,
+ ServerOptions.OidcTokenExecutable,
+ ServerOptions.AllowExternalOidcTokenExe,
+ m_LocalRefPolicy.get()});
if (ServerOptions.WorksSpacesConfig.Enabled)
{
@@ -228,6 +246,16 @@ ZenStorageServer::InitializeServices(const ZenStorageServerConfig& ServerOptions
*m_Workspaces));
}
+ if (!ServerOptions.SessionsTargetUrl.empty())
+ {
+ m_SessionsClient = std::make_unique<SessionsServiceClient>(SessionsServiceClient::Options{
+ .TargetUrl = ServerOptions.SessionsTargetUrl,
+ .AppName = "zenserver",
+ .Mode = GetServerMode(),
+ .SessionId = GetSessionId(),
+ });
+ }
+
if (ServerOptions.BuildStoreConfig.Enabled)
{
CidStoreConfiguration BuildCidConfig;
@@ -238,7 +266,31 @@ ZenStorageServer::InitializeServices(const ZenStorageServerConfig& ServerOptions
BuildStoreConfig BuildsCfg;
BuildsCfg.RootDirectory = m_DataRoot / "builds";
BuildsCfg.MaxDiskSpaceLimit = ServerOptions.BuildStoreConfig.MaxDiskSpaceLimit;
- m_BuildStore = std::make_unique<BuildStore>(std::move(BuildsCfg), m_GcManager, *m_BuildCidStore);
+
+ if (ServerOptions.BuildStoreConfig.MaxDiskSpaceLimitPercent > 0)
+ {
+ DiskSpace Space;
+ if (DiskSpaceInfo(m_DataRoot, Space) && Space.Total > 0)
+ {
+ uint64_t PercentLimit = Space.Total * ServerOptions.BuildStoreConfig.MaxDiskSpaceLimitPercent / 100;
+ BuildsCfg.MaxDiskSpaceLimit = ServerOptions.BuildStoreConfig.MaxDiskSpaceLimit > 0
+ ? std::min(ServerOptions.BuildStoreConfig.MaxDiskSpaceLimit, PercentLimit)
+ : PercentLimit;
+ ZEN_INFO("buildstore disk limit: {}% of {} = {} (effective limit: {})",
+ ServerOptions.BuildStoreConfig.MaxDiskSpaceLimitPercent,
+ NiceBytes(Space.Total),
+ NiceBytes(PercentLimit),
+ NiceBytes(BuildsCfg.MaxDiskSpaceLimit));
+ }
+ else
+ {
+ ZEN_WARN("buildstore-disksizelimit-percent: failed to query disk space for {}, using absolute limit {}",
+ m_DataRoot.string(),
+ NiceBytes(BuildsCfg.MaxDiskSpaceLimit));
+ }
+ }
+
+ m_BuildStore = std::make_unique<BuildStore>(std::move(BuildsCfg), m_GcManager, *m_BuildCidStore);
}
if (ServerOptions.StructuredCacheConfig.Enabled)
@@ -264,7 +316,7 @@ ZenStorageServer::InitializeServices(const ZenStorageServerConfig& ServerOptions
ObjCfg.Buckets.push_back(std::move(NewBucket));
}
- m_ObjStoreService = std::make_unique<HttpObjectStoreService>(m_StatusService, std::move(ObjCfg));
+ m_ObjStoreService = std::make_unique<HttpObjectStoreService>(m_StatsService, m_StatusService, std::move(ObjCfg));
}
if (ServerOptions.BuildStoreConfig.Enabled)
@@ -279,14 +331,14 @@ ZenStorageServer::InitializeServices(const ZenStorageServerConfig& ServerOptions
{
ZEN_OTEL_SPAN("InitializeComputeService");
- m_HttpFunctionService =
- std::make_unique<compute::HttpFunctionService>(*m_CidStore, m_StatsService, ServerOptions.DataDir / "functions");
+ m_HttpComputeService =
+ std::make_unique<compute::HttpComputeService>(*m_CidStore, *m_CidStore, m_StatsService, ServerOptions.DataDir / "functions");
}
#endif
#if ZEN_WITH_VFS
m_VfsServiceImpl = std::make_unique<VfsServiceImpl>();
- m_VfsServiceImpl->AddService(Ref<ProjectStore>(m_ProjectStore));
+ m_VfsServiceImpl->AddService(Ref<ProjectStore>(m_ProjectStore.Get()));
m_VfsServiceImpl->AddService(Ref<ZenCacheStore>(m_CacheStore));
m_VfsService = std::make_unique<VfsService>(m_StatusService, m_VfsServiceImpl.get());
@@ -316,6 +368,8 @@ ZenStorageServer::InitializeServices(const ZenStorageServerConfig& ServerOptions
.AttachmentPassCount = ServerOptions.GcConfig.AttachmentPassCount};
m_GcScheduler.Initialize(GcConfig);
+ m_ApiService = std::make_unique<HttpApiService>(*m_Http);
+
// Create and register admin interface last to make sure all is properly initialized
m_AdminService = std::make_unique<HttpAdminService>(
m_GcScheduler,
@@ -485,7 +539,7 @@ ZenStorageServer::InitializeState(const ZenStorageServerConfig& ServerOptions)
std::error_code Ec;
for (const std::filesystem::directory_entry& DirEntry : std::filesystem::directory_iterator{m_DataRoot, Ec})
{
- if (DirEntry.is_directory() && (DirEntry.path().filename() != "logs"))
+ if (DirEntry.is_directory() && DirEntry.path().filename() != "logs" && DirEntry.path().filename() != ".sentry-native")
{
ZEN_INFO("Deleting '{}'", DirEntry.path());
@@ -668,11 +722,15 @@ ZenStorageServer::InitializeStructuredCache(const ZenStorageServerConfig& Server
m_StatusService,
*m_UpstreamCache,
m_GcManager.GetDiskWriteBlocker(),
- *m_OpenProcessCache);
+ *m_OpenProcessCache,
+ m_LocalRefPolicy.get());
m_StatsReporter.AddProvider(m_CacheStore.Get());
m_StatsReporter.AddProvider(m_CidStore.get());
- m_StatsReporter.AddProvider(m_BuildCidStore.get());
+ if (m_BuildCidStore)
+ {
+ m_StatsReporter.AddProvider(m_BuildCidStore.get());
+ }
}
void
@@ -695,16 +753,16 @@ ZenStorageServer::Run()
ExtendableStringBuilder<256> BuildOptions;
GetBuildOptions(BuildOptions, '\n');
- ZEN_INFO("Build options ({}/{}):\n{}", GetOperatingSystemName(), GetCpuName(), BuildOptions);
+ ZEN_INFO("Build options ({}/{}, {}):\n{}", GetOperatingSystemName(), GetCpuName(), GetCompilerName(), BuildOptions);
}
ZEN_INFO(ZEN_APP_NAME " now running (pid: {})", GetCurrentProcessId());
- if (m_FrontendService)
+ if (m_FrontendService && !m_NoNetwork)
{
ZEN_INFO("frontend link: {}", m_Http->GetServiceUri(m_FrontendService.get()));
}
- else
+ else if (!m_FrontendService)
{
ZEN_INFO("frontend service disabled");
}
@@ -790,6 +848,17 @@ ZenStorageServer::Run()
OnReady();
+ StartSelfSession("zenserver");
+
+ if (m_SessionsClient)
+ {
+ m_SessionsClient->Announce();
+ EnqueueSessionAnnounceTimer();
+
+ m_SessionLogSink = m_SessionsClient->CreateLogSink();
+ GetDefaultBroadcastSink()->AddSink(m_SessionLogSink);
+ }
+
if (m_IsPowerCycle)
{
ZEN_INFO("Power cycle mode enabled -- shutting down");
@@ -810,17 +879,37 @@ ZenStorageServer::Cleanup()
ZEN_INFO(ZEN_APP_NAME " cleaning up");
try
{
+ m_SessionAnnounceTimer.cancel();
+
+ // Stop the IO context and join its thread first, before removing sinks.
+ // This ensures no async operations are trying to log through the
+ // broadcast sink while we modify its sink list.
m_IoContext.stop();
if (m_IoRunner.joinable())
{
m_IoRunner.join();
}
+ // Close the HTTP server before removing sinks. HTTP worker threads
+ // continuously log messages and hold the BroadcastSink shared lock,
+ // which would starve the exclusive lock needed by RemoveSink().
if (m_Http)
{
m_Http->Close();
}
+ if (m_SessionLogSink)
+ {
+ GetDefaultBroadcastSink()->RemoveSink(m_SessionLogSink);
+ m_SessionLogSink = {};
+ }
+ if (m_SessionsClient)
+ {
+ m_SessionsClient.reset();
+ }
+
+ ShutdownServices();
+
if (m_JobQueue)
{
m_JobQueue->Stop();
@@ -832,7 +921,7 @@ ZenStorageServer::Cleanup()
Flush();
#if ZEN_WITH_COMPUTE_SERVICES
- m_HttpFunctionService.reset();
+ m_HttpComputeService.reset();
#endif
m_AdminService.reset();
@@ -903,6 +992,20 @@ ZenStorageServer::CheckStateMarker()
}
void
+ZenStorageServer::EnqueueSessionAnnounceTimer()
+{
+ m_SessionAnnounceTimer.expires_after(std::chrono::seconds(15));
+ m_SessionAnnounceTimer.async_wait([this](const asio::error_code& Ec) {
+ if (!Ec && m_SessionsClient)
+ {
+ m_SessionsClient->Announce();
+ EnqueueSessionAnnounceTimer();
+ }
+ });
+ EnsureIoRunner();
+}
+
+void
ZenStorageServer::Flush()
{
ZEN_TRACE_CPU("ZenStorageServer::Flush");
@@ -946,6 +1049,7 @@ ZenStorageServerMain::DoRun(ZenServerState::ZenServerEntry* Entry)
Server.SetContentRoot(m_ServerOptions.ContentDir);
Server.SetTestMode(m_ServerOptions.IsTest);
Server.SetDedicatedMode(m_ServerOptions.IsDedicated);
+ Server.SetAllowPortProbing(!m_ServerOptions.IsDedicated && m_ServerOptions.AllowPortProbing);
int EffectiveBasePort = Server.Initialize(m_ServerOptions, Entry);
if (EffectiveBasePort == -1)