Commit 38414feb authored by Dominik Charousset's avatar Dominik Charousset

Streamline configuration class setup

parent ed6cc808
......@@ -18,6 +18,7 @@
#include <cassert>
#include <cstdint>
#include <string>
#include <utility>
namespace caf::net::dsl {
......@@ -47,12 +48,12 @@ public:
static constexpr std::string_view name = "lazy";
lazy(std::shared_ptr<ssl::context> ctx, std::string host, uint16_t port)
: has_ctx(std::move(ctx)), server(server_address{std::move(host), port}) {
lazy(std::string host, uint16_t port)
: server(server_address{std::move(host), port}) {
// nop
}
lazy(std::shared_ptr<ssl::context> ctx, const uri& addr)
: has_ctx(std::move(ctx)), server(addr) {
explicit lazy(const uri& addr) : server(addr) {
// nop
}
......@@ -78,8 +79,7 @@ public:
public:
static constexpr std::string_view name = "socket";
socket(std::shared_ptr<ssl::context> ctx, stream_socket fd)
: has_ctx(std::move(ctx)), fd(fd) {
explicit socket(stream_socket fd) : fd(fd) {
// nop
}
......
......@@ -24,6 +24,7 @@
#include <cassert>
#include <cstdint>
#include <string>
#include <utility>
namespace caf::net::dsl {
......@@ -58,6 +59,10 @@ public:
/// `has_ctx` instance if possible, `nullptr` otherwise.
virtual has_ctx* as_has_ctx() noexcept = 0;
/// Inspects the data of this configuration and returns a pointer to it as
/// `has_ctx` instance if possible, `nullptr` otherwise.
virtual const has_ctx* as_has_ctx() const noexcept = 0;
bool failed() const noexcept {
return name() == get_name<error>::value;
}
......@@ -88,13 +93,16 @@ class config_impl : public config_base {
public:
using super = config_base;
template <class From, class... Args>
explicit config_impl(From&& from, Args&&... args)
: super(std::forward<From>(from)), data(std::forward<Args>(args)...) {
if constexpr (std::is_base_of_v<config_base, std::decay_t<From>>) {
if (!from)
data = from.fail_reason();
}
template <class... Args>
explicit config_impl(const config_base& from, Args&&... args)
: super(from), data(std::forward<Args>(args)...) {
// nop
}
template <class... Args>
explicit config_impl(multiplexer* mpx, Args&&... args)
: super(mpx), data(std::forward<Args>(args)...) {
// nop
}
std::variant<error, Data...> data;
......@@ -128,6 +136,33 @@ public:
has_ctx* as_has_ctx() noexcept override {
return has_ctx::from(data);
}
const has_ctx* as_has_ctx() const noexcept override {
return has_ctx::from(data);
}
protected:
template <class Derived, class From, class Token, class... Args>
static intrusive_ptr<Derived> make_impl(std::in_place_type_t<Derived>,
const From& from, Token token,
Args&&... args) {
// Always construct the data in-place first. This makes sure we account
// for ownership transfers (e.g. for sockets).
auto ptr = make_counted<Derived>(from, token, std::forward<Args>(args)...);
// Discard the data if `from` contained an error. Otherwise, transfer the
// SSL context over to the refined configuration.
if (!from) {
ptr->data = std::get<error>(from.data);
} else if (auto* dst = ptr->as_has_ctx()) {
if (const auto* src = from.as_has_ctx()) {
dst->ctx = src->ctx;
} else {
ptr->data = make_error(caf::sec::logic_error,
"failed to transfer SSL context");
}
}
return ptr;
}
};
} // namespace caf::net::dsl
......@@ -25,6 +25,10 @@ struct generic_config_tag {
/// is starting a client or a server.
class generic_config {
public:
static constexpr auto fail_v = generic_config_tag<error>{};
static constexpr size_t fail_index = 0;
/// Configuration for a client that creates the socket on demand.
class lazy : public has_ctx {
public:
......@@ -33,7 +37,7 @@ public:
static constexpr auto lazy_v = generic_config_tag<lazy>{};
static constexpr auto fail_v = generic_config_tag<error>{};
static constexpr size_t lazy_index = 1;
class value : public config_impl<lazy> {
public:
......
......@@ -80,6 +80,18 @@ public:
};
return std::visit(get_ptr, data);
}
template <class SumType>
static const has_ctx* from(const SumType& data) noexcept {
auto get_ptr = [](const auto& val) -> const has_ctx* {
using val_t = std::decay_t<decltype(val)>;
if constexpr (std::is_base_of_v<has_ctx, val_t>)
return &val;
else
return nullptr;
};
return std::visit(get_ptr, data);
}
};
} // namespace caf::net::dsl
......@@ -33,11 +33,9 @@ public:
public:
static constexpr std::string_view name = "lazy";
lazy(std::shared_ptr<ssl::context> ctx, uint16_t port,
std::string bind_address)
: has_ctx(std::move(ctx)),
port(port),
bind_address(std::move(bind_address)) {
lazy(uint16_t port, std::string bind_address)
: port(port), bind_address(std::move(bind_address)) {
// nop
}
/// The port number to bind to.
......@@ -59,8 +57,7 @@ public:
public:
static constexpr std::string_view name = "socket";
socket(std::shared_ptr<ssl::context> ctx, tcp_accept_socket fd)
: has_ctx(std::move(ctx)), fd(fd) {
explicit socket(tcp_accept_socket fd) : fd(fd) {
// nop
}
......
......@@ -25,15 +25,18 @@ class CAF_NET_EXPORT server_config : public dsl::server_config_value {
public:
using super = dsl::server_config_value;
using super::super;
~server_config() override;
static intrusive_ptr<server_config>
make(dsl::server_config::lazy_t, const base_config& from, uint16_t port,
std::string bind_address);
using super::super;
static intrusive_ptr<server_config> make(dsl::server_config::socket_t,
const base_config& from,
tcp_accept_socket fd);
template <class T, class... Args>
static auto
make(dsl::server_config_tag<T>, const base_config& from, Args&&... args) {
auto ptr = super::make_impl(std::in_place_type<server_config>, from,
std::in_place_type<T>,
std::forward<Args>(args)...);
return ptr;
}
/// Stores the available routes on the HTTP server.
std::vector<route_ptr> routes;
......
......@@ -40,32 +40,14 @@ public:
using super::super;
static auto make(dsl::server_config::lazy_t, const base_config<Trait>& from,
uint16_t port, std::string bind_address) {
auto res = make_counted<server_config>(from.mpx);
if (auto* err = std::get_if<error>(&from.data)) {
res->data = *err;
} else {
auto& src_data = std::get<dsl::generic_config::lazy>(from.data);
res->data = dsl::server_config::lazy{src_data.ctx, port,
std::move(bind_address)};
res->trait = from.trait;
}
return res;
}
static auto make(dsl::server_config::socket_t, const base_config<Trait>& from,
tcp_accept_socket fd) {
auto res = make_counted<server_config>(from.mpx);
if (auto* err = std::get_if<error>(&from.data)) {
res->data = *err;
close(fd);
} else {
auto& src_data = std::get<dsl::generic_config::lazy>(from.data);
res->data = dsl::server_config::socket{src_data.ctx, fd};
res->trait = from.trait;
}
return res;
template <class T, class... Args>
static auto make(dsl::server_config_tag<T>, const base_config<Trait>& from,
Args&&... args) {
auto ptr = super::make_impl(std::in_place_type<server_config>, from,
std::in_place_type<T>,
std::forward<Args>(args)...);
ptr->trait = from.trait;
return ptr;
}
Trait trait;
......@@ -81,53 +63,14 @@ public:
using super::super;
template <class... Ts>
static auto
make(dsl::client_config::lazy_t, const base_config<Trait>& from, Ts&&... args) {
auto res = make_counted<client_config>(from.mpx);
if (auto* err = std::get_if<error>(&from.data)) {
res->data = *err;
} else {
auto& src_data = std::get<dsl::generic_config::lazy>(from.data);
res->data = dsl::client_config::lazy{src_data.ctx,
std::forward<Ts>(args)...};
res->trait = from.trait;
}
return res;
}
static auto make(dsl::client_config::socket_t, const base_config<Trait>& from,
stream_socket fd) {
auto res = make_counted<client_config>(from.mpx);
if (auto* err = std::get_if<error>(&from.data)) {
res->data = *err;
close(fd);
} else {
auto& src_data = std::get<dsl::generic_config::lazy>(from.data);
res->data = dsl::client_config::socket{src_data.ctx, fd};
res->trait = from.trait;
}
return res;
}
static auto make(dsl::client_config::socket_t, const base_config<Trait>& from,
ssl::connection conn) {
auto res = make_counted<client_config>(from.mpx);
if (auto* err = std::get_if<error>(&from.data)) {
res->data = *err;
} else {
auto& src_data = std::get<dsl::generic_config::lazy>(from.data);
res->data = dsl::client_config::socket{src_data.ctx, std::move(conn)};
res->trait = from.trait;
}
return res;
}
static auto make(dsl::client_config::fail_t, const base_config<Trait>& from,
error err) {
auto res = make_counted<client_config>(from.mpx);
res->data = std::move(err);
return res;
template <class T, class... Args>
static auto make(dsl::client_config_tag<T>, const base_config<Trait>& from,
Args&&... args) {
auto ptr = super::make_impl(std::in_place_type<client_config>, from,
std::in_place_type<T>,
std::forward<Args>(args)...);
ptr->trait = from.trait;
return ptr;
}
Trait trait;
......
......@@ -41,32 +41,14 @@ public:
using super::super;
static auto make(dsl::server_config::lazy_t, const base_config<Trait>& from,
uint16_t port, std::string bind_address) {
auto res = make_counted<server_config>(from.mpx);
if (auto* err = std::get_if<error>(&from.data)) {
res->data = *err;
} else {
auto& src_data = std::get<dsl::generic_config::lazy>(from.data);
res->data = dsl::server_config::lazy{src_data.ctx, port,
std::move(bind_address)};
res->trait = from.trait;
}
return res;
}
static auto make(dsl::server_config::socket_t, const base_config<Trait>& from,
tcp_accept_socket fd) {
auto res = make_counted<server_config>(from.mpx);
if (auto* err = std::get_if<error>(&from.data)) {
res->data = *err;
close(fd);
} else {
auto& src_data = std::get<dsl::generic_config::lazy>(from.data);
res->data = dsl::server_config::socket{src_data.ctx, fd};
res->trait = from.trait;
}
return res;
template <class T, class... Args>
static auto make(dsl::server_config_tag<T>, const base_config<Trait>& from,
Args&&... args) {
auto ptr = super::make_impl(std::in_place_type<server_config>, from,
std::in_place_type<T>,
std::forward<Args>(args)...);
ptr->trait = from.trait;
return ptr;
}
Trait trait;
......@@ -80,46 +62,17 @@ public:
using super = dsl::client_config_value;
explicit client_config(multiplexer* mpx) : super(mpx) {
hs.endpoint("/");
}
client_config(const client_config&) = default;
template <class... Ts>
static auto
make(dsl::client_config::lazy_t, const base_config<Trait>& from, Ts&&... args) {
auto res = make_counted<client_config>(from.mpx);
if (auto* err = std::get_if<error>(&from.data)) {
res->data = *err;
} else {
auto& src_data = std::get<dsl::generic_config::lazy>(from.data);
res->data = dsl::client_config::lazy{src_data.ctx,
std::forward<Ts>(args)...};
res->trait = from.trait;
}
return res;
}
static auto make(dsl::client_config::socket_t, const base_config<Trait>& from,
tcp_accept_socket fd) {
auto res = make_counted<client_config>(from.mpx);
if (auto* err = std::get_if<error>(&from.data)) {
res->data = *err;
close(fd);
} else {
auto& src_data = std::get<dsl::generic_config::lazy>(from.data);
res->data = dsl::client_config::socket{src_data.ctx, fd};
res->trait = from.trait;
}
return res;
}
using super::super;
static auto make(dsl::client_config::fail_t, const base_config<Trait>& from,
error err) {
auto res = make_counted<client_config>(from.mpx);
res->data = std::move(err);
return res;
template <class T, class... Args>
static auto make(dsl::client_config_tag<T>, const base_config<Trait>& from,
Args&&... args) {
auto ptr = super::make_impl(std::in_place_type<client_config>, from,
std::in_place_type<T>,
std::forward<Args>(args)...);
ptr->trait = from.trait;
ptr->hs.endpoint("/");
return ptr;
}
Trait trait;
......
......@@ -6,32 +6,8 @@
namespace caf::net::http {
intrusive_ptr<server_config>
server_config::make(dsl::server_config::lazy_t, const base_config& from,
uint16_t port, std::string bind_address) {
auto res = make_counted<server_config>(from.mpx);
if (auto* err = std::get_if<error>(&from.data)) {
res->data = *err;
} else {
auto& src_data = std::get<dsl::generic_config::lazy>(from.data);
res->data = dsl::server_config::lazy{src_data.ctx, port,
std::move(bind_address)};
}
return res;
}
intrusive_ptr<server_config> server_config::make(dsl::server_config::socket_t,
const base_config& from,
tcp_accept_socket fd) {
auto res = make_counted<server_config>(from.mpx);
if (auto* err = std::get_if<error>(&from.data)) {
res->data = *err;
close(fd);
} else {
auto& src_data = std::get<dsl::generic_config::lazy>(from.data);
res->data = dsl::server_config::socket{src_data.ctx, fd};
}
return res;
server_config::~server_config() {
// nop
}
} // namespace caf::net::http
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment