aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/zenserver.h
blob: 5a8a079c0ac44bf8ca6cb0766d109cbc3a98924b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include <zencore/basicfile.h>
#include <zenhttp/httpserver.h>
#include <zenhttp/httpstats.h>
#include <zenhttp/httpstatus.h>
#include <zenutil/zenserverprocess.h>

#include <memory>
#include <string_view>
#include "config/config.h"

ZEN_THIRD_PARTY_INCLUDES_START
#include <asio.hpp>
ZEN_THIRD_PARTY_INCLUDES_END

#include "diag/diagsvcs.h"
#include "stats/statsreporter.h"

#ifndef ZEN_APP_NAME
#	define ZEN_APP_NAME "Unreal Zen Storage Server"
#endif

namespace zen {

struct FLLMTag;
extern const FLLMTag& GetZenserverTag();

struct ZenStorageServerConfig;

class ZenServerBase : public IHttpStatusProvider
{
	ZenServerBase& operator=(ZenServerBase&&) = delete;
	ZenServerBase(ZenServerBase&&)			  = delete;

public:
	ZenServerBase();
	~ZenServerBase();

	void RequestExit(int ExitCode);

	void SetIsReadyFunc(std::function<void()>&& IsReadyFunc) { m_IsReadyFunc = std::move(IsReadyFunc); }

	void SetDataRoot(std::filesystem::path Root) { m_DataRoot = Root; }
	void SetContentRoot(std::filesystem::path Root) { m_ContentRoot = Root; }
	void SetDedicatedMode(bool State) { m_IsDedicatedMode = State; }
	void SetTestMode(bool State) { m_TestMode = State; }

protected:
	int	 Initialize(const ZenServerConfig& ServerOptions, ZenServerState::ZenServerEntry* ServerEntry);
	void Finalize();
	void GetBuildOptions(StringBuilderBase& OutOptions, char Separator = ',') const;
	void LogSettingsSummary(const ZenServerConfig& ServerConfig);

protected:
	NamedMutex						m_ServerMutex;
	ZenServerState::ZenServerEntry* m_ServerEntry  = nullptr;
	bool							m_UseSentry	   = false;
	bool							m_IsPowerCycle = false;

	bool m_IsDedicatedMode		  = false;
	bool m_TestMode				  = false;
	bool m_DebugOptionForcedCrash = false;

	std::thread		 m_IoRunner;
	asio::io_context m_IoContext;
	void			 EnsureIoRunner();

	enum ServerState
	{
		kInitializing,
		kRunning,
		kShuttingDown
	} m_CurrentState = kInitializing;

	inline void				SetNewState(ServerState NewState) { m_CurrentState = NewState; }
	static std::string_view ToString(ServerState Value);

	std::function<void()> m_IsReadyFunc;
	void				  OnReady();

	std::filesystem::path m_DataRoot;	  // Root directory for server state
	std::filesystem::path m_ContentRoot;  // Root directory for frontend content

	Ref<HttpServer> m_Http;

	std::unique_ptr<IHttpRequestFilter> m_HttpRequestFilter;

	HttpHealthService m_HealthService;
	HttpStatusService m_StatusService;

	// Stats reporting

	StatsReporter	   m_StatsReporter;
	asio::steady_timer m_StatsReportingTimer{m_IoContext};
	void			   EnqueueStatsReportingTimer();

	// Process Monitoring

	void CheckOwnerPid();
	bool UpdateProcessMonitor();
	void EnqueueProcessMonitorTimer();

	ProcessMonitor	   m_ProcessMonitor;
	asio::steady_timer m_PidCheckTimer{m_IoContext};
	bool			   m_FoundNoActiveSponsors = false;

	// Server state exit signaling

	asio::steady_timer m_StateExitFlagTimer{m_IoContext};

	void EnqueueStateExitFlagTimer();
	void CheckStateExitFlag();

	// SIGINT handling

	void			   EnqueueSigIntTimer();
	void			   CheckSigInt();
	asio::steady_timer m_SigIntTimer{m_IoContext};

	// IHttpStatusProvider
	virtual void HandleStatusRequest(HttpServerRequest& Request) override;

private:
	void InitializeSecuritySettings(const ZenServerConfig& ServerOptions);
};
class ZenServerMain
{
public:
	ZenServerMain(ZenServerConfig& ServerOptions);
	~ZenServerMain();

	int Run();

	ZenServerMain(const ZenServerMain&) = delete;
	ZenServerMain& operator=(const ZenServerMain&) = delete;

protected:
	ZenServerConfig& m_ServerOptions;
	LockFile		 m_LockFile;

	virtual void InitializeLogging();
	virtual void DoRun(ZenServerState::ZenServerEntry* Entry) = 0;

	void	 NotifyReady();
	CbObject MakeLockData(bool IsReady);
};

}  // namespace zen