Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
session_model.h
Go to the documentation of this file.
1/*****************************************************************************
2BSD 3-Clause License
3
4Copyright (c) 2025, kcenon
5All rights reserved.
6*****************************************************************************/
7
8#pragma once
9
12
13#include <memory>
14#include <type_traits>
15
16namespace kcenon::network::core {
17
18// Import VoidResult from network namespace for convenience
20
56template <typename SessionType>
57class session_model final : public session_concept {
58public:
59 using session_ptr = std::shared_ptr<SessionType>;
61
66 explicit session_model(session_ptr session)
67 : session_(std::move(session))
68 , created_at_(std::chrono::steady_clock::now())
70
71 ~session_model() override = default;
72
73 // =========================================================================
74 // Core Session Operations (delegated to wrapped session)
75 // =========================================================================
76
77 [[nodiscard]] auto id() const -> std::string_view override {
79 return session_->id();
80 } else if constexpr (has_server_id_method<SessionType>::value) {
81 return session_->server_id();
82 } else {
83 return "";
84 }
85 }
86
87 [[nodiscard]] auto is_connected() const -> bool override {
89 return session_->is_connected();
90 } else if constexpr (has_is_stopped_method<SessionType>::value) {
91 return !session_->is_stopped();
92 } else {
93 return true; // Assume connected if no method available
94 }
95 }
96
97 [[nodiscard]] auto send(std::vector<uint8_t>&& data)
98 -> VoidResult override {
100 return session_->send(std::move(data));
101 } else if constexpr (has_send_packet_method<SessionType>::value) {
102 session_->send_packet(std::move(data));
103 return VoidResult::ok(std::monostate{});
104 } else {
105 return VoidResult::err(-1, "Session does not support send");
106 }
107 }
108
109 auto close() -> void override {
111 session_->close();
112 } else if constexpr (has_stop_session_method<SessionType>::value) {
113 session_->stop_session();
114 }
115 }
116
117 auto stop() -> void override {
119 session_->stop_session();
120 } else if constexpr (has_close_method<SessionType>::value) {
121 session_->close();
122 }
123 }
124
125 // =========================================================================
126 // Type Information
127 // =========================================================================
128
129 [[nodiscard]] auto type() const noexcept -> const std::type_info& override {
130 return typeid(SessionType);
131 }
132
133 [[nodiscard]] auto get_raw() noexcept -> void* override {
134 return session_.get();
135 }
136
137 [[nodiscard]] auto get_raw() const noexcept -> const void* override {
138 return session_.get();
139 }
140
141 // =========================================================================
142 // Activity Tracking
143 // =========================================================================
144
145 [[nodiscard]] auto has_activity_tracking() const noexcept -> bool override {
147 }
148
149 [[nodiscard]] auto created_at() const
150 -> std::chrono::steady_clock::time_point override {
151 return created_at_;
152 }
153
154 [[nodiscard]] auto last_activity() const
155 -> std::chrono::steady_clock::time_point override {
156 return last_activity_;
157 }
158
159 auto update_activity() -> void override {
160 if constexpr (traits::has_activity_tracking) {
161 last_activity_ = std::chrono::steady_clock::now();
162 }
163 }
164
165 [[nodiscard]] auto idle_duration() const -> std::chrono::milliseconds override {
166 if constexpr (traits::has_activity_tracking) {
167 return std::chrono::duration_cast<std::chrono::milliseconds>(
168 std::chrono::steady_clock::now() - last_activity_);
169 } else {
170 return std::chrono::milliseconds{0};
171 }
172 }
173
174 // =========================================================================
175 // Direct Access to Wrapped Session
176 // =========================================================================
177
182 [[nodiscard]] auto get_session() noexcept -> SessionType* {
183 return session_.get();
184 }
185
190 [[nodiscard]] auto get_session() const noexcept -> const SessionType* {
191 return session_.get();
192 }
193
198 [[nodiscard]] auto get_session_ptr() const noexcept -> session_ptr {
199 return session_;
200 }
201
202private:
204 std::chrono::steady_clock::time_point created_at_;
205 std::chrono::steady_clock::time_point last_activity_;
206
207 // =========================================================================
208 // SFINAE Helpers for Method Detection
209 // =========================================================================
210
211 // id() method detection
212 template <typename T, typename = void>
213 struct has_id_method : std::false_type {};
214
215 template <typename T>
216 struct has_id_method<T, std::void_t<decltype(std::declval<const T&>().id())>>
217 : std::true_type {};
218
219 // server_id() method detection
220 template <typename T, typename = void>
221 struct has_server_id_method : std::false_type {};
222
223 template <typename T>
225 std::void_t<decltype(std::declval<const T&>().server_id())>>
226 : std::true_type {};
227
228 // is_connected() method detection
229 template <typename T, typename = void>
230 struct has_is_connected_method : std::false_type {};
231
232 template <typename T>
234 T, std::void_t<decltype(std::declval<const T&>().is_connected())>>
235 : std::true_type {};
236
237 // is_stopped() method detection
238 template <typename T, typename = void>
239 struct has_is_stopped_method : std::false_type {};
240
241 template <typename T>
243 T, std::void_t<decltype(std::declval<const T&>().is_stopped())>>
244 : std::true_type {};
245
246 // send() method detection
247 template <typename T, typename = void>
248 struct has_send_method : std::false_type {};
249
250 template <typename T>
252 T, std::void_t<decltype(std::declval<T&>().send(std::declval<std::vector<uint8_t>&&>()))>>
253 : std::true_type {};
254
255 // send_packet() method detection
256 template <typename T, typename = void>
257 struct has_send_packet_method : std::false_type {};
258
259 template <typename T>
261 T,
262 std::void_t<decltype(std::declval<T&>().send_packet(
263 std::declval<std::vector<uint8_t>&&>()))>>
264 : std::true_type {};
265
266 // close() method detection
267 template <typename T, typename = void>
268 struct has_close_method : std::false_type {};
269
270 template <typename T>
271 struct has_close_method<T, std::void_t<decltype(std::declval<T&>().close())>>
272 : std::true_type {};
273
274 // stop_session() method detection
275 template <typename T, typename = void>
276 struct has_stop_session_method : std::false_type {};
277
278 template <typename T>
280 std::void_t<decltype(std::declval<T&>().stop_session())>>
281 : std::true_type {};
282};
283
290template <typename SessionType>
291[[nodiscard]] auto make_session_model(std::shared_ptr<SessionType> session)
292 -> std::unique_ptr<session_concept> {
293 // Explicitly construct unique_ptr<session_concept> from raw pointer
294 // This ensures proper polymorphic conversion
295 return std::unique_ptr<session_concept>(
296 new session_model<SessionType>(std::move(session)));
297}
298
299} // namespace kcenon::network::core
static Result< T > ok(U &&value)
static Result< T > err(const simple_error &error)
Type-erased interface for session management.
Template that wraps concrete session types to implement session_concept.
auto is_connected() const -> bool override
Checks if the session is currently connected.
auto last_activity() const -> std::chrono::steady_clock::time_point override
Gets the last activity timestamp.
auto created_at() const -> std::chrono::steady_clock::time_point override
Gets the creation timestamp.
session_model(session_ptr session)
Constructs a session model wrapping the given session.
auto get_session() noexcept -> SessionType *
Gets the underlying session (non-owning)
std::shared_ptr< SessionType > session_ptr
auto idle_duration() const -> std::chrono::milliseconds override
Calculates idle duration since last activity.
auto send(std::vector< uint8_t > &&data) -> VoidResult override
Sends data through the session.
auto type() const noexcept -> const std::type_info &override
Gets the runtime type information of the wrapped session.
std::chrono::steady_clock::time_point created_at_
auto stop() -> void override
Stops the session (alias for protocol-specific implementations)
auto get_session() const noexcept -> const SessionType *
Gets the underlying session (non-owning, const)
auto get_raw() const noexcept -> const void *override
Gets a raw const pointer to the underlying session.
auto id() const -> std::string_view override
Gets the session's unique identifier.
auto has_activity_tracking() const noexcept -> bool override
Checks if this session type supports activity tracking.
auto close() -> void override
Closes the session.
auto update_activity() -> void override
Updates the last activity timestamp to current time.
auto get_session_ptr() const noexcept -> session_ptr
Gets the underlying session shared_ptr.
std::chrono::steady_clock::time_point last_activity_
auto get_raw() noexcept -> void *override
Gets a raw pointer to the underlying session.
auto make_session_model(std::shared_ptr< SessionType > session) -> std::unique_ptr< session_concept >
Factory function to create a session_model.
Customization point for session manager behavior.
static constexpr bool has_activity_tracking
Enable activity timestamp tracking (required for idle cleanup)