remove global vars

This commit is contained in:
jie 2021-07-14 14:16:00 +08:00
parent 11c681acf3
commit 41e0fe4c11
7 changed files with 120 additions and 89 deletions

View File

@ -13,7 +13,6 @@
#include <chrono> #include <chrono>
#include <exception> #include <exception>
#include "router.hpp"
#include "logging.hpp" #include "logging.hpp"
namespace bserv { namespace bserv {
@ -24,6 +23,9 @@ namespace asio = boost::asio;
namespace json = boost::json; namespace json = boost::json;
using asio::ip::tcp; using asio::ip::tcp;
using request_type = http::request<http::string_body>;
using response_type = http::response<http::string_body>;
class request_failed_exception class request_failed_exception
: public std::exception { : public std::exception {
private: private:
@ -37,9 +39,9 @@ public:
// sends one async request to a remote server // sends one async request to a remote server
template <typename ResponseType> template <typename ResponseType>
class client_session class http_client_session
: public std::enable_shared_from_this< : public std::enable_shared_from_this<
client_session<ResponseType>> { http_client_session<ResponseType>> {
private: private:
tcp::resolver resolver_; tcp::resolver resolver_;
beast::tcp_stream stream_; beast::tcp_stream stream_;
@ -54,7 +56,7 @@ private:
request_failed_exception{what + ": " + ec.message()})); request_failed_exception{what + ": " + ec.message()}));
} }
public: public:
client_session( http_client_session(
asio::io_context& ioc, asio::io_context& ioc,
const http::request<http::string_body>& req) const http::request<http::string_body>& req)
: resolver_{asio::make_strand(ioc)}, : resolver_{asio::make_strand(ioc)},
@ -65,15 +67,15 @@ public:
resolver_.async_resolve( resolver_.async_resolve(
host, port, host, port,
beast::bind_front_handler( beast::bind_front_handler(
&client_session::on_resolve, &http_client_session::on_resolve,
client_session<ResponseType>::shared_from_this())); http_client_session<ResponseType>::shared_from_this()));
return promise_.get_future(); return promise_.get_future();
} }
void on_resolve( void on_resolve(
beast::error_code ec, beast::error_code ec,
tcp::resolver::results_type results) { tcp::resolver::results_type results) {
if (ec) { if (ec) {
failed(ec, "client_session::resolver resolve"); failed(ec, "http_client_session::resolver resolve");
return; return;
} }
// sets a timeout on the operation // sets a timeout on the operation
@ -82,14 +84,14 @@ public:
stream_.async_connect( stream_.async_connect(
results, results,
beast::bind_front_handler( beast::bind_front_handler(
&client_session::on_connect, &http_client_session::on_connect,
client_session<ResponseType>::shared_from_this())); http_client_session<ResponseType>::shared_from_this()));
} }
void on_connect( void on_connect(
beast::error_code ec, beast::error_code ec,
tcp::resolver::results_type::endpoint_type) { tcp::resolver::results_type::endpoint_type) {
if (ec) { if (ec) {
failed(ec, "client_session::stream connect"); failed(ec, "http_client_session::stream connect");
return; return;
} }
// sets a timeout on the operation // sets a timeout on the operation
@ -98,23 +100,23 @@ public:
http::async_write( http::async_write(
stream_, req_, stream_, req_,
beast::bind_front_handler( beast::bind_front_handler(
&client_session::on_write, &http_client_session::on_write,
client_session<ResponseType>::shared_from_this())); http_client_session<ResponseType>::shared_from_this()));
} }
void on_write( void on_write(
beast::error_code ec, beast::error_code ec,
std::size_t bytes_transferred) { std::size_t bytes_transferred) {
boost::ignore_unused(bytes_transferred); boost::ignore_unused(bytes_transferred);
if (ec) { if (ec) {
failed(ec, "client_session::stream write"); failed(ec, "http_client_session::stream write");
return; return;
} }
// receives the HTTP response // receives the HTTP response
http::async_read( http::async_read(
stream_, buffer_, res_, stream_, buffer_, res_,
beast::bind_front_handler( beast::bind_front_handler(
&client_session::on_read, &http_client_session::on_read,
client_session<ResponseType>::shared_from_this())); http_client_session<ResponseType>::shared_from_this()));
} }
static_assert(std::is_same<ResponseType, http::response<http::string_body>>::value static_assert(std::is_same<ResponseType, http::response<http::string_body>>::value
|| std::is_same<ResponseType, boost::json::value>::value, || std::is_same<ResponseType, boost::json::value>::value,
@ -124,7 +126,7 @@ public:
std::size_t bytes_transferred) { std::size_t bytes_transferred) {
boost::ignore_unused(bytes_transferred); boost::ignore_unused(bytes_transferred);
if (ec) { if (ec) {
failed(ec, "client_session::stream read"); failed(ec, "http_client_session::stream read");
return; return;
} }
if constexpr (std::is_same<ResponseType, http::response<http::string_body>>::value) { if constexpr (std::is_same<ResponseType, http::response<http::string_body>>::value) {
@ -141,25 +143,41 @@ public:
// `not_connected` happens sometimes so don't bother reporting it // `not_connected` happens sometimes so don't bother reporting it
if (ec && ec != beast::errc::not_connected) { if (ec && ec != beast::errc::not_connected) {
// reports the error to the log! // reports the error to the log!
fail(ec, "client_session::stream::socket shutdown"); fail(ec, "http_client_session::stream::socket shutdown");
return; return;
} }
// if we get here then the connection is closed gracefully // if we get here then the connection is closed gracefully
} }
}; };
class client { request_type get_request(
const std::string& host,
const std::string& target,
const http::verb& method,
const boost::json::object& obj) {
request_type req;
req.method(method);
req.target(target);
req.set(http::field::host, host);
req.set(http::field::user_agent, NAME);
req.set(http::field::content_type, "application/json");
req.body() = boost::json::serialize(obj);
req.prepare_payload();
return req;
}
class http_client {
private: private:
asio::io_context& ioc_; asio::io_context& ioc_;
public: public:
client(asio::io_context& ioc) http_client(asio::io_context& ioc)
: ioc_{ioc} {} : ioc_{ioc} {}
std::future<http::response<http::string_body>> request( std::future<http::response<http::string_body>> request(
const std::string& host, const std::string& host,
const std::string& port, const std::string& port,
const http::request<http::string_body>& req) { const http::request<http::string_body>& req) {
return std::make_shared< return std::make_shared<
client_session<http::response<http::string_body>> http_client_session<http::response<http::string_body>>
>(ioc_, req)->send(host, port); >(ioc_, req)->send(host, port);
} }
std::future<boost::json::value> request_for_object( std::future<boost::json::value> request_for_object(
@ -167,30 +185,9 @@ public:
const std::string& port, const std::string& port,
const http::request<http::string_body>& req) { const http::request<http::string_body>& req) {
return std::make_shared< return std::make_shared<
client_session<boost::json::value> http_client_session<boost::json::value>
>(ioc_, req)->send(host, port); >(ioc_, req)->send(host, port);
} }
};
std::shared_ptr<client> client_ptr;
namespace request {
request_type get_request(
const std::string& host,
const std::string& target,
const http::verb& method,
const boost::json::object& obj) {
request_type req;
req.method(method);
req.target(target);
req.set(http::field::host, host);
req.set(http::field::user_agent, NAME);
req.set(http::field::content_type, "application/json");
req.body() = boost::json::serialize(obj);
req.prepare_payload();
return req;
}
std::future<response_type> send( std::future<response_type> send(
const std::string& host, const std::string& host,
@ -199,9 +196,8 @@ namespace request {
const http::verb& method, const http::verb& method,
const boost::json::object& obj) { const boost::json::object& obj) {
request_type req = get_request(host, target, method, obj); request_type req = get_request(host, target, method, obj);
return client_ptr->request(host, port, req); return request(host, port, req);
} }
std::future<boost::json::value> send_for_object( std::future<boost::json::value> send_for_object(
const std::string& host, const std::string& host,
const std::string& port, const std::string& port,
@ -209,9 +205,8 @@ namespace request {
const http::verb& method, const http::verb& method,
const boost::json::object& obj) { const boost::json::object& obj) {
request_type req = get_request(host, target, method, obj); request_type req = get_request(host, target, method, obj);
return client_ptr->request_for_object(host, port, req); return request_for_object(host, port, req);
} }
std::future<response_type> get( std::future<response_type> get(
const std::string& host, const std::string& host,
const std::string& port, const std::string& port,
@ -219,7 +214,6 @@ namespace request {
const boost::json::object& obj) { const boost::json::object& obj) {
return send(host, port, target, http::verb::get, obj); return send(host, port, target, http::verb::get, obj);
} }
std::future<boost::json::value> get_for_object( std::future<boost::json::value> get_for_object(
const std::string& host, const std::string& host,
const std::string& port, const std::string& port,
@ -227,7 +221,6 @@ namespace request {
const boost::json::object& obj) { const boost::json::object& obj) {
return send_for_object(host, port, target, http::verb::get, obj); return send_for_object(host, port, target, http::verb::get, obj);
} }
std::future<response_type> put( std::future<response_type> put(
const std::string& host, const std::string& host,
const std::string& port, const std::string& port,
@ -235,7 +228,6 @@ namespace request {
const boost::json::object& obj) { const boost::json::object& obj) {
return send(host, port, target, http::verb::put, obj); return send(host, port, target, http::verb::put, obj);
} }
std::future<boost::json::value> put_for_object( std::future<boost::json::value> put_for_object(
const std::string& host, const std::string& host,
const std::string& port, const std::string& port,
@ -243,7 +235,6 @@ namespace request {
const boost::json::object& obj) { const boost::json::object& obj) {
return send_for_object(host, port, target, http::verb::put, obj); return send_for_object(host, port, target, http::verb::put, obj);
} }
std::future<response_type> post( std::future<response_type> post(
const std::string& host, const std::string& host,
const std::string& port, const std::string& port,
@ -251,7 +242,6 @@ namespace request {
const boost::json::object& obj) { const boost::json::object& obj) {
return send(host, port, target, http::verb::post, obj); return send(host, port, target, http::verb::post, obj);
} }
std::future<boost::json::value> post_for_object( std::future<boost::json::value> post_for_object(
const std::string& host, const std::string& host,
const std::string& port, const std::string& port,
@ -259,7 +249,6 @@ namespace request {
const boost::json::object& obj) { const boost::json::object& obj) {
return send_for_object(host, port, target, http::verb::post, obj); return send_for_object(host, port, target, http::verb::post, obj);
} }
std::future<response_type> delete_( std::future<response_type> delete_(
const std::string& host, const std::string& host,
const std::string& port, const std::string& port,
@ -267,7 +256,6 @@ namespace request {
const boost::json::object& obj) { const boost::json::object& obj) {
return send(host, port, target, http::verb::delete_, obj); return send(host, port, target, http::verb::delete_, obj);
} }
std::future<boost::json::value> delete_for_object( std::future<boost::json::value> delete_for_object(
const std::string& host, const std::string& host,
const std::string& port, const std::string& port,
@ -275,8 +263,7 @@ namespace request {
const boost::json::object& obj) { const boost::json::object& obj) {
return send_for_object(host, port, target, http::verb::delete_, obj); return send_for_object(host, port, target, http::verb::delete_, obj);
} }
};
} // request
} // bserv } // bserv

View File

@ -88,8 +88,6 @@ db_connection::~db_connection() {
mgr_.counter_lock_.unlock(); mgr_.counter_lock_.unlock();
} }
std::shared_ptr<db_connection_manager> db_conn_mgr;
// ************************************************************************** // **************************************************************************
class db_parameter { class db_parameter {

View File

@ -14,6 +14,7 @@
#include <pqxx/pqxx> #include <pqxx/pqxx>
#include "client.hpp"
#include "database.hpp" #include "database.hpp"
#include "session.hpp" #include "session.hpp"
#include "utils.hpp" #include "utils.hpp"
@ -24,8 +25,11 @@ namespace bserv {
namespace beast = boost::beast; namespace beast = boost::beast;
namespace http = beast::http; namespace http = beast::http;
using request_type = http::request<http::string_body>; struct server_resources {
using response_type = http::response<http::string_body>; std::shared_ptr<session_manager_base> session_mgr;
std::shared_ptr<db_connection_manager> db_conn_mgr;
std::shared_ptr<http_client> http_client_ptr;
};
namespace placeholders { namespace placeholders {
@ -55,7 +59,9 @@ constexpr placeholder<-3> response;
// boost::json::object&& // boost::json::object&&
constexpr placeholder<-4> json_params; constexpr placeholder<-4> json_params;
// std::shared_ptr<bserv::db_connection> // std::shared_ptr<bserv::db_connection>
constexpr placeholder<-5> transaction; constexpr placeholder<-5> db_connection_ptr;
// std::shared_ptr<bserv::http_client>
constexpr placeholder<-6> http_client_ptr;
} // placeholders } // placeholders
@ -116,6 +122,7 @@ struct get_parameter<0, Head, Tail...> {
template <typename Type> template <typename Type>
Type&& get_parameter_data( Type&& get_parameter_data(
server_resources&,
const std::vector<std::string>&, const std::vector<std::string>&,
request_type&, response_type&, Type&& val) { request_type&, response_type&, Type&& val) {
return static_cast<Type&&>(val); return static_cast<Type&&>(val);
@ -123,6 +130,7 @@ Type&& get_parameter_data(
template <int N, std::enable_if_t<(N >= 0), int> = 0> template <int N, std::enable_if_t<(N >= 0), int> = 0>
const std::string& get_parameter_data( const std::string& get_parameter_data(
server_resources&,
const std::vector<std::string>& url_params, const std::vector<std::string>& url_params,
request_type&, response_type&, request_type&, response_type&,
placeholders::placeholder<N>) { placeholders::placeholder<N>) {
@ -130,6 +138,7 @@ const std::string& get_parameter_data(
} }
std::shared_ptr<session_type> get_parameter_data( std::shared_ptr<session_type> get_parameter_data(
server_resources& resources,
const std::vector<std::string>&, const std::vector<std::string>&,
request_type& request, response_type& response, request_type& request, response_type& response,
placeholders::placeholder<-1>) { placeholders::placeholder<-1>) {
@ -142,13 +151,14 @@ std::shared_ptr<session_type> get_parameter_data(
session_id = cookie_dict[SESSION_NAME]; session_id = cookie_dict[SESSION_NAME];
} }
std::shared_ptr<session_type> session_ptr; std::shared_ptr<session_type> session_ptr;
if (session_mgr->get_or_create(session_id, session_ptr)) { if (resources.session_mgr->get_or_create(session_id, session_ptr)) {
response.set(http::field::set_cookie, SESSION_NAME + "=" + session_id); response.set(http::field::set_cookie, SESSION_NAME + "=" + session_id);
} }
return session_ptr; return session_ptr;
} }
request_type& get_parameter_data( request_type& get_parameter_data(
server_resources&,
const std::vector<std::string>&, const std::vector<std::string>&,
request_type& request, response_type&, request_type& request, response_type&,
placeholders::placeholder<-2>) { placeholders::placeholder<-2>) {
@ -156,6 +166,7 @@ request_type& get_parameter_data(
} }
response_type& get_parameter_data( response_type& get_parameter_data(
server_resources&,
const std::vector<std::string>&, const std::vector<std::string>&,
request_type&, response_type& response, request_type&, response_type& response,
placeholders::placeholder<-3>) { placeholders::placeholder<-3>) {
@ -163,6 +174,7 @@ response_type& get_parameter_data(
} }
boost::json::object get_parameter_data( boost::json::object get_parameter_data(
server_resources&,
const std::vector<std::string>&, const std::vector<std::string>&,
request_type& request, response_type&, request_type& request, response_type&,
placeholders::placeholder<-4>) { placeholders::placeholder<-4>) {
@ -195,10 +207,19 @@ boost::json::object get_parameter_data(
} }
std::shared_ptr<db_connection> get_parameter_data( std::shared_ptr<db_connection> get_parameter_data(
server_resources& resources,
const std::vector<std::string>&, const std::vector<std::string>&,
request_type&, response_type&, request_type&, response_type&,
placeholders::placeholder<-5>) { placeholders::placeholder<-5>) {
return db_conn_mgr->get_or_block(); return resources.db_conn_mgr->get_or_block();
}
std::shared_ptr<http_client> get_parameter_data(
server_resources& resources,
const std::vector<std::string>&,
request_type&, response_type&,
placeholders::placeholder<-6>) {
return resources.http_client_ptr;
} }
template <int Idx, typename Func, typename Params, typename ...Args> template <int Idx, typename Func, typename Params, typename ...Args>
@ -206,15 +227,16 @@ struct path_handler;
template <int Idx, typename Ret, typename ...Args, typename ...Params> template <int Idx, typename Ret, typename ...Args, typename ...Params>
struct path_handler<Idx, Ret (*)(Args ...), parameter_pack<Params...>> { struct path_handler<Idx, Ret (*)(Args ...), parameter_pack<Params...>> {
Ret invoke(Ret (*pf)(Args ...), parameter_pack<Params...>& params, Ret invoke(server_resources& resources,
Ret (*pf)(Args ...), parameter_pack<Params...>& params,
const std::vector<std::string>& url_params, const std::vector<std::string>& url_params,
request_type& request, response_type& response) { request_type& request, response_type& response) {
if constexpr (Idx == 0) return (*pf)(); if constexpr (Idx == 0) return (*pf)();
else return static_cast<path_handler< else return static_cast<path_handler<
Idx - 1, Ret (*)(Args ...), parameter_pack<Params...>, Idx - 1, Ret (*)(Args ...), parameter_pack<Params...>,
typename get_parameter<Idx - 1, Params...>::type>* typename get_parameter<Idx - 1, Params...>::type>*
>(this)->invoke2(pf, params, url_params, request, response, >(this)->invoke2(resources, pf, params, url_params, request, response,
get_parameter_data(url_params, request, response, get_parameter_data(resources, url_params, request, response,
get_parameter_value<Idx - 1>(params))); get_parameter_value<Idx - 1>(params)));
} }
}; };
@ -228,7 +250,8 @@ struct path_handler<Idx, Ret (*)(Args ...),
template < template <
typename Head2, typename ...Tail2, typename Head2, typename ...Tail2,
std::enable_if_t<sizeof...(Tail2) == sizeof...(Tail), int> = 0> std::enable_if_t<sizeof...(Tail2) == sizeof...(Tail), int> = 0>
Ret invoke2(Ret (*pf)(Args ...), parameter_pack<Params...>& params, Ret invoke2(server_resources& resources,
Ret (*pf)(Args ...), parameter_pack<Params...>& params,
const std::vector<std::string>& url_params, const std::vector<std::string>& url_params,
request_type& request, response_type& response, request_type& request, response_type& response,
Head2&& head2, Tail2&& ...tail2) { Head2&& head2, Tail2&& ...tail2) {
@ -238,8 +261,8 @@ struct path_handler<Idx, Ret (*)(Args ...),
else return static_cast<path_handler< else return static_cast<path_handler<
Idx - 1, Ret (*)(Args ...), parameter_pack<Params...>, Idx - 1, Ret (*)(Args ...), parameter_pack<Params...>,
typename get_parameter<Idx - 1, Params...>::type, Head, Tail...>* typename get_parameter<Idx - 1, Params...>::type, Head, Tail...>*
>(this)->invoke2(pf, params, url_params, request, response, >(this)->invoke2(resources, pf, params, url_params, request, response,
get_parameter_data(url_params, request, response, get_parameter_data(resources, url_params, request, response,
get_parameter_value<Idx - 1>(params)), get_parameter_value<Idx - 1>(params)),
static_cast<Head2&&>(head2), static_cast<Tail2&&>(tail2)...); static_cast<Head2&&>(head2), static_cast<Tail2&&>(tail2)...);
} }
@ -265,6 +288,7 @@ struct path_holder : std::enable_shared_from_this<path_holder> {
const std::string&, const std::string&,
std::vector<std::string>&) const = 0; std::vector<std::string>&) const = 0;
virtual std::optional<boost::json::value> invoke( virtual std::optional<boost::json::value> invoke(
server_resources&,
const std::vector<std::string>&, const std::vector<std::string>&,
request_type&, response_type&) = 0; request_type&, response_type&) = 0;
}; };
@ -295,9 +319,11 @@ public:
return matched; return matched;
} }
std::optional<boost::json::value> invoke( std::optional<boost::json::value> invoke(
server_resources& resources,
const std::vector<std::string>& url_params, const std::vector<std::string>& url_params,
request_type& request, response_type& response) { request_type& request, response_type& response) {
return handler_.invoke( return handler_.invoke(
resources,
pf_, params_, url_params, pf_, params_, url_params,
request, response); request, response);
} }
@ -335,15 +361,19 @@ class router {
private: private:
using path_holder_type = std::shared_ptr<router_internal::path_holder>; using path_holder_type = std::shared_ptr<router_internal::path_holder>;
std::vector<path_holder_type> paths_; std::vector<path_holder_type> paths_;
std::shared_ptr<server_resources> resources_;
public: public:
router(const std::initializer_list<path_holder_type>& paths) router(const std::initializer_list<path_holder_type>& paths)
: paths_{paths} {} : paths_{paths} {}
void set_resources(std::shared_ptr<server_resources> resources) {
resources_ = resources;
}
std::optional<boost::json::value> operator()( std::optional<boost::json::value> operator()(
const std::string& url, request_type& request, response_type& response) { const std::string& url, request_type& request, response_type& response) {
std::vector<std::string> url_params; std::vector<std::string> url_params;
for (auto& ptr : paths_) { for (auto& ptr : paths_) {
if (ptr->match(url, url_params)) if (ptr->match(url, url_params))
return ptr->invoke(url_params, request, response); return ptr->invoke(*resources_, url_params, request, response);
} }
throw url_not_found_exception{}; throw url_not_found_exception{};
} }

View File

@ -320,22 +320,32 @@ private:
// io_context for all I/O // io_context for all I/O
asio::io_context ioc_; asio::io_context ioc_;
router routes_; router routes_;
std::shared_ptr<session_manager_base> session_mgr_;
std::shared_ptr<db_connection_manager> db_conn_mgr_;
std::shared_ptr<http_client> http_client_ptr_;
public: public:
server(const server_config& config, router&& routes) server(const server_config& config, router&& routes)
: ioc_{config.get_num_threads()}, routes_{routes} { : ioc_{config.get_num_threads()},
routes_{std::move(routes)} {
init_logging(config); init_logging(config);
// database connection // database connection
try { try {
db_conn_mgr = std::make_shared< db_conn_mgr_ = std::make_shared<
db_connection_manager>(config.get_db_conn_str(), config.get_num_db_conn()); db_connection_manager>(config.get_db_conn_str(), config.get_num_db_conn());
} catch (const std::exception& e) { } catch (const std::exception& e) {
lgfatal << "db connection initialization failed: " << e.what() << std::endl; lgfatal << "db connection initialization failed: " << e.what() << std::endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
session_mgr = std::make_shared<memory_session>(); session_mgr_ = std::make_shared<memory_session_manager>();
http_client_ptr_ = std::make_shared<http_client>(ioc_);
client_ptr = std::make_shared<client>(ioc_); std::shared_ptr<server_resources> resources_ptr = std::make_shared<server_resources>();
resources_ptr->session_mgr = session_mgr_;
resources_ptr->db_conn_mgr = db_conn_mgr_;
resources_ptr->http_client_ptr = http_client_ptr_;
routes_.set_resources(resources_ptr);
// creates and launches a listening port // creates and launches a listening port
std::make_shared<listener>( std::make_shared<listener>(

View File

@ -23,9 +23,9 @@ const std::string SESSION_NAME = "bsessionid";
// using session_type = std::map<std::string, boost::json::value>; // using session_type = std::map<std::string, boost::json::value>;
using session_type = boost::json::object; using session_type = boost::json::object;
struct session_base struct session_manager_base
: std::enable_shared_from_this<session_base> { : std::enable_shared_from_this<session_manager_base> {
virtual ~session_base() = default; virtual ~session_manager_base() = default;
// if `key` refers to an existing session, that session will be placed in // if `key` refers to an existing session, that session will be placed in
// `session_ptr` and this function will return `false`. // `session_ptr` and this function will return `false`.
// otherwise, this function will create a new session, place the created // otherwise, this function will create a new session, place the created
@ -39,9 +39,7 @@ struct session_base
std::shared_ptr<session_type>& session_ptr) = 0; std::shared_ptr<session_type>& session_ptr) = 0;
}; };
std::shared_ptr<session_base> session_mgr; class memory_session_manager : public session_manager_base {
class memory_session : public session_base {
private: private:
using time_point = std::chrono::steady_clock::time_point; using time_point = std::chrono::steady_clock::time_point;
std::mt19937 rng_; std::mt19937 rng_;
@ -58,7 +56,7 @@ private:
std::set<std::pair<time_point, std::size_t>> queue_; std::set<std::pair<time_point, std::size_t>> queue_;
mutable std::mutex lock_; mutable std::mutex lock_;
public: public:
memory_session() memory_session_manager()
: rng_{utils::internal::get_rd_value()}, : rng_{utils::internal::get_rd_value()},
dist_{0, std::numeric_limits<std::size_t>::max()} {} dist_{0, std::numeric_limits<std::size_t>::max()} {}
bool get_or_create( bool get_or_create(

View File

@ -209,10 +209,10 @@ boost::json::object user_logout(
}; };
} }
boost::json::object send_request() { boost::json::object send_request(std::shared_ptr<bserv::http_client> client_ptr) {
// post for response: // post for response:
// auto res = bserv::request::post( // auto res = client_ptr->post(
// "localhost", "8081", "/test", {{"msg", "request"}} // "localhost", "8080", "/echo", {{"msg", "request"}}
// ).get(); // ).get();
// return {{"response", boost::json::parse(res.body())}}; // return {{"response", boost::json::parse(res.body())}};
// ------------------------------------------------------- // -------------------------------------------------------
@ -221,10 +221,15 @@ boost::json::object send_request() {
// ------------------------------------------------------- // -------------------------------------------------------
// post for json response (json value, rather than json // post for json response (json value, rather than json
// object, is returned): // object, is returned):
auto obj = bserv::request::post_for_object( auto obj = client_ptr->post_for_object(
"localhost", "8081", "/test", {{"msg", "request"}} "localhost", "8080", "/echo", {{"msg", "request"}}
).get(); ).get();
return {{"response", obj}}; return {{"response", obj}};
} }
boost::json::object echo(
boost::json::object&& params) {
return params;
}
#endif // _HANDLERS_HPP #endif // _HANDLERS_HPP

View File

@ -108,18 +108,21 @@ int main(int argc, char* argv[]) {
bserv::make_path("/register", &user_register, bserv::make_path("/register", &user_register,
bserv::placeholders::request, bserv::placeholders::request,
bserv::placeholders::json_params, bserv::placeholders::json_params,
bserv::placeholders::transaction), bserv::placeholders::db_connection_ptr),
bserv::make_path("/login", &user_login, bserv::make_path("/login", &user_login,
bserv::placeholders::request, bserv::placeholders::request,
bserv::placeholders::json_params, bserv::placeholders::json_params,
bserv::placeholders::transaction, bserv::placeholders::db_connection_ptr,
bserv::placeholders::session), bserv::placeholders::session),
bserv::make_path("/logout", &user_logout, bserv::make_path("/logout", &user_logout,
bserv::placeholders::session), bserv::placeholders::session),
bserv::make_path("/find/<str>", &find_user, bserv::make_path("/find/<str>", &find_user,
bserv::placeholders::transaction, bserv::placeholders::db_connection_ptr,
bserv::placeholders::_1), bserv::placeholders::_1),
bserv::make_path("/send", &send_request) bserv::make_path("/send", &send_request,
bserv::placeholders::http_client_ptr),
bserv::make_path("/echo", &echo,
bserv::placeholders::json_params)
}}; }};
return EXIT_SUCCESS; return EXIT_SUCCESS;