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
class
TopicReadSession
final
{
41
public
:
42
/// @cond
43
// For internal use only.
44
explicit
TopicReadSession(std::shared_ptr<NYdb::NTopic::IReadSession> read_session);
45
/// @endcond
46
47
/// @brief Get read session events
48
///
49
/// Waits until event occurs
50
/// @param max_events_count maximum events count in batch
51
/// @param max_size_bytes total size limit for data messages in batch
52
/// if not specified, read session chooses event batch size automatically
53
std
::
vector
<
NYdb
::
NTopic
::
TReadSessionEvent
::
TEvent
>
GetEvents
(
54
std
::
optional
<
std
::
size_t
>
max_events_count
= {},
55
size_t
max_size_bytes
=
std
::
numeric_limits
<
size_t
>::
max
()
56
);
57
58
/// @brief Get read session events
59
///
60
/// Waits until event occurs
61
/// @param settings ydb native read session settings
62
std
::
vector
<
NYdb
::
NTopic
::
TReadSessionEvent
::
TEvent
>
GetEvents
(
63
const
NYdb
::
NTopic
::
TReadSessionGetEventSettings
&
settings
64
);
65
66
/// @brief Close read session
67
///
68
/// Waits for all commit acknowledgments to arrive.
69
/// Force close after timeout
70
bool
Close
(std::chrono::milliseconds timeout);
71
72
/// @brief Get native read session
73
///
74
/// @warning Use with care! Facilities from @ref userver/drivers/subscribable_futures.hpp can help
75
/// with non-blocking wait operations.
76
NYdb::NTopic::IReadSession&
GetNativeTopicReadSession
() USERVER_IMPL_LIFETIME_BOUND;
77
78
private
:
79
std::shared_ptr<NYdb::NTopic::IReadSession> read_session_;
80
};
81
82
/// @brief Write session used to connect to a topic for writting
83
///
84
/// @see https://ydb.tech/docs/en/reference/ydb-sdk/topic#write
85
class
TopicWriteSession
final
{
86
public
:
87
/// @cond
88
/// For internal use only.
89
explicit
TopicWriteSession(std::shared_ptr<NYdb::NTopic::IWriteSession> write_session);
90
/// @endcond
91
92
/// @brief Wait for the next write session event
93
///
94
/// Suspends the current coroutine until an event is available, then returns it without blocking the thread.
95
NYdb::NTopic::TWriteSessionEvent::TEvent
GetEvent
();
96
97
/// @brief Poll for a write session event without waiting
98
///
99
/// Returns the next buffered event immediately if one is available, or `std::nullopt` if the event queue is empty.
100
/// Does not suspend the coroutine.
101
///
102
/// @note Sometimes may return `std::nullopt` even if an event is available. Intended for use in loops.
103
std::optional<NYdb::NTopic::TWriteSessionEvent::TEvent>
TryGetEvent
();
104
105
/// @brief Write a messsage using a continuation token from TReadyToAcceptEvent
106
///
107
/// Must be called only after receiving TReadyToAcceptEvent from GetEvent() or TryGetEvent().
108
void
Write
(NYdb::NTopic::TContinuationToken&& token, NYdb::NTopic::TWriteMessage&& message);
109
110
/// @brief Close write session
111
///
112
/// Waits for all in-flights messages to be acknowledged.
113
/// Force closes after timeout
114
bool
Close
(std::chrono::milliseconds timeout);
115
116
/// @brief Get native write session
117
///
118
/// @warning Use with care! Facilities from @ref userver/drivers/subscribable_futures.hpp can help
119
/// with non-blocking wait operations.
120
NYdb::NTopic::IWriteSession&
GetNativeTopicWriteSession
() USERVER_IMPL_LIFETIME_BOUND;
121
122
private
:
123
std::shared_ptr<NYdb::NTopic::IWriteSession> write_session_;
124
};
125
126
/// @brief Simple write session used to write messages to a topic without
127
/// manually handling write session events.
128
///
129
/// This is a userver-native analogue of YDB SDK
130
/// `ISimpleBlockingWriteSession`: methods may wait for YDB flow-control
131
/// continuation tokens, but waiting suspends the current coroutine instead of
132
/// blocking an OS thread. It wraps a single `IWriteSession`; its simple API does
133
/// not expose the native event loop or acknowledgments.
134
///
135
/// @see https://ydb.tech/docs/en/reference/ydb-sdk/topic#write
136
class
TopicSimpleWriteSession
final
{
137
public
:
138
/// @cond
139
/// For internal use only.
140
explicit
TopicSimpleWriteSession(std::shared_ptr<NYdb::NTopic::IWriteSession> write_session);
141
/// @endcond
142
143
TopicSimpleWriteSession(
const
TopicSimpleWriteSession&) =
delete
;
144
TopicSimpleWriteSession& operator=(
const
TopicSimpleWriteSession&) =
delete
;
145
TopicSimpleWriteSession(TopicSimpleWriteSession&&)
noexcept
;
146
TopicSimpleWriteSession& operator=(TopicSimpleWriteSession&&)
noexcept
;
147
148
/// @brief Write a single message.
149
///
150
/// Waits until YDB provides a continuation token or until `deadline`.
151
/// @returns true if the message was enqueued for writing, false if the
152
/// deadline was reached or the session was closed before a token arrived.
153
bool
Write
(
154
NYdb::NTopic::TWriteMessage&& message,
155
NYdb::TTransactionBase* tx =
nullptr
,
156
engine::Deadline deadline
=
{
}
157
);
158
159
/// @brief Write a single message using basic message options.
160
bool
Write
(
161
std::string_view data,
162
std::optional<std::uint64_t> seq_no =
std
::
nullopt
,
163
std::optional<std::chrono::system_clock::time_point> create_timestamp =
std
::
nullopt
,
164
engine::Deadline deadline
=
{
}
165
);
166
167
/// @brief Wait until initial SeqNo is discovered from the server.
168
std::
uint64_t
GetInitSeqNo
(engine::Deadline deadline
=
{
}
);
169
170
/// @brief Close the write session.
171
///
172
/// Waits for all in-flight messages to be acknowledged.
173
/// Force closes after `timeout`.
174
/// @returns `true` if all writes were completed and acknowledged. Returns
175
/// `false` if the timeout expired and some writes were aborted; in that
176
/// case their delivery is not guaranteed and should be handled as an
177
/// application-level delivery failure.
178
bool
Close
(std::chrono::milliseconds timeout);
179
180
/// @brief Returns true if the write session is alive and active.
181
bool
IsAlive
()
const
noexcept
;
182
183
/// @brief Get native write session
184
///
185
/// @warning Use with care! Facilities from @ref userver/drivers/subscribable_futures.hpp can help
186
/// with non-blocking wait operations.
187
NYdb::NTopic::IWriteSession&
GetNativeTopicWriteSession
() USERVER_IMPL_LIFETIME_BOUND;
188
189
private
:
190
std::optional<NYdb::NTopic::TContinuationToken> WaitForToken(engine::Deadline deadline);
191
192
std::shared_ptr<NYdb::NTopic::IWriteSession> write_session_;
193
std::atomic_bool closed_{
false
};
194
};
195
196
/// @brief Settings for TopicProducer.
197
class
TopicProducerSettings
final
:
public
NYdb::NTopic::TProducerSettings {
198
using
NYdb::NTopic::TProducerSettings::MaxBlockTimeout;
199
using
NYdb::NTopic::TProducerSettings::MaxBlockTimeout_;
200
using
NYdb::NTopic::TProducerSettings::MaxMemoryUsage;
201
using
NYdb::NTopic::TProducerSettings::MaxMemoryUsage_;
202
};
203
204
/// @brief Native YDB producer used for partition-aware writes to a topic.
205
///
206
/// Unlike TopicSimpleWriteSession, this is a wrapper around the YDB SDK
207
/// `IProducer`. It selects partitions by message key or explicit partition and
208
/// manages the corresponding write sessions internally.
209
///
210
/// Write() fails immediately if the internal buffer is overloaded.
211
///
212
/// @see https://ydb.tech/docs/en/reference/ydb-sdk/topic#write
213
class
TopicProducer
final
{
214
public
:
215
/// @cond
216
/// For internal use only.
217
explicit
TopicProducer(std::shared_ptr<NYdb::NTopic::IProducer> producer);
218
/// @endcond
219
220
/// @brief Write a single message to the topic.
221
///
222
/// Adds the message to the internal buffer and returns its queueing status.
223
/// Fails immediately with `EWriteStatus::Timeout` if the buffer is full.
224
/// Use Flush() to wait for the buffered messages to be persistently written.
225
NYdb::NTopic::TWriteResult
Write
(NYdb::NTopic::TWriteMessage&& message);
226
227
/// @brief Flush all buffered messages to the server.
228
///
229
/// Waits until all in-flight messages are acknowledged.
230
/// @param deadline timeout for flush completion
231
NYdb::NTopic::TFlushResult
Flush
(engine::Deadline deadline
=
{
}
);
232
233
/// @brief Close the producer.
234
///
235
/// Waits for all in-flight messages to be acknowledged.
236
/// Force closes after timeout.
237
NYdb::NTopic::TCloseResult
Close
(std::chrono::milliseconds timeout);
238
239
/// @brief Get native producer.
240
///
241
/// @warning Use with care! Facilities from @ref userver/drivers/subscribable_futures.hpp can help
242
/// with non-blocking wait operations.
243
NYdb::NTopic::IProducer&
GetNativeTopicProducer
() USERVER_IMPL_LIFETIME_BOUND;
244
245
private
:
246
std::shared_ptr<NYdb::NTopic::IProducer> producer_;
247
};
248
249
/// @ingroup userver_clients
250
///
251
/// @brief YDB Topic Client
252
///
253
/// @see https://ydb.tech/docs/en/concepts/topic
254
class
TopicClient
final
{
255
public
:
256
static
constexpr
std::uint64_t kDefaultProducerMaxMemoryUsageBytes = 2ULL * 1024 * 1024 * 1024;
257
258
/// @cond
259
// For internal use only.
260
TopicClient(std::shared_ptr<impl::Driver> driver, impl::TopicSettings settings);
261
/// @endcond
262
263
~TopicClient();
264
265
/// Alter topic
266
void
AlterTopic
(
const
std::string& path,
const
NYdb::NTopic::TAlterTopicSettings& settings);
267
268
/// Describe topic
269
NYdb::NTopic::TDescribeTopicResult
DescribeTopic
(
const
std::string& path);
270
271
/// Create read session
272
TopicReadSession
CreateReadSession
(
const
NYdb::NTopic::TReadSessionSettings& settings);
273
274
/// Create write session
275
TopicWriteSession
CreateWriteSession
(
const
NYdb::NTopic::TWriteSessionSettings& settings);
276
277
/// Create simple write session.
278
///
279
/// @note Event handlers from `settings` are not compatible with
280
/// TopicSimpleWriteSession. They are reset with a warning.
281
TopicSimpleWriteSession
CreateSimpleWriteSession
(
const
NYdb::NTopic::TWriteSessionSettings& settings);
282
283
/// Create producer.
284
///
285
/// Unlike TopicSimpleWriteSession, TopicProducer is a native YDB
286
/// multi-session producer: it routes each message by key or explicit
287
/// partition and fails immediately if its buffer is overloaded. Flush()
288
/// waits for persistence without closing the producer;
289
/// TopicSimpleWriteSession instead flushes pending writes as part of
290
/// Close().
291
/// @param settings producer settings (topic path, partitioner, etc.)
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