Kagome
Polkadot Runtime Engine in C++17
http_listener_impl.cpp
Go to the documentation of this file.
1 
7 
8 #include <utility>
9 
10 #include <boost/asio.hpp>
11 #include "api/transport/tuner.hpp"
13 
14 namespace kagome::api {
16  const std::shared_ptr<application::AppStateManager> &app_state_manager,
17  std::shared_ptr<Context> context,
18  Configuration listener_config,
19  SessionImpl::Configuration session_config)
20  : context_{std::move(context)},
21  config_{std::move(listener_config)},
22  session_config_{session_config},
23  logger_{log::createLogger("RpcHttpListener", "rpc_transport")} {
24  BOOST_ASSERT(app_state_manager);
25  app_state_manager->takeControl(*this);
26  }
27 
29  try {
32  } catch (const boost::wrapexcept<boost::system::system_error> &exception) {
33  logger_->critical("Failed to prepare a listener: {}", exception.what());
34  return false;
35  } catch (const std::exception &exception) {
36  logger_->critical("Exception when preparing a listener: {}",
37  exception.what());
38  return false;
39  }
40 
41  boost::system::error_code ec;
42  acceptor_->set_option(boost::asio::socket_base::reuse_address(true), ec);
43  if (ec) {
44  logger_->error("Failed to set `reuse address` option to acceptor");
45  return false;
46  }
47  return true;
48  }
49 
51  BOOST_ASSERT(acceptor_);
52 
53  if (!acceptor_->is_open()) {
54  logger_->error("error: trying to start on non opened acceptor");
55  return false;
56  }
57 
58  SL_INFO(logger_,
59  "Listening for new connections on {}:{}",
60  config_.endpoint.address(),
61  acceptor_->local_endpoint().port());
62  acceptOnce();
63  return true;
64  }
65 
67  if (acceptor_) {
68  acceptor_->cancel();
69  }
70  }
71 
73  NewSessionHandler &&on_new_session) {
75  std::make_unique<NewSessionHandler>(std::move(on_new_session));
76  }
77 
79  new_session_ = std::make_shared<SessionImpl>(*context_, session_config_);
80 
81  auto on_accept = [wp = weak_from_this()](boost::system::error_code ec) {
82  if (auto self = wp.lock()) {
83  if (not ec) {
84  if (self->on_new_session_) {
85  (*self->on_new_session_)(self->new_session_);
86  }
87  self->new_session_->start();
88  }
89 
90  if (self->acceptor_->is_open()) {
91  // continue to accept until acceptor is ready
92  self->acceptOnce();
93  }
94  }
95  };
96 
97  acceptor_->async_accept(new_session_->socket(), std::move(on_accept));
98  }
99 
100 } // namespace kagome::api
std::shared_ptr< Context > context_
std::shared_ptr< SessionImpl > new_session_
std::function< void(const std::shared_ptr< Session > &)> NewSessionHandler
Definition: listener.hpp:26
std::unique_ptr< Acceptor > acceptOnFreePort(std::shared_ptr< boost::asio::io_context > context, Endpoint endpoint, uint16_t port_tolerance, const log::Logger &logger)
Definition: tuner.cpp:10
Endpoint endpoint
listening endpoint
Definition: listener.hpp:33
std::unique_ptr< NewSessionHandler > on_new_session_
void acceptOnce() override
Accept incoming connection.
std::unique_ptr< Acceptor > acceptor_
const SessionImpl::Configuration session_config_
constexpr uint16_t kDefaultPortTolerance
Definition: tuner.hpp:17
void setHandlerForNewSession(NewSessionHandler &&on_new_session) override
Set handler for working new session.
Logger createLogger(const std::string &tag)
Definition: logger.cpp:112
HttpListenerImpl(const std::shared_ptr< application::AppStateManager > &app_state_manager, std::shared_ptr< Context > context, Configuration listener_config, SessionImpl::Configuration session_config)