aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/upstream/zen.h
blob: 78b6bc589e222a22e41fa36fbc358a09cee06e39 (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
// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include <zencore/iobuffer.h>
#include <zencore/iohash.h>
#include <zencore/logging.h>
#include <zencore/memoryview.h>
#include <zencore/thread.h>
#include <zencore/uid.h>
#include <zencore/zencore.h>

ZEN_THIRD_PARTY_INCLUDES_START
#include <tsl/robin_map.h>
#include <asio.hpp>
ZEN_THIRD_PARTY_INCLUDES_END

#include <chrono>
#include <list>

struct ZenCacheValue;

namespace zen {

class CbObjectWriter;
class CbObjectView;
class CbPackage;
class ZenStructuredCacheClient;

//////////////////////////////////////////////////////////////////////////

namespace detail {
	struct ZenCacheSessionState;
}

struct ZenCacheResult
{
	IoBuffer	Response;
	int64_t		Bytes		   = {};
	double		ElapsedSeconds = {};
	int32_t		ErrorCode	   = {};
	std::string Reason;
	bool		Success = false;
};

struct ZenStructuredCacheClientOptions
{
	std::string_view			 Name;
	std::string_view			 Url;
	std::span<std::string const> Urls;
	std::chrono::milliseconds	 ConnectTimeout{};
	std::chrono::milliseconds	 Timeout{};
};

/** Zen Structured Cache session
 *
 * This provides a context in which cache queries can be performed
 *
 * These are currently all synchronous. Will need to be made asynchronous
 */
class ZenStructuredCacheSession
{
public:
	ZenStructuredCacheSession(Ref<ZenStructuredCacheClient>&& OuterClient);
	~ZenStructuredCacheSession();

	ZenCacheResult CheckHealth();
	ZenCacheResult GetCacheRecord(std::string_view Namespace, std::string_view BucketId, const IoHash& Key, ZenContentType Type);
	ZenCacheResult GetCacheChunk(std::string_view Namespace, std::string_view BucketId, const IoHash& Key, const IoHash& ValueContentId);
	ZenCacheResult PutCacheRecord(std::string_view Namespace,
								  std::string_view BucketId,
								  const IoHash&	   Key,
								  IoBuffer		   Value,
								  ZenContentType   Type);
	ZenCacheResult PutCacheValue(std::string_view Namespace,
								 std::string_view BucketId,
								 const IoHash&	  Key,
								 const IoHash&	  ValueContentId,
								 IoBuffer		  Payload);
	ZenCacheResult InvokeRpc(const CbObjectView& Request);
	ZenCacheResult InvokeRpc(const CbPackage& Package);

private:
	inline LoggerRef Log() { return m_Log; }

	LoggerRef					  m_Log;
	Ref<ZenStructuredCacheClient> m_Client;
	detail::ZenCacheSessionState* m_SessionState;
};

/** Zen Structured Cache client
 *
 * This represents an endpoint to query -- actual queries should be done via
 * ZenStructuredCacheSession
 */
class ZenStructuredCacheClient : public RefCounted
{
public:
	ZenStructuredCacheClient(const ZenStructuredCacheClientOptions& Options);
	~ZenStructuredCacheClient();

	std::string_view ServiceUrl() const { return m_ServiceUrl; }

	inline LoggerRef Log() { return m_Log; }

private:
	LoggerRef				  m_Log;
	std::string				  m_ServiceUrl;
	std::chrono::milliseconds m_ConnectTimeout;
	std::chrono::milliseconds m_Timeout;

	RwLock									 m_SessionStateLock;
	std::list<detail::ZenCacheSessionState*> m_SessionStateCache;

	detail::ZenCacheSessionState* AllocSessionState();
	void						  FreeSessionState(detail::ZenCacheSessionState*);

	friend class ZenStructuredCacheSession;
};

}  // namespace zen