Skip to content

Commit

Permalink
Merge pull request #317 from ufownl/topic/Achieve_complete_type_safe
Browse files Browse the repository at this point in the history
Improve type safety of `typed_broker`
  • Loading branch information
Neverlord committed Jun 21, 2015
2 parents 63f63a1 + 3b6f726 commit 9fe8650
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 10 deletions.
48 changes: 44 additions & 4 deletions libcaf_io/caf/io/experimental/typed_broker.hpp
Expand Up @@ -17,18 +17,19 @@
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/

#ifndef CAF_IO_TYPED_BROKER_HPP
#define CAF_IO_TYPED_BROKER_HPP
#ifndef CAF_IO_EXPERIMENTAL_TYPED_BROKER_HPP
#define CAF_IO_EXPERIMENTAL_TYPED_BROKER_HPP

#include <map>
#include <vector>
#include <type_traits>

#include "caf/none.hpp"
#include "caf/config.hpp"
#include "caf/make_counted.hpp"
#include "caf/spawn.hpp"
#include "caf/extend.hpp"
#include "caf/typed_behavior.hpp"
#include "caf/typed_actor.hpp"
#include "caf/local_actor.hpp"

#include "caf/detail/logging.hpp"
Expand All @@ -46,6 +47,13 @@ namespace caf {
namespace io {
namespace experimental {

using minimal_client = typed_actor<reacts_to<new_data_msg>,
reacts_to<connection_closed_msg>>;

using minimal_server =
minimal_client::extend<reacts_to<new_connection_msg>,
reacts_to<acceptor_closed_msg>>;

template <class... Sigs>
class typed_broker;

Expand Down Expand Up @@ -73,6 +81,8 @@ class typed_broker : public abstract_event_based_actor<typed_behavior<Sigs...>,
public:
using signatures = detail::type_list<Sigs...>;

using actor_hdl = typed_actor<Sigs...>;

using behavior_type = typed_behavior<Sigs...>;

using super = abstract_event_based_actor<behavior_type, false,
Expand Down Expand Up @@ -180,6 +190,9 @@ class typed_broker : public abstract_event_based_actor<typed_behavior<Sigs...>,
typename detail::get_callable_trait<F>::arg_types
>::type
>::type;
static_assert(std::is_convertible<typename impl::actor_hdl,
minimal_client>::value,
"Cannot fork: new broker misses required handlers");
return spawn_functor_impl<no_spawn_options, impl>(
nullptr, [&sptr](abstract_broker* forked) {
sptr->set_broker(forked);
Expand All @@ -188,6 +201,33 @@ class typed_broker : public abstract_event_based_actor<typed_behavior<Sigs...>,
std::move(fun), hdl, std::forward<Ts>(xs)...);
}

connection_handle add_tcp_scribe(const std::string& host, uint16_t port) {
static_assert(std::is_convertible<actor_hdl, minimal_client>::value,
"Cannot add scribe: broker misses required handlers");
return super::add_tcp_scribe(host, port);
}

connection_handle add_tcp_scribe(network::native_socket fd) {
static_assert(std::is_convertible<actor_hdl, minimal_client>::value,
"Cannot add scribe: broker misses required handlers");
return super::add_tcp_scribe(fd);
}

std::pair<accept_handle, uint16_t>
add_tcp_doorman(uint16_t port = 0,
const char* in = nullptr,
bool reuse_addr = false) {
static_assert(std::is_convertible<actor_hdl, minimal_server>::value,
"Cannot add doorman: broker misses required handlers");
return super::add_tcp_doorman(port, in, reuse_addr);
}

accept_handle add_tcp_doorman(network::native_socket fd) {
static_assert(std::is_convertible<actor_hdl, minimal_server>::value,
"Cannot add doorman: broker misses required handlers");
return super::add_tcp_doorman(fd);
}

typed_broker() {
// nop
}
Expand All @@ -212,4 +252,4 @@ class typed_broker : public abstract_event_based_actor<typed_behavior<Sigs...>,
} // namespace io
} // namespace caf

#endif // CAF_IO_TYPED_BROKER_HPP
#endif // CAF_IO_EXPERIMENTAL_TYPED_BROKER_HPP
6 changes: 6 additions & 0 deletions libcaf_io/caf/io/spawn_io.hpp
Expand Up @@ -131,6 +131,9 @@ spawn_io_client_typed(F fun, const std::string& host, uint16_t port,
using arg_types = typename trait::arg_types;
using first_arg = typename detail::tl_head<arg_types>::type;
using impl_class = typename std::remove_pointer<first_arg>::type;
static_assert(std::is_convertible<typename impl_class::actor_hdl,
minimal_client>::value,
"Cannot spawn io client: broker misses required handlers");
return spawn_io_client_impl<Os, impl_class>(std::move(fun), host, port,
std::forward<Ts>(xs)...);
}
Expand All @@ -148,6 +151,9 @@ spawn_io_server_typed(F fun, uint16_t port, Ts&&... xs) {
using arg_types = typename trait::arg_types;
using first_arg = typename detail::tl_head<arg_types>::type;
using impl_class = typename std::remove_pointer<first_arg>::type;
static_assert(std::is_convertible<typename impl_class::actor_hdl,
minimal_server>::value,
"Cannot spawn io server: broker misses required handlers");
return spawn_io_server_impl<Os, impl_class>(std::move(fun), port,
std::forward<Ts>(xs)...);
}
Expand Down
13 changes: 7 additions & 6 deletions libcaf_io/test/typed_broker.cpp
Expand Up @@ -48,13 +48,11 @@ using ping_atom = caf::atom_constant<atom("ping")>;
using pong_atom = caf::atom_constant<atom("pong")>;
using kickoff_atom = caf::atom_constant<atom("kickoff")>;

using peer = typed_actor<replies_to<connection_closed_msg>::with<void>,
replies_to<new_data_msg>::with<void>,
replies_to<ping_atom, int>::with<void>,
replies_to<pong_atom, int>::with<void>>;
using peer = minimal_client::extend<reacts_to<ping_atom, int>,
reacts_to<pong_atom, int>>;

using acceptor = typed_actor<replies_to<new_connection_msg>::with<void>,
replies_to<publish_atom>::with<uint16_t>>;
using acceptor =
minimal_server::extend<replies_to<publish_atom>::with<uint16_t>>;

behavior ping(event_based_actor* self, size_t num_pings) {
CAF_MESSAGE("num_pings: " << num_pings);
Expand Down Expand Up @@ -175,6 +173,9 @@ acceptor::behavior_type acceptor_fun(acceptor::broker_pointer self,
self->fork(peer_fun, msg.handle, buddy);
self->quit();
},
[](const new_data_msg&) {},
[](const connection_closed_msg&) {},
[](const acceptor_closed_msg&) {},
[=](publish_atom) {
return self->add_tcp_doorman(0, "127.0.0.1").second;
}
Expand Down

0 comments on commit 9fe8650

Please sign in to comment.