OZO 「お象」
Boost.Asio and libpq based asynchronous PostgreSQL unofficial header-only C++17 client library.
connection_pool.h
1 #pragma once
2 
3 #include <ozo/connection_info.h>
4 #include <ozo/transaction_status.h>
5 #include <ozo/asio.h>
6 #include <ozo/connector.h>
7 #include <ozo/core/thread_safety.h>
8 #include <ozo/detail/connection_pool.h>
9 
10 namespace ozo {
11 
21  std::size_t capacity = 10;
22  std::size_t queue_capacity = 128;
23  time_traits::duration idle_timeout = std::chrono::seconds(60);
24  time_traits::duration lifespan = std::chrono::hours(24);
25 };
26 
34 struct /*[[deprecated]]*/ connection_pool_timeouts {
35  time_traits::duration connect = std::chrono::seconds(10);
36  time_traits::duration queue = std::chrono::seconds(10);
37 };
38 
45 template <typename Rep>
47  using native_handle_type = typename Rep::native_handle_type;
48  using oid_map_type = typename Rep::oid_map_type;
49  using error_context_type = typename Rep::error_context_type;
50  using statistics_type = typename Rep::statistics_type;
51 };
52 
53 template <typename OidMap, typename Statistics = none_t>
54 class connection_rep {
55 public:
56  using oid_map_type = OidMap;
57  using native_handle_type = typename ozo::pg::conn::pointer;
58  using statistics_type = Statistics;
59  using error_context_type = std::string;
60 
61  const ozo::pg::conn& safe_native_handle() const & {return safe_handle_;}
62  ozo::pg::conn& safe_native_handle() & {return safe_handle_;}
63 
64  const oid_map_type& oid_map() const & {return oid_map_;}
65  oid_map_type& oid_map() & {return oid_map_;}
66 
67  const auto& statistics() const & {return statistics_;}
68 
69  template <typename Key, typename Value>
70  void update_statistics(const Key&, Value&&) noexcept {
71  static_assert(std::is_void_v<Key>, "update_statistics is not supperted");
72  }
73 
74  const error_context_type& get_error_context() const noexcept {
75  return error_context_;
76  }
77  void set_error_context(error_context_type v) {
78  error_context_ = std::move(v);
79  }
80 
81  connection_rep(
82  ozo::pg::conn&& safe_handle,
83  OidMap oid_map = OidMap{},
84  error_context_type error_context = {},
85  Statistics statistics = Statistics{})
86  : safe_handle_(std::move(safe_handle)),
87  oid_map_(std::move(oid_map)),
88  error_context_(std::move(error_context)),
89  statistics_(std::move(statistics)) {}
90 private:
91  ozo::pg::conn safe_handle_;
92  oid_map_type oid_map_;
93  error_context_type error_context_;
94  statistics_type statistics_;
95 };
96 
115 template <typename Rep, typename Executor = asio::io_context::executor_type>
117 public:
118  using rep_type = Rep;
123  using executor_type = Executor;
124 
125  pooled_connection(const Executor& ex, Rep&& rep);
126 
135  native_handle_type native_handle() const noexcept;
136 
142  const oid_map_type& oid_map() const noexcept { return ozo::unwrap(rep_).oid_map();}
143 
144  template <typename Key, typename Value>
145  void update_statistics(const Key& key, Value&& v) noexcept {
146  ozo::unwrap(rep_).update_statistics(key, std::forward<Value(v)>);
147  }
148  const statistics_type& statistics() const noexcept { return ozo::unwrap(rep_).statistics();}
149 
155  const error_context_type& get_error_context() const noexcept {
156  return ozo::unwrap(rep_).get_error_context();
157  }
158 
166  ozo::unwrap(rep_).set_error_context(std::move(v));
167  }
168 
174  executor_type get_executor() const noexcept { return ex_; }
175 
186  template <typename WaitHandler>
187  void async_wait_write(WaitHandler&& handler);
188 
199  template <typename WaitHandler>
200  void async_wait_read(WaitHandler&& handler);
201 
212  error_code close() noexcept;
213 
220  void cancel() noexcept;
221 
230  bool is_bad() const noexcept;
231 
240  operator bool () const noexcept { return !is_bad();}
241 
248  bool is_open() const noexcept { return native_handle() != nullptr;}
249 
251 private:
252  using stream_type = typename detail::connection_stream<executor_type>::type;
253 
254  rep_type rep_;
255  executor_type ex_;
256  stream_type stream_;
257 };
258 
259 template <typename ...Ts>
260 struct is_connection<pooled_connection<Ts...>> : std::true_type {};
261 
262 template <typename T>
263 struct connection_traits<yamail::resource_pool::handle<T>> :
264  connection_traits<typename yamail::resource_pool::handle<T>::value_type> {};
265 
301 template <typename Source, typename ThreadSafety = std::decay_t<decltype(thread_safe)>>
303  static_assert(ConnectionSource<Source>, "should model ConnectionSource concept");
304 
305 public:
306  using connection_rep_type = ozo::connection_rep<typename ozo::unwrap_type<ozo::connection_type<Source>>::oid_map_type>;
307 
308  using impl_type = detail::get_connection_pool_impl_t<connection_rep_type, ThreadSafety>;
317  connection_pool(Source source, const connection_pool_config& config, const ThreadSafety& /*thread_safety*/ = ThreadSafety{})
318  : impl_(config.capacity, config.queue_capacity, config.idle_timeout, config.lifespan),
319  source_(std::move(source)) {}
320 
324  using connection_type = std::shared_ptr<pooled_connection<yamail::resource_pool::handle<connection_rep_type>>>;
325 
336  template <typename TimeConstraint, typename Handler>
337  void operator ()(io_context& io, TimeConstraint t, Handler&& handler);
338 
339  auto stats() const {
340  return impl_.stats();
341  }
342 
343  auto operator [](io_context& io) {
344  return connection_provider(*this, io);
345  }
346 
347 private:
348 
349  auto queue_timeout(time_traits::time_point at) const {
350  return time_left(at);
351  }
352 
353  auto queue_timeout(time_traits::duration t) const {
354  return t;
355  }
356 
357  auto queue_timeout(none_t) const {
358  return time_traits::duration(0);
359  }
360 
361  impl_type impl_;
362  Source source_;
363 };
364 
365 //[[DEPRECATED]] for backward compatibility only
366 template <typename ...Ts>
367 [[deprecated]] auto make_connector(connection_pool<Ts...>& source, io_context& io, const connection_pool_timeouts& timeouts) {
368  return bind_get_connection_timeout(source[io], timeouts.connect);
369 }
370 
371 //[[DEPRECATED]] for backward compatibility only
372 template <typename ...Ts>
373 [[deprecated]] auto make_connector(connection_pool<Ts...>& source, io_context& io) {
374  return source[io];
375 }
376 
377 static_assert(ConnectionProvider<decltype(std::declval<connection_pool<connection_info<>>>()[std::declval<io_context&>()])>, "is not a ConnectionProvider");
378 
379 template <typename T>
380 struct is_connection_pool : std::false_type {};
381 
382 template <typename ...Args>
383 struct is_connection_pool<connection_pool<Args...>> : std::true_type {};
384 
385 template <typename T>
386 constexpr auto ConnectionPool = is_connection_pool<std::decay_t<T>>::value;
387 
402 template <typename ConnectionSource, typename ThreadSafety = decltype(thread_safe)>
404  const ThreadSafety& thread_safety = ThreadSafety{}) {
405  static_assert(ozo::ConnectionSource<ConnectionSource>, "source should model ConnectionSource concept");
406  return connection_pool<std::decay_t<ConnectionSource>, std::decay_t<ThreadSafety>>{
407  std::forward<ConnectionSource>(source), config, thread_safety};
408 }
409 
410 } // namespace ozo
411 
412 #include <ozo/impl/connection_pool.h>
ozo::connection_pool
Connection pool implementation.
Definition: connection_pool.h:302
ozo::pooled_connection::close
error_code close() noexcept
Definition: connection_pool.h:156
ozo::unwrap
constexpr decltype(auto) unwrap(T &&v) noexcept(noexcept(unwrap_impl< std::decay_t< T >>::apply(std::forward< T >(v))))
Unwraps argument underlying value or forwards the argument.
Definition: unwrap.h:57
ozo::connection_provider
Default model for the ConnectionProvider concept.
Definition: connector.h:66
ozo::error_code
boost::system::error_code error_code
Error code representation of the library.
Definition: error.h:38
ozo::pooled_connection::executor_type
Executor executor_type
The type of the executor associated with the object.
Definition: connection_pool.h:123
ozo::connection_traits< yamail::resource_pool::handle< T >::value_type >::oid_map_type
typename Rep::oid_map_type oid_map_type
Oid map of types that are used with the connection.
Definition: connection_pool.h:48
ozo::connection_pool_config::idle_timeout
time_traits::duration idle_timeout
time interval to close connection after last usage
Definition: connection_pool.h:23
ozo::pooled_connection::async_wait_write
void async_wait_write(WaitHandler &&handler)
Definition: connection_pool.h:145
ozo::pooled_connection::native_handle
native_handle_type native_handle() const noexcept
Definition: connection_pool.h:136
ozo::pooled_connection::cancel
void cancel() noexcept
Definition: connection_pool.h:163
ozo::connection_pool_timeouts::queue
time_traits::duration queue
[[IGNORED]]
Definition: connection_pool.h:36
ozo::connection_pool::operator()
void operator()(io_context &io, TimeConstraint t, Handler &&handler)
Definition: connection_pool.h:112
ozo::pooled_connection::get_executor
executor_type get_executor() const noexcept
Definition: connection_pool.h:174
ozo::pooled_connection::is_open
bool is_open() const noexcept
Definition: connection_pool.h:248
ozo::connection_pool_config::capacity
std::size_t capacity
maximum number of stored connections
Definition: connection_pool.h:21
ozo::OidMap
constexpr auto OidMap
Map of C++ types to corresponding PostgreSQL types OIDs.
Definition: type_traits.h:534
ozo::pooled_connection
Pool bound model for Connection concept.
Definition: connection_pool.h:116
ConnectionProvider
Connection provider concept
ozo::connection_pool::connection_pool
connection_pool(Source source, const connection_pool_config &config, const ThreadSafety &=ThreadSafety{})
Definition: connection_pool.h:317
ozo::time_traits::time_point
std::chrono::steady_clock::time_point time_point
Time point type of the library.
Definition: time_traits.h:14
ozo::connection_traits< yamail::resource_pool::handle< T >::value_type >::native_handle_type
typename Rep::native_handle_type native_handle_type
Native connection handle type.
Definition: connection_pool.h:47
ozo::connection_pool_config
Connection pool configuration.
Definition: connection_pool.h:20
ozo::connection_traits
Connection traits depend on a representation type.
Definition: connection_pool.h:46
ozo::pooled_connection::async_wait_read
void async_wait_read(WaitHandler &&handler)
Definition: connection_pool.h:151
ozo::connection_traits< yamail::resource_pool::handle< T >::value_type >::statistics_type
typename Rep::statistics_type statistics_type
Connection statistics to be collected.
Definition: connection_pool.h:50
ozo::pooled_connection::oid_map
const oid_map_type & oid_map() const noexcept
Definition: connection_pool.h:142
ozo::connection_traits< yamail::resource_pool::handle< T >::value_type >::error_context_type
typename Rep::error_context_type error_context_type
Additional error context which could provide context depended information for errors.
Definition: connection_pool.h:49
ConnectionSource
Connection source concept
ozo::connection_pool::connection_type
std::shared_ptr< pooled_connection< yamail::resource_pool::handle< connection_rep_type > >> connection_type
Definition: connection_pool.h:324
ozo::thread_safety
defines admissibility to use in multithreaded environment without additional synchronization
Definition: thread_safety.h:17
ozo::pooled_connection::rep_type
Rep rep_type
Connection representation type.
Definition: connection_pool.h:118
ozo::pooled_connection::get_error_context
const error_context_type & get_error_context() const noexcept
Definition: connection_pool.h:155
ozo::connection_pool_config::lifespan
time_traits::duration lifespan
time interval to keep connection open
Definition: connection_pool.h:24
ozo::pooled_connection::statistics_type
typename connection_traits< rep_type >::statistics_type statistics_type
Connection statistics to be collected.
Definition: connection_pool.h:122
ozo::time_traits::duration
std::chrono::steady_clock::duration duration
Time duration type of the library.
Definition: time_traits.h:13
ozo::pooled_connection::set_error_context
void set_error_context(error_context_type v={})
Definition: connection_pool.h:165
ozo::time_left
constexpr time_traits::duration time_left(time_traits::time_point t, time_traits::time_point now) noexcept
Time left to deadline.
Definition: deadline.h:77
ozo::connection_pool::make_connection_pool
auto make_connection_pool(ConnectionSource &&source, const connection_pool_config &config, const ThreadSafety &thread_safety=ThreadSafety{})
Connection pool construct helper function.
Definition: connection_pool.h:403
Handler
Handler concept.
ozo::pooled_connection::is_bad
bool is_bad() const noexcept
Definition: connection_pool.h:169
ozo::connection_pool_config::queue_capacity
std::size_t queue_capacity
maximum number of queued requests to get available connection
Definition: connection_pool.h:22
ozo::pooled_connection::native_handle_type
typename connection_traits< rep_type >::native_handle_type native_handle_type
Native connection handle type.
Definition: connection_pool.h:119
ozo::connection_pool_timeouts
[[DEPRECATED]] Timeouts for the ozo::get_connection() operation
Definition: connection_pool.h:34
ozo::connection_pool_timeouts::connect
time_traits::duration connect
maximum time interval to establish to or wait for free connection with DBMS
Definition: connection_pool.h:35
ozo::pooled_connection::oid_map_type
typename connection_traits< rep_type >::oid_map_type oid_map_type
Oid map of types that are used with the connection.
Definition: connection_pool.h:120
ozo::pooled_connection::error_context_type
typename connection_traits< rep_type >::error_context_type error_context_type
Additional error context which could provide context depended information for errors.
Definition: connection_pool.h:121
ozo::get_error_context
const auto & get_error_context(const Connection &conn)
Get additional error context.
Definition: connection.h:124