userver: userver/ydb/topic.hpp Source File
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 <chrono>
7#include <memory>
8#include <optional>
9#include <string>
10
11#include <ydb-cpp-sdk/client/topic/client.h>
12#include <ydb-cpp-sdk/client/topic/producer.h>
13#include <ydb-cpp-sdk/client/types/executor/executor.h>
14
15#include <userver/compiler/impl/lifetime.hpp>
16#include <userver/engine/deadline.hpp>
17
18USERVER_NAMESPACE_BEGIN
19
20namespace ydb {
21
22namespace impl {
23class Driver;
24struct TopicSettings;
25} // namespace impl
26
27/// @brief Read session used to connect to one or more topics for reading
28///
29/// @see https://ydb.tech/docs/en/reference/ydb-sdk/topic#reading
30///
31/// ## Example usage:
32///
33/// @ref samples/ydb_service/components/topic_reader.hpp
34/// @ref samples/ydb_service/components/topic_reader.cpp
35///
36/// @example samples/ydb_service/components/topic_reader.hpp
37/// @example samples/ydb_service/components/topic_reader.cpp
38class TopicReadSession final {
39public:
40 /// @cond
41 // For internal use only.
42 explicit TopicReadSession(std::shared_ptr<NYdb::NTopic::IReadSession> read_session);
43 /// @endcond
44
45 /// @brief Get read session events
46 ///
47 /// Waits until event occurs
48 /// @param max_events_count maximum events count in batch
49 /// @param max_size_bytes total size limit for data messages in batch
50 /// if not specified, read session chooses event batch size automatically
52 std::optional<std::size_t> max_events_count = {},
53 size_t max_size_bytes = std::numeric_limits<size_t>::max()
54 );
55
56 /// @brief Get read session events
57 ///
58 /// Waits until event occurs
59 /// @param settings ydb native read session settings
61 const NYdb::NTopic::TReadSessionGetEventSettings& settings
62 );
63
64 /// @brief Close read session
65 ///
66 /// Waits for all commit acknowledgments to arrive.
67 /// Force close after timeout
68 bool Close(std::chrono::milliseconds timeout);
69
70 /// @brief Get native read session
71 ///
72 /// @warning Use with care! Facilities from @ref userver/drivers/subscribable_futures.hpp can help
73 /// with non-blocking wait operations.
74 NYdb::NTopic::IReadSession& GetNativeTopicReadSession() USERVER_IMPL_LIFETIME_BOUND;
75
76private:
77 std::shared_ptr<NYdb::NTopic::IReadSession> read_session_;
78};
79
80/// @brief Write session used to connect to a topic for writting
81///
82/// @see https://ydb.tech/docs/en/reference/ydb-sdk/topic#write
83class TopicWriteSession final {
84public:
85 /// @cond
86 /// For internal use only.
87 explicit TopicWriteSession(std::shared_ptr<NYdb::NTopic::IWriteSession> write_session);
88 /// @endcond
89
90 /// @brief Wait for the next write session event
91 ///
92 /// Suspends the current coroutine until an event is available, then returns it without blocking the thread.
93 NYdb::NTopic::TWriteSessionEvent::TEvent GetEvent();
94
95 /// @brief Poll for a write session event without waiting
96 ///
97 /// Returns the next buffered event immediately if one is available, or `std::nullopt` if the event queue is empty.
98 /// Does not suspend the coroutine.
99 ///
100 /// @note Sometimes may return `std::nullopt` even if an event is available. Intended for use in loops.
101 std::optional<NYdb::NTopic::TWriteSessionEvent::TEvent> TryGetEvent();
102
103 /// @brief Write a messsage using a continuation token from TReadyToAcceptEvent
104 ///
105 /// Must be called only after receiving TReadyToAcceptEvent from GetEvent() or TryGetEvent().
106 void Write(NYdb::NTopic::TContinuationToken&& token, NYdb::NTopic::TWriteMessage&& message);
107
108 /// @brief Close write session
109 ///
110 /// Waits for all in-flights messages to be acknowledged.
111 /// Force closes after timeout
112 bool Close(std::chrono::milliseconds timeout);
113
114 /// @brief Get native write session
115 ///
116 /// @warning Use with care! Facilities from @ref userver/drivers/subscribable_futures.hpp can help
117 /// with non-blocking wait operations.
118 NYdb::NTopic::IWriteSession& GetNativeTopicWriteSession() USERVER_IMPL_LIFETIME_BOUND;
119
120private:
121 std::shared_ptr<NYdb::NTopic::IWriteSession> write_session_;
122};
123
124/// @brief Producer used to write messages to a topic.
125///
126/// @see https://ydb.tech/docs/en/reference/ydb-sdk/topic#write
127class TopicProducer final {
128public:
129 /// @cond
130 /// For internal use only.
131 explicit TopicProducer(std::shared_ptr<NYdb::NTopic::IProducer> producer);
132 /// @endcond
133
134 /// @brief Write a single message to the topic.
135 ///
136 /// Adds the message to the internal buffer and returns immediately.
137 /// Use Flush() to wait for the buffered messages to be persistently written.
138 NYdb::NTopic::TWriteResult Write(NYdb::NTopic::TWriteMessage&& message);
139
140 /// @brief Flush all buffered messages to the server.
141 ///
142 /// Waits until all in-flight messages are acknowledged.
143 /// @param deadline timeout for flush completion
144 NYdb::NTopic::TFlushResult Flush(engine::Deadline deadline = {});
145
146 /// @brief Close the producer.
147 ///
148 /// Waits for all in-flight messages to be acknowledged.
149 /// Force closes after timeout.
150 NYdb::NTopic::TCloseResult Close(std::chrono::milliseconds timeout);
151
152 /// @brief Get native producer.
153 ///
154 /// @warning Use with care! Facilities from @ref userver/drivers/subscribable_futures.hpp can help
155 /// with non-blocking wait operations.
156 NYdb::NTopic::IProducer& GetNativeTopicProducer() USERVER_IMPL_LIFETIME_BOUND;
157
158private:
159 std::shared_ptr<NYdb::NTopic::IProducer> producer_;
160};
161
162/// @ingroup userver_clients
163///
164/// @brief YDB Topic Client
165///
166/// @see https://ydb.tech/docs/en/concepts/topic
167class TopicClient final {
168public:
169 /// @cond
170 // For internal use only.
171 TopicClient(std::shared_ptr<impl::Driver> driver, impl::TopicSettings settings);
172 /// @endcond
173
174 ~TopicClient();
175
176 /// Alter topic
177 void AlterTopic(const std::string& path, const NYdb::NTopic::TAlterTopicSettings& settings);
178
179 /// Describe topic
180 NYdb::NTopic::TDescribeTopicResult DescribeTopic(const std::string& path);
181
182 /// Create read session
183 TopicReadSession CreateReadSession(const NYdb::NTopic::TReadSessionSettings& settings);
184
185 /// Create write session
186 TopicWriteSession CreateWriteSession(const NYdb::NTopic::TWriteSessionSettings& settings);
187
188 /// Create producer
189 TopicProducer CreateProducer(const NYdb::NTopic::TProducerSettings& settings);
190
191 /// Get native topic client
192 /// @warning Use with care! Facilities from
193 /// `<core/include/userver/drivers/subscribable_futures.hpp>` can help with
194 /// non-blocking wait operations.
195 NYdb::NTopic::TTopicClient& GetNativeTopicClient() USERVER_IMPL_LIFETIME_BOUND;
196
197private:
198 std::shared_ptr<impl::Driver> driver_;
199 // Owned executors: Stop() only after `topic_client_` is destroyed (see
200 // ~TopicClient). Joining these threads after the native client is gone
201 // avoids atexit use-after-destroy (e.g. SEGV in TCodecMap). Stopping them
202 // while TTopicClient is still alive would deadlock or stall writes.
203 NYdb::IExecutor::TPtr compression_executor_;
204 NYdb::IExecutor::TPtr handlers_executor_;
205 // `reset()` in ~TopicClient runs before Stop() on the executors above.
206 std::optional<NYdb::NTopic::TTopicClient> topic_client_;
207};
208
209} // namespace ydb
210
211USERVER_NAMESPACE_END