userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
topic.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/ydb/topic.hpp
4
/// @brief YDB Topic client
5
6
#
include
<
atomic
>
7
#
include
<
chrono
>
8
#
include
<
cstdint
>
9
#
include
<
memory
>
10
#
include
<
optional
>
11
#
include
<
string
>
12
#
include
<
string_view
>
13
14
#
include
<
ydb
-
cpp
-
sdk
/
client
/
topic
/
client
.
h
>
15
#
include
<
ydb
-
cpp
-
sdk
/
client
/
topic
/
producer
.
h
>
16
#
include
<
ydb
-
cpp
-
sdk
/
client
/
types
/
executor
/
executor
.
h
>
17
18
#
include
<
userver
/
compiler
/
impl
/
lifetime
.
hpp
>
19
#
include
<
userver
/
engine
/
deadline
.
hpp
>
20
21
USERVER_NAMESPACE_BEGIN
22
23
namespace
ydb {
24
25
namespace
impl {
26
class
Driver;
27
struct
TopicSettings;
28
}
// namespace impl
29
30
/// @brief Read session used to connect to one or more topics for reading
31
///
32
/// @see https://ydb.tech/docs/en/reference/ydb-sdk/topic#reading
33
///
34
/// ## Example usage:
35
///
36
/// @ref samples/ydb_service/components/topic_reader.hpp
37
/// @ref samples/ydb_service/components/topic_reader.cpp
38
///
39
/// @example samples/ydb_service/components/topic_reader.hpp
40
/// @example samples/ydb_service/components/topic_reader.cpp
41
class
TopicReadSession
final
{
42
public
:
43
/// @cond
44
// For internal use only.
45
explicit
TopicReadSession(std::shared_ptr<NYdb::NTopic::IReadSession> read_session);
46
/// @endcond
47
48
/// @brief Get read session events
49
///
50
/// Waits until event occurs
51
/// @param max_events_count maximum events count in batch
52
/// @param max_size_bytes total size limit for data messages in batch
53
/// if not specified, read session chooses event batch size automatically
54
std
::
vector
<
NYdb
::
NTopic
::
TReadSessionEvent
::
TEvent
>
GetEvents
(
55
std
::
optional
<
std
::
size_t
>
max_events_count
= {},
56
size_t
max_size_bytes
=
std
::
numeric_limits
<
size_t
>::
max
()
57
);
58
59
/// @brief Get read session events
60
///
61
/// Waits until event occurs
62
/// @param settings ydb native read session settings
63
std
::
vector
<
NYdb
::
NTopic
::
TReadSessionEvent
::
TEvent
>
GetEvents
(
64
const
NYdb
::
NTopic
::
TReadSessionGetEventSettings
&
settings
65
);
66
67
/// @brief Close read session
68
///
69
/// Waits for all commit acknowledgments to arrive.
70
/// Force close after timeout
71
bool
Close
(std::chrono::milliseconds timeout);
72
73
/// @brief Get native read session
74
///
75
/// @warning Use with care! Facilities from @ref userver/drivers/subscribable_futures.hpp can help
76
/// with non-blocking wait operations.
77
NYdb::NTopic::IReadSession&
GetNativeTopicReadSession
() USERVER_IMPL_LIFETIME_BOUND;
78
79
private
:
80
std::shared_ptr<NYdb::NTopic::IReadSession> read_session_;
81
};
82
83
/// @brief Write session used to connect to a topic for writting
84
///
85
/// @see https://ydb.tech/docs/en/reference/ydb-sdk/topic#write
86
class
TopicWriteSession
final
{
87
public
:
88
/// @cond
89
/// For internal use only.
90
explicit
TopicWriteSession(std::shared_ptr<NYdb::NTopic::IWriteSession> write_session);
91
/// @endcond
92
93
/// @brief Wait for the next write session event
94
///
95
/// Suspends the current coroutine until an event is available, then returns it without blocking the thread.
96
NYdb::NTopic::TWriteSessionEvent::TEvent
GetEvent
();
97
98
/// @brief Poll for a write session event without waiting
99
///
100
/// Returns the next buffered event immediately if one is available, or `std::nullopt` if the event queue is empty.
101
/// Does not suspend the coroutine.
102
///
103
/// @note Sometimes may return `std::nullopt` even if an event is available. Intended for use in loops.
104
std::optional<NYdb::NTopic::TWriteSessionEvent::TEvent>
TryGetEvent
();
105
106
/// @brief Write a messsage using a continuation token from TReadyToAcceptEvent
107
///
108
/// Must be called only after receiving TReadyToAcceptEvent from GetEvent() or TryGetEvent().
109
void
Write
(NYdb::NTopic::TContinuationToken&& token, NYdb::NTopic::TWriteMessage&& message);
110
111
/// @brief Close write session
112
///
113
/// Waits for all in-flights messages to be acknowledged.
114
/// Force closes after timeout
115
bool
Close
(std::chrono::milliseconds timeout);
116
117
/// @brief Get native write session
118
///
119
/// @warning Use with care! Facilities from @ref userver/drivers/subscribable_futures.hpp can help
120
/// with non-blocking wait operations.
121
NYdb::NTopic::IWriteSession&
GetNativeTopicWriteSession
() USERVER_IMPL_LIFETIME_BOUND;
122
123
private
:
124
std::shared_ptr<NYdb::NTopic::IWriteSession> write_session_;
125
};
126
127
/// @brief Simple write session used to write messages to a topic without
128
/// manually handling write session events.
129
///
130
/// This is a userver-native analogue of YDB SDK
131
/// `ISimpleBlockingWriteSession`: methods may wait for YDB flow-control
132
/// continuation tokens, but waiting suspends the current coroutine instead of
133
/// blocking an OS thread. It wraps a single `IWriteSession`; its simple API does
134
/// not expose the native event loop or acknowledgments.
135
///
136
/// @see https://ydb.tech/docs/en/reference/ydb-sdk/topic#write
137
class
TopicSimpleWriteSession
final
{
138
public
:
139
/// @cond
140
/// For internal use only.
141
explicit
TopicSimpleWriteSession(std::shared_ptr<NYdb::NTopic::IWriteSession> write_session);
142
/// @endcond
143
144
TopicSimpleWriteSession(
const
TopicSimpleWriteSession&) =
delete
;
145
TopicSimpleWriteSession& operator=(
const
TopicSimpleWriteSession&) =
delete
;
146
TopicSimpleWriteSession(TopicSimpleWriteSession&&)
noexcept
;
147
TopicSimpleWriteSession& operator=(TopicSimpleWriteSession&&)
noexcept
;
148
149
/// @brief Write a single message.
150
///
151
/// Waits until YDB provides a continuation token or until `deadline`.
152
/// @returns true if the message was enqueued for writing, false if the
153
/// deadline was reached or the session was closed before a token arrived.
154
bool
Write
(
155
NYdb::NTopic::TWriteMessage&& message,
156
NYdb::TTransactionBase* tx =
nullptr
,
157
engine::Deadline deadline
=
{
}
158
);
159
160
/// @brief Write a single message using basic message options.
161
bool
Write
(
162
std::string_view data,
163
std::optional<std::uint64_t> seq_no =
std
::
nullopt
,
164
std::optional<std::chrono::system_clock::time_point> create_timestamp =
std
::
nullopt
,
165
engine::Deadline deadline
=
{
}
166
);
167
168
/// @brief Wait until initial SeqNo is discovered from the server.
169
std::
uint64_t
GetInitSeqNo
(engine::Deadline deadline
=
{
}
);
170
171
/// @brief Close the write session.
172
///
173
/// Waits for all in-flight messages to be acknowledged.
174
/// Force closes after `timeout`.
175
/// @returns `true` if all writes were completed and acknowledged. Returns
176
/// `false` if the timeout expired and some writes were aborted; in that
177
/// case their delivery is not guaranteed and should be handled as an
178
/// application-level delivery failure.
179
bool
Close
(std::chrono::milliseconds timeout);
180
181
/// @brief Returns true if the write session is alive and active.
182
bool
IsAlive
()
const
noexcept
;
183
184
/// @brief Get native write session
185
///
186
/// @warning Use with care! Facilities from @ref userver/drivers/subscribable_futures.hpp can help
187
/// with non-blocking wait operations.
188
NYdb::NTopic::IWriteSession&
GetNativeTopicWriteSession
() USERVER_IMPL_LIFETIME_BOUND;
189
190
private
:
191
std::optional<NYdb::NTopic::TContinuationToken> WaitForToken(engine::Deadline deadline);
192
193
std::shared_ptr<NYdb::NTopic::IWriteSession> write_session_;
194
std::atomic_bool closed_{
false
};
195
};
196
197
/// @brief Settings for TopicProducer.
198
class
TopicProducerSettings
final
:
public
NYdb::NTopic::TProducerSettings {
199
using
NYdb::NTopic::TProducerSettings::MaxBlockTimeout;
200
using
NYdb::NTopic::TProducerSettings::MaxBlockTimeout_;
201
using
NYdb::NTopic::TProducerSettings::MaxMemoryUsage;
202
using
NYdb::NTopic::TProducerSettings::MaxMemoryUsage_;
203
};
204
205
/// @brief Native YDB producer used for partition-aware writes to a topic.
206
///
207
/// Unlike TopicSimpleWriteSession, this is a wrapper around the YDB SDK
208
/// `IProducer`. It selects partitions by message key or explicit partition and
209
/// manages the corresponding write sessions internally.
210
///
211
/// Write() fails immediately if the internal buffer is overloaded.
212
///
213
/// @see https://ydb.tech/docs/en/reference/ydb-sdk/topic#write
214
class
TopicProducer
final
{
215
public
:
216
/// @cond
217
/// For internal use only.
218
explicit
TopicProducer(std::shared_ptr<NYdb::NTopic::IProducer> producer);
219
/// @endcond
220
221
/// @brief Write a single message to the topic.
222
///
223
/// Adds the message to the internal buffer and returns its queueing status.
224
/// Fails immediately with `EWriteStatus::Timeout` if the buffer is full.
225
/// Use Flush() to wait for the buffered messages to be persistently written.
226
NYdb::NTopic::TWriteResult
Write
(NYdb::NTopic::TWriteMessage&& message);
227
228
/// @brief Flush all buffered messages to the server.
229
///
230
/// Waits until all in-flight messages are acknowledged.
231
/// @param deadline timeout for flush completion
232
NYdb::NTopic::TFlushResult
Flush
(engine::Deadline deadline
=
{
}
);
233
234
/// @brief Close the producer.
235
///
236
/// Waits for all in-flight messages to be acknowledged.
237
/// Force closes after timeout.
238
NYdb::NTopic::TCloseResult
Close
(std::chrono::milliseconds timeout);
239
240
/// @brief Get native producer.
241
///
242
/// @warning Use with care! Facilities from @ref userver/drivers/subscribable_futures.hpp can help
243
/// with non-blocking wait operations.
244
NYdb::NTopic::IProducer&
GetNativeTopicProducer
() USERVER_IMPL_LIFETIME_BOUND;
245
246
private
:
247
std::shared_ptr<NYdb::NTopic::IProducer> producer_;
248
};
249
250
/// @ingroup userver_clients
251
///
252
/// @brief YDB Topic Client
253
///
254
/// @see https://ydb.tech/docs/en/concepts/topic
255
class
TopicClient
final
{
256
public
:
257
static
constexpr
std::uint64_t kDefaultProducerMaxMemoryUsageBytes = 2ULL * 1024 * 1024 * 1024;
258
259
/// @cond
260
// For internal use only.
261
TopicClient(std::shared_ptr<impl::Driver> driver, impl::TopicSettings settings);
262
/// @endcond
263
264
~TopicClient();
265
266
/// Alter topic
267
void
AlterTopic
(
const
std::string& path,
const
NYdb::NTopic::TAlterTopicSettings& settings);
268
269
/// Describe topic
270
NYdb::NTopic::TDescribeTopicResult
DescribeTopic
(
const
std::string& path);
271
272
/// Create read session
273
TopicReadSession
CreateReadSession
(
const
NYdb::NTopic::TReadSessionSettings& settings);
274
275
/// Create write session
276
TopicWriteSession
CreateWriteSession
(
const
NYdb::NTopic::TWriteSessionSettings& settings);
277
278
/// Create simple write session.
279
///
280
/// @note Event handlers from `settings` are not compatible with
281
/// TopicSimpleWriteSession. They are reset with a warning.
282
TopicSimpleWriteSession
CreateSimpleWriteSession
(
const
NYdb::NTopic::TWriteSessionSettings& settings);
283
284
/// Create producer.
285
///
286
/// Unlike TopicSimpleWriteSession, TopicProducer is a native YDB
287
/// multi-session producer: it routes each message by key or explicit
288
/// partition and fails immediately if its buffer is overloaded. Flush()
289
/// waits for persistence without closing the producer;
290
/// TopicSimpleWriteSession instead flushes pending writes as part of
291
/// Close().
292
/// @param max_memory_usage_bytes maximum buffered message memory in bytes
293
TopicProducer
CreateProducer
(
294
const
TopicProducerSettings& settings,
295
std::uint64_t max_memory_usage_bytes = kDefaultProducerMaxMemoryUsageBytes
296
);
297
298
/// Get native topic client
299
/// @warning Use with care! Facilities from
300
/// `<core/include/userver/drivers/subscribable_futures.hpp>` can help with
301
/// non-blocking wait operations.
302
NYdb::NTopic::TTopicClient&
GetNativeTopicClient
() USERVER_IMPL_LIFETIME_BOUND;
303
304
private
:
305
std::shared_ptr<impl::Driver> driver_;
306
// Owned executors: Stop() only after `topic_client_` is destroyed (see
307
// ~TopicClient). Joining these threads after the native client is gone
308
// avoids atexit use-after-destroy (e.g. SEGV in TCodecMap). Stopping them
309
// while TTopicClient is still alive would deadlock or stall writes.
310
NYdb::IExecutor::TPtr compression_executor_;
311
NYdb::IExecutor::TPtr handlers_executor_;
312
// `reset()` in ~TopicClient runs before Stop() on the executors above.
313
std::optional<NYdb::NTopic::TTopicClient> topic_client_;
314
};
315
316
}
// namespace ydb
317
318
USERVER_NAMESPACE_END
userver
ydb
topic.hpp
Generated on
for userver by
Doxygen
1.17.0