![]() |
|
|||
Warning, file /include/boost/mysql/connection_pool.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 // 0002 // Copyright (c) 2019-2024 Ruben Perez Hidalgo (rubenperez038 at gmail dot com) 0003 // 0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying 0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0006 // 0007 0008 #ifndef BOOST_MYSQL_CONNECTION_POOL_HPP 0009 #define BOOST_MYSQL_CONNECTION_POOL_HPP 0010 0011 #include <boost/mysql/any_connection.hpp> 0012 #include <boost/mysql/diagnostics.hpp> 0013 #include <boost/mysql/error_code.hpp> 0014 #include <boost/mysql/pool_params.hpp> 0015 0016 #include <boost/mysql/detail/access.hpp> 0017 #include <boost/mysql/detail/config.hpp> 0018 #include <boost/mysql/detail/connection_pool_fwd.hpp> 0019 0020 #include <boost/asio/any_completion_handler.hpp> 0021 #include <boost/asio/any_io_executor.hpp> 0022 #include <boost/asio/async_result.hpp> 0023 0024 #include <chrono> 0025 #include <memory> 0026 #include <utility> 0027 0028 namespace boost { 0029 namespace mysql { 0030 0031 /** 0032 * \brief (EXPERIMENTAL) A proxy to a connection owned by a pool that returns it to the pool when destroyed. 0033 * \details 0034 * A `pooled_connection` behaves like to a `std::unique_ptr`: it has exclusive ownership of an 0035 * \ref any_connection created by the pool. When destroyed, it returns the connection to the pool. 0036 * A `pooled_connection` may own nothing. We say such a connection is invalid (`this->valid() == false`). 0037 * \n 0038 * This class is movable but not copyable. 0039 * 0040 * \par Object lifetimes 0041 * While `*this` is alive, the \ref connection_pool internal data will be kept alive 0042 * automatically. It's safe to destroy the `connection_pool` object before `*this`. 0043 * 0044 * \par Thread safety 0045 * By default, individual connections created by the pool are **not** thread-safe, 0046 * even if the pool was created using \ref pool_executor_params::thread_safe. 0047 * \n 0048 * Distinct objects: safe. \n 0049 * Shared objects: unsafe. \n 0050 * 0051 * \par Experimental 0052 * This part of the API is experimental, and may change in successive 0053 * releases without previous notice. 0054 */ 0055 class pooled_connection 0056 { 0057 #ifndef BOOST_MYSQL_DOXYGEN 0058 friend struct detail::access; 0059 friend class detail::basic_pool_impl<detail::io_traits, pooled_connection>; 0060 #endif 0061 0062 detail::connection_node* impl_{nullptr}; 0063 std::shared_ptr<detail::pool_impl> pool_impl_; 0064 0065 pooled_connection(detail::connection_node& node, std::shared_ptr<detail::pool_impl> pool_impl) noexcept 0066 : impl_(&node), pool_impl_(std::move(pool_impl)) 0067 { 0068 } 0069 0070 public: 0071 /** 0072 * \brief Constructs an invalid pooled connection. 0073 * \details 0074 * The resulting object is invalid (`this->valid() == false`). 0075 * 0076 * \par Exception safety 0077 * No-throw guarantee. 0078 */ 0079 pooled_connection() noexcept = default; 0080 0081 /** 0082 * \brief Move constructor. 0083 * \details 0084 * Transfers connection ownership from `other` to `*this`. 0085 * \n 0086 * After this function returns, if `other.valid() == true`, `this->valid() == true`. 0087 * In any case, `other` will become invalid (`other.valid() == false`). 0088 * 0089 * \par Exception safety 0090 * No-throw guarantee. 0091 */ 0092 pooled_connection(pooled_connection&& other) noexcept 0093 : impl_(other.impl_), pool_impl_(std::move(other.pool_impl_)) 0094 { 0095 other.impl_ = nullptr; 0096 } 0097 0098 /** 0099 * \brief Move assignment. 0100 * \details 0101 * If `this->valid()`, returns the connection owned by `*this` to the pool and marks 0102 * it as pending reset (as if the destructor was called). 0103 * It then transfers connection ownership from `other` to `*this`. 0104 * \n 0105 * After this function returns, if `other.valid() == true`, `this->valid() == true`. 0106 * In any case, `other` will become invalid (`other.valid() == false`). 0107 * 0108 * \par Exception safety 0109 * No-throw guarantee. 0110 */ 0111 pooled_connection& operator=(pooled_connection&& other) noexcept 0112 { 0113 if (impl_) 0114 detail::return_connection(std::move(pool_impl_), *impl_, true); 0115 impl_ = other.impl_; 0116 other.impl_ = nullptr; 0117 pool_impl_ = std::move(other.pool_impl_); 0118 return *this; 0119 } 0120 0121 #ifndef BOOST_MYSQL_DOXYGEN 0122 pooled_connection(const pooled_connection&) = delete; 0123 pooled_connection& operator=(const pooled_connection&) = delete; 0124 #endif 0125 0126 /** 0127 * \brief Destructor. 0128 * \details 0129 * If `this->valid() == true`, returns the owned connection to the pool 0130 * and marks it as pending reset. If your connection doesn't need to be reset 0131 * (e.g. because you didn't mutate session state), use \ref return_without_reset. 0132 * 0133 * \par Thead-safety 0134 * If the \ref connection_pool object that `*this` references has been constructed 0135 * with adequate executor configuration, this function is safe to be called concurrently 0136 * with \ref connection_pool::async_run, \ref connection_pool::async_get_connection, 0137 * \ref connection_pool::cancel and \ref return_without_reset on other `pooled_connection` objects. 0138 */ 0139 ~pooled_connection() 0140 { 0141 if (impl_) 0142 detail::return_connection(std::move(pool_impl_), *impl_, true); 0143 } 0144 0145 /** 0146 * \brief Returns whether the object owns a connection or not. 0147 * \par Exception safety 0148 * No-throw guarantee. 0149 */ 0150 bool valid() const noexcept { return impl_ != nullptr; } 0151 0152 /** 0153 * \brief Retrieves the connection owned by this object. 0154 * \par Preconditions 0155 * The object should own a connection (`this->valid() == true`). 0156 * 0157 * \par Object lifetimes 0158 * The returned reference is valid as long as `*this` or an object 0159 * move-constructed or move-assigned from `*this` is alive. 0160 * 0161 * \par Exception safety 0162 * No-throw guarantee. 0163 */ 0164 any_connection& get() noexcept { return detail::get_connection(*impl_); } 0165 0166 /// \copydoc get 0167 const any_connection& get() const noexcept { return detail::get_connection(*impl_); } 0168 0169 /// \copydoc get 0170 any_connection* operator->() noexcept { return &get(); } 0171 0172 /// \copydoc get 0173 const any_connection* operator->() const noexcept { return &get(); } 0174 0175 /** 0176 * \brief Returns the owned connection to the pool and marks it as not requiring reset. 0177 * \details 0178 * Returns a connection to the pool and marks it as idle. This will 0179 * skip the \ref any_connection::async_reset_connection call to wipe session state. 0180 * \n 0181 * This can provide a performance gain, but must be used with care. Failing to wipe 0182 * session state can lead to resource leaks (prepared statements not being released), 0183 * incorrect results and vulnerabilities (different logical operations interacting due 0184 * to leftover state). 0185 * \n 0186 * Please read the documentation on \ref any_connection::async_reset_connection before 0187 * calling this function. If in doubt, don't use it, and leave the destructor return 0188 * the connection to the pool for you. 0189 * \n 0190 * When this function returns, `*this` will own nothing (`this->valid() == false`). 0191 * 0192 * \par Preconditions 0193 * `this->valid() == true` 0194 * 0195 * \par Exception safety 0196 * No-throw guarantee. 0197 * 0198 * \par Thead-safety 0199 * If the \ref connection_pool object that `*this` references has been constructed 0200 * with adequate executor configuration, this function is safe to be called concurrently 0201 * with \ref connection_pool::async_run, \ref connection_pool::async_get_connection, 0202 * \ref connection_pool::cancel and `~pooled_connection`. 0203 */ 0204 void return_without_reset() noexcept 0205 { 0206 BOOST_ASSERT(valid()); 0207 detail::return_connection(std::move(pool_impl_), *impl_, false); 0208 impl_ = nullptr; 0209 } 0210 }; 0211 0212 /** 0213 * \brief (EXPERIMENTAL) A pool of connections of variable size. 0214 * \details 0215 * A connection pool creates and manages \ref any_connection objects. 0216 * Using a pool allows to reuse sessions, avoiding part of the overhead associated 0217 * to session establishment. It also features built-in error handling and reconnection. 0218 * See the discussion and examples for more details on when to use this class. 0219 * \n 0220 * Connections are retrieved by \ref async_get_connection, which yields a 0221 * \ref pooled_connection object. They are returned to the pool when the 0222 * `pooled_connection` is destroyed, or by calling \ref pooled_connection::return_without_reset. 0223 * \n 0224 * A pool needs to be run before it can return any connection. Use \ref async_run for this. 0225 * Pools can only be run once. 0226 * \n 0227 * Connections are created, connected and managed internally by the pool, following 0228 * a well-defined state model. Please refer to the discussion for details. 0229 * \n 0230 * Due to oddities in Boost.Asio's universal async model, this class only 0231 * exposes async functions. You can use `asio::use_future` to transform them 0232 * into sync functions (please read the discussion for details). 0233 * \n 0234 * This is a move-only type. 0235 * 0236 * \par Thread-safety 0237 * By default, connection pools are *not* thread-safe, but most functions can 0238 * be made thread-safe by passing an adequate \ref pool_executor_params objects 0239 * to the constructor. See \ref pool_executor_params::thread_safe and the discussion 0240 * for details. 0241 * \n 0242 * Distinct objects: safe. \n 0243 * Shared objects: unsafe, unless passing adequate values to the constructor. 0244 * 0245 * \par Object lifetimes 0246 * Connection pool objects create an internal state object that is referenced 0247 * by other objects and operations (like \ref pooled_connection). This object 0248 * will be kept alive using shared ownership semantics even after the `connection_pool` 0249 * object is destroyed. This results in intuitive lifetime rules. 0250 * 0251 * \par Experimental 0252 * This part of the API is experimental, and may change in successive 0253 * releases without previous notice. 0254 */ 0255 class connection_pool 0256 { 0257 std::shared_ptr<detail::pool_impl> impl_; 0258 0259 #ifndef BOOST_MYSQL_DOXYGEN 0260 friend struct detail::access; 0261 #endif 0262 0263 static constexpr std::chrono::steady_clock::duration get_default_timeout() noexcept 0264 { 0265 return std::chrono::seconds(30); 0266 } 0267 0268 struct initiate_run 0269 { 0270 template <class Handler> 0271 void operator()(Handler&& h, std::shared_ptr<detail::pool_impl> self) 0272 { 0273 async_run_erased(std::move(self), std::forward<Handler>(h)); 0274 } 0275 }; 0276 0277 BOOST_MYSQL_DECL 0278 static void async_run_erased( 0279 std::shared_ptr<detail::pool_impl> pool, 0280 asio::any_completion_handler<void(error_code)> handler 0281 ); 0282 0283 struct initiate_get_connection 0284 { 0285 template <class Handler> 0286 void operator()( 0287 Handler&& h, 0288 std::shared_ptr<detail::pool_impl> self, 0289 std::chrono::steady_clock::duration timeout, 0290 diagnostics* diag 0291 ) 0292 { 0293 async_get_connection_erased(std::move(self), timeout, diag, std::forward<Handler>(h)); 0294 } 0295 }; 0296 0297 BOOST_MYSQL_DECL 0298 static void async_get_connection_erased( 0299 std::shared_ptr<detail::pool_impl> pool, 0300 std::chrono::steady_clock::duration timeout, 0301 diagnostics* diag, 0302 asio::any_completion_handler<void(error_code, pooled_connection)> handler 0303 ); 0304 0305 template <class CompletionToken> 0306 auto async_get_connection_impl( 0307 std::chrono::steady_clock::duration timeout, 0308 diagnostics* diag, 0309 CompletionToken&& token 0310 ) 0311 -> decltype(asio::async_initiate<CompletionToken, void(error_code, pooled_connection)>( 0312 initiate_get_connection{}, 0313 token, 0314 impl_, 0315 timeout, 0316 diag 0317 )) 0318 { 0319 BOOST_ASSERT(valid()); 0320 return asio::async_initiate<CompletionToken, void(error_code, pooled_connection)>( 0321 initiate_get_connection{}, 0322 token, 0323 impl_, 0324 timeout, 0325 diag 0326 ); 0327 } 0328 0329 BOOST_MYSQL_DECL 0330 connection_pool(pool_executor_params&& ex_params, pool_params&& params, int); 0331 0332 public: 0333 /** 0334 * \brief Constructs a connection pool. 0335 * \details 0336 * Internal I/O objects (like timers) are constructed using 0337 * `ex_params.pool_executor`. Connections are constructed using 0338 * `ex_params.connection_executor`. This can be used to create 0339 * thread-safe pools. 0340 * \n 0341 * The pool is created in a "not-running" state. Call \ref async_run to transition to the 0342 * "running" state. Calling \ref async_get_connection in the "not-running" state will fail 0343 * with \ref client_errc::cancelled. 0344 * \n 0345 * The constructed pool is always valid (`this->valid() == true`). 0346 * 0347 * \par Exception safety 0348 * Strong guarantee. Exceptions may be thrown by memory allocations. 0349 * \throws std::invalid_argument If `params` contains values that violate the rules described in \ref 0350 * pool_params. 0351 */ 0352 connection_pool(pool_executor_params ex_params, pool_params params) 0353 : connection_pool(std::move(ex_params), std::move(params), 0) 0354 { 0355 } 0356 0357 /** 0358 * \brief Constructs a connection pool. 0359 * \details 0360 * Both internal I/O objects and connections are constructed using the passed executor. 0361 * \n 0362 * The pool is created in a "not-running" state. Call \ref async_run to transition to the 0363 * "running" state. Calling \ref async_get_connection in the "not-running" state will fail 0364 * with \ref client_errc::cancelled. 0365 * \n 0366 * The constructed pool is always valid (`this->valid() == true`). 0367 * 0368 * \par Exception safety 0369 * Strong guarantee. Exceptions may be thrown by memory allocations. 0370 * \throws std::invalid_argument If `params` contains values that violate the rules described in \ref 0371 * pool_params. 0372 */ 0373 connection_pool(asio::any_io_executor ex, pool_params params) 0374 : connection_pool(pool_executor_params{ex, ex}, std::move(params), 0) 0375 { 0376 } 0377 0378 /** 0379 * \brief Constructs a connection pool. 0380 * \details 0381 * Both internal I/O objects and connections are constructed using `ctx.get_executor()`. 0382 * \n 0383 * The pool is created in a "not-running" state. Call \ref async_run to transition to the 0384 * "running" state. Calling \ref async_get_connection in the "not-running" state will fail 0385 * with \ref client_errc::cancelled. 0386 * \n 0387 * The constructed pool is always valid (`this->valid() == true`). 0388 * \n 0389 * This function participates in overload resolution only if `ExecutionContext` 0390 * satisfies the `ExecutionContext` requirements imposed by Boost.Asio. 0391 * 0392 * \par Exception safety 0393 * Strong guarantee. Exceptions may be thrown by memory allocations. 0394 * \throws std::invalid_argument If `params` contains values that violate the rules described in \ref 0395 * pool_params. 0396 */ 0397 template < 0398 class ExecutionContext 0399 #ifndef BOOST_MYSQL_DOXYGEN 0400 , 0401 class = typename std::enable_if<std::is_convertible< 0402 decltype(std::declval<ExecutionContext&>().get_executor()), 0403 asio::any_io_executor>::value>::type 0404 #endif 0405 > 0406 connection_pool(ExecutionContext& ctx, pool_params params) 0407 : connection_pool({ctx.get_executor(), ctx.get_executor()}, std::move(params), 0) 0408 { 0409 } 0410 0411 #ifndef BOOST_MYSQL_DOXYGEN 0412 connection_pool(const connection_pool&) = delete; 0413 connection_pool& operator=(const connection_pool&) = delete; 0414 #endif 0415 0416 /** 0417 * \brief Move-constructor. 0418 * \details 0419 * Constructs a connection pool by taking ownership of `other`. 0420 * \n 0421 * After this function returns, if `other.valid() == true`, `this->valid() == true`. 0422 * In any case, `other` will become invalid (`other.valid() == false`). 0423 * \n 0424 * Moving a connection pool with outstanding async operations 0425 * is safe. 0426 * 0427 * \par Exception safety 0428 * No-throw guarantee. 0429 * 0430 * \par Thead-safety 0431 * This function is never thread-safe, regardless of the executor 0432 * configuration passed to the constructor. Calling this function 0433 * concurrently with any other function introduces data races. 0434 */ 0435 connection_pool(connection_pool&& other) = default; 0436 0437 /** 0438 * \brief Move assignment. 0439 * \details 0440 * Assigns `other` to `*this`, transferring ownership. 0441 * \n 0442 * After this function returns, if `other.valid() == true`, `this->valid() == true`. 0443 * In any case, `other` will become invalid (`other.valid() == false`). 0444 * \n 0445 * Moving a connection pool with outstanding async operations 0446 * is safe. 0447 * 0448 * \par Exception safety 0449 * No-throw guarantee. 0450 * 0451 * \par Thead-safety 0452 * This function is never thread-safe, regardless of the executor 0453 * configuration passed to the constructor. Calling this function 0454 * concurrently with any other function introduces data races. 0455 */ 0456 connection_pool& operator=(connection_pool&& other) = default; 0457 0458 /// Destructor. 0459 ~connection_pool() = default; 0460 0461 /** 0462 * \brief Returns whether the object is in a moved-from state. 0463 * \details 0464 * This function returns always `true` except for pools that have been 0465 * moved-from. Moved-from objects don't represent valid pools. They can only 0466 * be assigned to or destroyed. 0467 * 0468 * \par Exception safety 0469 * No-throw guarantee. 0470 * 0471 * \par Thead-safety 0472 * This function is never thread-safe, regardless of the executor 0473 * configuration passed to the constructor. Calling this function 0474 * concurrently with any other function introduces data races. 0475 */ 0476 bool valid() const noexcept { return impl_.get() != nullptr; } 0477 0478 /// The executor type associated to this object. 0479 using executor_type = asio::any_io_executor; 0480 0481 /** 0482 * \brief Retrieves the executor associated to this object. 0483 * \details 0484 * Returns the pool executor passed to the constructor, as per 0485 * \ref pool_executor_params::pool_executor. 0486 * 0487 * \par Exception safety 0488 * No-throw guarantee. 0489 * 0490 * \par Thead-safety 0491 * This function is never thread-safe, regardless of the executor 0492 * configuration passed to the constructor. Calling this function 0493 * concurrently with any other function introduces data races. 0494 */ 0495 BOOST_MYSQL_DECL 0496 executor_type get_executor() noexcept; 0497 0498 /** 0499 * \brief Runs the pool task in charge of managing connections. 0500 * \details 0501 * This function creates and connects new connections, and resets and pings 0502 * already created ones. You need to call this function for \ref async_get_connection 0503 * to succeed. 0504 * \n 0505 * The async operation will run indefinitely, until the pool is cancelled 0506 * (by being destroyed or calling \ref cancel). The operation completes once 0507 * all internal connection operations (including connects, pings and resets) 0508 * complete. 0509 * \n 0510 * It is safe to call this function after calling \ref cancel. 0511 * 0512 * \par Preconditions 0513 * This function can be called at most once for a single pool. 0514 * Formally, `async_run` hasn't been called before on `*this` or any object 0515 * used to move-construct or move-assign `*this`. 0516 * \n 0517 * Additionally, `this->valid() == true`. 0518 * 0519 * \par Object lifetimes 0520 * While the operation is outstanding, the pool's internal data will be kept alive. 0521 * It is safe to destroy `*this` while the operation is outstanding. 0522 * 0523 * \par Handler signature 0524 * The handler signature for this operation is `void(boost::mysql::error_code)` 0525 * 0526 * \par Errors 0527 * This function always complete successfully. The handler signature ensures 0528 * maximum compatibility with Boost.Asio infrastructure. 0529 * 0530 * \par Executor 0531 * This function will run entirely in the pool's executor (as given by `this->get_executor()`). 0532 * No internal data will be accessed or modified as part of the initiating function. 0533 * This simplifies thread-safety. 0534 * 0535 * \par Thead-safety 0536 * When the pool is constructed with adequate executor configuration, this function 0537 * is safe to be called concurrently with \ref async_get_connection, \ref cancel, 0538 * `~pooled_connection` and \ref pooled_connection::return_without_reset. 0539 */ 0540 template <BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code)) CompletionToken> 0541 auto async_run(CompletionToken&& token) BOOST_MYSQL_RETURN_TYPE( 0542 decltype(asio::async_initiate<CompletionToken, void(error_code)>(initiate_run{}, token, impl_)) 0543 ) 0544 { 0545 BOOST_ASSERT(valid()); 0546 return asio::async_initiate<CompletionToken, void(error_code)>(initiate_run{}, token, impl_); 0547 } 0548 0549 /// \copydoc async_get_connection(diagnostics&,CompletionToken&&) 0550 template < 0551 BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, ::boost::mysql::pooled_connection)) 0552 CompletionToken> 0553 auto async_get_connection(CompletionToken&& token) BOOST_MYSQL_RETURN_TYPE( 0554 decltype(async_get_connection_impl({}, nullptr, std::forward<CompletionToken>(token))) 0555 ) 0556 { 0557 return async_get_connection_impl( 0558 get_default_timeout(), 0559 nullptr, 0560 std::forward<CompletionToken>(token) 0561 ); 0562 } 0563 0564 /** 0565 * \brief Retrieves a connection from the pool. 0566 * \details 0567 * Retrieves an idle connection from the pool to be used. 0568 * \n 0569 * If this function completes successfully (empty error code), the return \ref pooled_connection 0570 * will have `valid() == true` and will be usable. If it completes with a non-empty error code, 0571 * it will have `valid() == false`. 0572 * \n 0573 * If a connection is idle when the operation is started, it will complete immediately 0574 * with that connection. Otherwise, it will wait for a connection to become idle 0575 * (possibly creating one in the process, if pool configuration allows it), up to 0576 * a duration of 30 seconds. 0577 * \n 0578 * If a timeout happens because connection establishment has failed, appropriate 0579 * diagnostics will be returned. 0580 * 0581 * \par Preconditions 0582 * `this->valid() == true` \n 0583 * 0584 * \par Object lifetimes 0585 * While the operation is outstanding, the pool's internal data will be kept alive. 0586 * It is safe to destroy `*this` while the operation is outstanding. 0587 * 0588 * \par Handler signature 0589 * The handler signature for this operation is 0590 * `void(boost::mysql::error_code, boost::mysql::pooled_connection)` 0591 * 0592 * \par Errors 0593 * \li Any error returned by \ref any_connection::async_connect, if a timeout 0594 * happens because connection establishment is failing. 0595 * \li \ref client_errc::timeout, if a timeout happens for any other reason 0596 * (e.g. all connections are in use and limits forbid creating more). 0597 * \li \ref client_errc::cancelled if \ref cancel was called before the operation is started or while 0598 * it is outstanding, or if the pool is not running. 0599 * 0600 * \par Executor 0601 * This function will run entirely in the pool's executor (as given by `this->get_executor()`). 0602 * No internal data will be accessed or modified as part of the initiating function. 0603 * This simplifies thread-safety. 0604 * 0605 * \par Thead-safety 0606 * When the pool is constructed with adequate executor configuration, this function 0607 * is safe to be called concurrently with \ref async_run, \ref cancel, 0608 * `~pooled_connection` and \ref pooled_connection::return_without_reset. 0609 */ 0610 template < 0611 BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, ::boost::mysql::pooled_connection)) 0612 CompletionToken> 0613 auto async_get_connection(diagnostics& diag, CompletionToken&& token) BOOST_MYSQL_RETURN_TYPE( 0614 decltype(async_get_connection_impl({}, nullptr, std::forward<CompletionToken>(token))) 0615 ) 0616 { 0617 return async_get_connection_impl(get_default_timeout(), &diag, std::forward<CompletionToken>(token)); 0618 } 0619 0620 /// \copydoc async_get_connection(std::chrono::steady_clock::duration,diagnostics&,CompletionToken&&) 0621 template < 0622 BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, ::boost::mysql::pooled_connection)) 0623 CompletionToken> 0624 auto async_get_connection(std::chrono::steady_clock::duration timeout, CompletionToken&& token) 0625 BOOST_MYSQL_RETURN_TYPE( 0626 decltype(async_get_connection_impl({}, nullptr, std::forward<CompletionToken>(token))) 0627 ) 0628 { 0629 return async_get_connection_impl(timeout, nullptr, std::forward<CompletionToken>(token)); 0630 } 0631 0632 /** 0633 * \brief Retrieves a connection from the pool. 0634 * \details 0635 * Retrieves an idle connection from the pool to be used. 0636 * \n 0637 * If this function completes successfully (empty error code), the return \ref pooled_connection 0638 * will have `valid() == true` and will be usable. If it completes with a non-empty error code, 0639 * it will have `valid() == false`. 0640 * \n 0641 * If a connection is idle when the operation is started, it will complete immediately 0642 * with that connection. Otherwise, it will wait for a connection to become idle 0643 * (possibly creating one in the process, if pool configuration allows it), up to 0644 * a duration of `timeout`. A zero timeout disables it. 0645 * \n 0646 * If a timeout happens because connection establishment has failed, appropriate 0647 * diagnostics will be returned. 0648 * 0649 * \par Preconditions 0650 * `this->valid() == true` \n 0651 * Timeout values must be positive: `timeout.count() >= 0`. 0652 * 0653 * \par Object lifetimes 0654 * While the operation is outstanding, the pool's internal data will be kept alive. 0655 * It is safe to destroy `*this` while the operation is outstanding. 0656 * 0657 * \par Handler signature 0658 * The handler signature for this operation is 0659 * `void(boost::mysql::error_code, boost::mysql::pooled_connection)` 0660 * 0661 * \par Errors 0662 * \li Any error returned by \ref any_connection::async_connect, if a timeout 0663 * happens because connection establishment is failing. 0664 * \li \ref client_errc::timeout, if a timeout happens for any other reason 0665 * (e.g. all connections are in use and limits forbid creating more). 0666 * \li \ref client_errc::cancelled if \ref cancel was called before the operation is started or while 0667 * it is outstanding, or if the pool is not running. 0668 * 0669 * \par Executor 0670 * This function will run entirely in the pool's executor (as given by `this->get_executor()`). 0671 * No internal data will be accessed or modified as part of the initiating function. 0672 * This simplifies thread-safety. 0673 * 0674 * \par Thead-safety 0675 * When the pool is constructed with adequate executor configuration, this function 0676 * is safe to be called concurrently with \ref async_run, \ref cancel, 0677 * `~pooled_connection` and \ref pooled_connection::return_without_reset. 0678 */ 0679 template < 0680 BOOST_ASIO_COMPLETION_TOKEN_FOR(void(::boost::mysql::error_code, ::boost::mysql::pooled_connection)) 0681 CompletionToken> 0682 auto async_get_connection( 0683 std::chrono::steady_clock::duration timeout, 0684 diagnostics& diag, 0685 CompletionToken&& token 0686 ) 0687 BOOST_MYSQL_RETURN_TYPE( 0688 decltype(async_get_connection_impl({}, nullptr, std::forward<CompletionToken>(token))) 0689 ) 0690 { 0691 return async_get_connection_impl(timeout, &diag, std::forward<CompletionToken>(token)); 0692 } 0693 0694 /** 0695 * \brief Stops any current outstanding operation and marks the pool as cancelled. 0696 * \details 0697 * This function has the following effects: 0698 * \n 0699 * \li Stops the currently outstanding \ref async_run operation, if any, which will complete 0700 * with a success error code. 0701 * \li Cancels any outstanding \ref async_get_connection operations, which will complete with 0702 * \ref client_errc::cancelled. 0703 * \li Marks the pool as cancelled. Successive `async_get_connection` calls will complete 0704 * immediately with \ref client_errc::cancelled. 0705 * \n 0706 * This function will return immediately, without waiting for the cancelled operations to complete. 0707 * \n 0708 * You may call this function any number of times. Successive calls will have no effect. 0709 * 0710 * \par Preconditions 0711 * `this->valid() == true` 0712 * 0713 * \par Exception safety 0714 * Basic guarantee. Memory allocations and acquiring mutexes may throw. 0715 * 0716 * \par Thead-safety 0717 * When the pool is constructed with adequate executor configuration, this function 0718 * is safe to be called concurrently with \ref async_run, \ref async_get_connection, 0719 * `~pooled_connection` and \ref pooled_connection::return_without_reset. 0720 */ 0721 BOOST_MYSQL_DECL 0722 void cancel(); 0723 }; 0724 0725 } // namespace mysql 0726 } // namespace boost 0727 0728 #ifdef BOOST_MYSQL_HEADER_ONLY 0729 #include <boost/mysql/impl/connection_pool.ipp> 0730 #endif 0731 0732 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |