Refactor Server (RIPD-1120):

* Make Handler a template argument
This commit is contained in:
Vinnie Falco
2016-05-20 08:44:13 -04:00
parent 80a9a2bf5d
commit 289c8c9f09
53 changed files with 997 additions and 1176 deletions

View File

@@ -21,8 +21,8 @@
#define RIPPLE_SERVER_SERVERIMPL_H_INCLUDED
#include <ripple/basics/chrono.h>
#include <ripple/server/Handler.h>
#include <ripple/server/Server.h>
#include <ripple/server/impl/Door.h>
#include <ripple/server/impl/io_list.h>
#include <ripple/beast/core/List.h>
#include <ripple/beast/core/Thread.h>
@@ -30,17 +30,52 @@
#include <boost/optional.hpp>
#include <array>
#include <chrono>
#include <condition_variable>
#include <deque>
#include <functional>
#include <mutex>
#include <thread>
namespace ripple {
class BasicPeer;
class Door;
/** A multi-protocol server.
This server maintains multiple configured listening ports,
with each listening port allows for multiple protocols including
HTTP, HTTP/S, WebSocket, Secure WebSocket, and the Peer protocol.
*/
class Server
{
public:
/** Destroy the server.
The server is closed if it is not already closed. This call
blocks until the server has stopped.
*/
virtual
~Server() = default;
/** Returns the Journal associated with the server. */
virtual
beast::Journal
journal() = 0;
/** Set the listening port settings.
This may only be called once.
*/
virtual
void
ports (std::vector<Port> const& v) = 0;
/** Close the server.
The close is performed asynchronously. The handler will be notified
when the server has stopped. The server is considered stopped when
there are no pending I/O completion handlers and all connections
have closed.
Thread safety:
Safe to call concurrently from any thread.
*/
virtual
void
close() = 0;
};
template<class Handler>
class ServerImpl : public Server
{
private:
@@ -51,7 +86,7 @@ private:
historySize = 100
};
using Doors = std::vector <std::shared_ptr<Door>>;
using Doors = std::vector <std::shared_ptr<Door<Handler>>>;
Handler& handler_;
beast::Journal j_;
@@ -61,14 +96,14 @@ private:
std::mutex m_;
std::vector<Port> ports_;
std::vector<std::weak_ptr<Door>> list_;
std::vector<std::weak_ptr<Door<Handler>>> list_;
int high_ = 0;
std::array <std::size_t, 64> hist_;
io_list ios_;
public:
ServerImpl (Handler& handler,
ServerImpl(Handler& handler,
boost::asio::io_service& io_service, beast::Journal journal);
~ServerImpl();
@@ -91,7 +126,6 @@ public:
return ios_;
}
public:
boost::asio::io_service&
get_io_service()
{
@@ -107,7 +141,71 @@ private:
ceil_log2 (unsigned long long x);
};
template<class Handler>
ServerImpl<Handler>::
ServerImpl(Handler& handler,
boost::asio::io_service& io_service, beast::Journal journal)
: handler_(handler)
, j_(journal)
, io_service_(io_service)
, strand_(io_service_)
, work_(io_service_)
{
}
template<class Handler>
ServerImpl<Handler>::
~ServerImpl()
{
// Handler::onStopped will not be called
work_ = boost::none;
ios_.close();
ios_.join();
}
template<class Handler>
void
ServerImpl<Handler>::
ports (std::vector<Port> const& ports)
{
if (closed())
Throw<std::logic_error> ("ports() on closed Server");
ports_.reserve(ports.size());
for(auto const& port : ports)
{
if (! port.websockets())
{
ports_.push_back(port);
if(auto sp = ios_.emplace<Door<Handler>>(handler_,
io_service_, ports_.back(), j_))
{
list_.push_back(sp);
sp->run();
}
}
}
}
template<class Handler>
void
ServerImpl<Handler>::
close()
{
ios_.close(
[&]
{
work_ = boost::none;
handler_.onStopped(*this);
});
}
template<class Handler>
bool
ServerImpl<Handler>::
closed()
{
return ios_.closed();
}
} // ripple
#endif