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

Streamline configuration class setup

parent ed6cc808
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <cassert> #include <cassert>
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <utility>
namespace caf::net::dsl { namespace caf::net::dsl {
...@@ -47,12 +48,12 @@ public: ...@@ -47,12 +48,12 @@ public:
static constexpr std::string_view name = "lazy"; static constexpr std::string_view name = "lazy";
lazy(std::shared_ptr<ssl::context> ctx, std::string host, uint16_t port) lazy(std::string host, uint16_t port)
: has_ctx(std::move(ctx)), server(server_address{std::move(host), port}) { : server(server_address{std::move(host), port}) {
// nop
} }
lazy(std::shared_ptr<ssl::context> ctx, const uri& addr) explicit lazy(const uri& addr) : server(addr) {
: has_ctx(std::move(ctx)), server(addr) {
// nop // nop
} }
...@@ -78,8 +79,7 @@ public: ...@@ -78,8 +79,7 @@ public:
public: public:
static constexpr std::string_view name = "socket"; static constexpr std::string_view name = "socket";
socket(std::shared_ptr<ssl::context> ctx, stream_socket fd) explicit socket(stream_socket fd) : fd(fd) {
: has_ctx(std::move(ctx)), fd(fd) {
// nop // nop
} }
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <cassert> #include <cassert>
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <utility>
namespace caf::net::dsl { namespace caf::net::dsl {
...@@ -58,6 +59,10 @@ public: ...@@ -58,6 +59,10 @@ public:
/// `has_ctx` instance if possible, `nullptr` otherwise. /// `has_ctx` instance if possible, `nullptr` otherwise.
virtual has_ctx* as_has_ctx() noexcept = 0; 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 { bool failed() const noexcept {
return name() == get_name<error>::value; return name() == get_name<error>::value;
} }
...@@ -88,13 +93,16 @@ class config_impl : public config_base { ...@@ -88,13 +93,16 @@ class config_impl : public config_base {
public: public:
using super = config_base; using super = config_base;
template <class From, class... Args> template <class... Args>
explicit config_impl(From&& from, Args&&... args) explicit config_impl(const config_base& from, Args&&... args)
: super(std::forward<From>(from)), data(std::forward<Args>(args)...) { : super(from), data(std::forward<Args>(args)...) {
if constexpr (std::is_base_of_v<config_base, std::decay_t<From>>) { // nop
if (!from) }
data = from.fail_reason();
} template <class... Args>
explicit config_impl(multiplexer* mpx, Args&&... args)
: super(mpx), data(std::forward<Args>(args)...) {
// nop
} }
std::variant<error, Data...> data; std::variant<error, Data...> data;
...@@ -128,6 +136,33 @@ public: ...@@ -128,6 +136,33 @@ public:
has_ctx* as_has_ctx() noexcept override { has_ctx* as_has_ctx() noexcept override {
return has_ctx::from(data); 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 } // namespace caf::net::dsl
...@@ -25,6 +25,10 @@ struct generic_config_tag { ...@@ -25,6 +25,10 @@ struct generic_config_tag {
/// is starting a client or a server. /// is starting a client or a server.
class generic_config { class generic_config {
public: 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. /// Configuration for a client that creates the socket on demand.
class lazy : public has_ctx { class lazy : public has_ctx {
public: public:
...@@ -33,7 +37,7 @@ public: ...@@ -33,7 +37,7 @@ public:
static constexpr auto lazy_v = generic_config_tag<lazy>{}; 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> { class value : public config_impl<lazy> {
public: public:
......
...@@ -80,6 +80,18 @@ public: ...@@ -80,6 +80,18 @@ public:
}; };
return std::visit(get_ptr, data); 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 } // namespace caf::net::dsl
...@@ -33,11 +33,9 @@ public: ...@@ -33,11 +33,9 @@ public:
public: public:
static constexpr std::string_view name = "lazy"; static constexpr std::string_view name = "lazy";
lazy(std::shared_ptr<ssl::context> ctx, uint16_t port, lazy(uint16_t port, std::string bind_address)
std::string bind_address) : port(port), bind_address(std::move(bind_address)) {
: has_ctx(std::move(ctx)), // nop
port(port),
bind_address(std::move(bind_address)) {
} }
/// The port number to bind to. /// The port number to bind to.
...@@ -59,8 +57,7 @@ public: ...@@ -59,8 +57,7 @@ public:
public: public:
static constexpr std::string_view name = "socket"; static constexpr std::string_view name = "socket";
socket(std::shared_ptr<ssl::context> ctx, tcp_accept_socket fd) explicit socket(tcp_accept_socket fd) : fd(fd) {
: has_ctx(std::move(ctx)), fd(fd) {
// nop // nop
} }
......
...@@ -25,15 +25,18 @@ class CAF_NET_EXPORT server_config : public dsl::server_config_value { ...@@ -25,15 +25,18 @@ class CAF_NET_EXPORT server_config : public dsl::server_config_value {
public: public:
using super = dsl::server_config_value; using super = dsl::server_config_value;
using super::super; ~server_config() override;
static intrusive_ptr<server_config> using super::super;
make(dsl::server_config::lazy_t, const base_config& from, uint16_t port,
std::string bind_address);
static intrusive_ptr<server_config> make(dsl::server_config::socket_t, template <class T, class... Args>
const base_config& from, static auto
tcp_accept_socket fd); 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. /// Stores the available routes on the HTTP server.
std::vector<route_ptr> routes; std::vector<route_ptr> routes;
......
...@@ -40,32 +40,14 @@ public: ...@@ -40,32 +40,14 @@ public:
using super::super; using super::super;
static auto make(dsl::server_config::lazy_t, const base_config<Trait>& from, template <class T, class... Args>
uint16_t port, std::string bind_address) { static auto make(dsl::server_config_tag<T>, const base_config<Trait>& from,
auto res = make_counted<server_config>(from.mpx); Args&&... args) {
if (auto* err = std::get_if<error>(&from.data)) { auto ptr = super::make_impl(std::in_place_type<server_config>, from,
res->data = *err; std::in_place_type<T>,
} else { std::forward<Args>(args)...);
auto& src_data = std::get<dsl::generic_config::lazy>(from.data); ptr->trait = from.trait;
res->data = dsl::server_config::lazy{src_data.ctx, port, return ptr;
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;
} }
Trait trait; Trait trait;
...@@ -81,53 +63,14 @@ public: ...@@ -81,53 +63,14 @@ public:
using super::super; using super::super;
template <class... Ts> template <class T, class... Args>
static auto static auto make(dsl::client_config_tag<T>, const base_config<Trait>& from,
make(dsl::client_config::lazy_t, const base_config<Trait>& from, Ts&&... args) { Args&&... args) {
auto res = make_counted<client_config>(from.mpx); auto ptr = super::make_impl(std::in_place_type<client_config>, from,
if (auto* err = std::get_if<error>(&from.data)) { std::in_place_type<T>,
res->data = *err; std::forward<Args>(args)...);
} else { ptr->trait = from.trait;
auto& src_data = std::get<dsl::generic_config::lazy>(from.data); return ptr;
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;
} }
Trait trait; Trait trait;
......
...@@ -41,32 +41,14 @@ public: ...@@ -41,32 +41,14 @@ public:
using super::super; using super::super;
static auto make(dsl::server_config::lazy_t, const base_config<Trait>& from, template <class T, class... Args>
uint16_t port, std::string bind_address) { static auto make(dsl::server_config_tag<T>, const base_config<Trait>& from,
auto res = make_counted<server_config>(from.mpx); Args&&... args) {
if (auto* err = std::get_if<error>(&from.data)) { auto ptr = super::make_impl(std::in_place_type<server_config>, from,
res->data = *err; std::in_place_type<T>,
} else { std::forward<Args>(args)...);
auto& src_data = std::get<dsl::generic_config::lazy>(from.data); ptr->trait = from.trait;
res->data = dsl::server_config::lazy{src_data.ctx, port, return ptr;
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;
} }
Trait trait; Trait trait;
...@@ -80,46 +62,17 @@ public: ...@@ -80,46 +62,17 @@ public:
using super = dsl::client_config_value; using super = dsl::client_config_value;
explicit client_config(multiplexer* mpx) : super(mpx) { using super::super;
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;
}
static auto make(dsl::client_config::fail_t, const base_config<Trait>& from, template <class T, class... Args>
error err) { static auto make(dsl::client_config_tag<T>, const base_config<Trait>& from,
auto res = make_counted<client_config>(from.mpx); Args&&... args) {
res->data = std::move(err); auto ptr = super::make_impl(std::in_place_type<client_config>, from,
return res; std::in_place_type<T>,
std::forward<Args>(args)...);
ptr->trait = from.trait;
ptr->hs.endpoint("/");
return ptr;
} }
Trait trait; Trait trait;
......
...@@ -6,32 +6,8 @@ ...@@ -6,32 +6,8 @@
namespace caf::net::http { namespace caf::net::http {
intrusive_ptr<server_config> server_config::~server_config() {
server_config::make(dsl::server_config::lazy_t, const base_config& from, // nop
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;
} }
} // namespace caf::net::http } // 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