Commit 72af9221 authored by Dominik Charousset's avatar Dominik Charousset

Refactor the BASP broker as a class-based actor

Our new design must make sure that the BASP instance inside the BASP
broker outlives the scheduler. Otherwise, currently running BASP workers
might access released memory during shutdown. Hence, we move the BASP
instance to a member of the actor itself to make sure that object won't
get destroyed when the BASP broker quits but when it gets actually
destroyed instead.
parent 6f1fb436
...@@ -40,114 +40,121 @@ ...@@ -40,114 +40,121 @@
namespace caf { namespace caf {
namespace io { namespace io {
struct basp_broker_state : proxy_registry::backend, basp::instance::callee { /// A broker implementation for the Binary Actor System Protocol (BASP).
basp_broker_state(broker* selfptr); class basp_broker : public broker,
public proxy_registry::backend,
public basp::instance::callee {
public:
// -- member types -----------------------------------------------------------
using super = broker;
using ctx_map = std::unordered_map<connection_handle, basp::endpoint_context>;
using monitored_actor_map = std::unordered_map<actor_addr,
std::unordered_set<node_id>>;
// -- constructors, destructors, and assignment operators --------------------
~basp_broker_state() override; explicit basp_broker(actor_config& cfg);
~basp_broker() override;
// -- implementation of broker -----------------------------------------------
void on_exit() override;
const char* name() const override;
behavior make_behavior() override;
proxy_registry* proxy_registry_ptr() override;
resume_result resume(execution_unit*, size_t) override;
// -- implementation of proxy_registry::backend ------------------------------
// inherited from proxy_registry::backend
strong_actor_ptr make_proxy(node_id nid, actor_id aid) override; strong_actor_ptr make_proxy(node_id nid, actor_id aid) override;
// inherited from proxy_registry::backend
void set_last_hop(node_id* ptr) override; void set_last_hop(node_id* ptr) override;
// inherited from basp::instance::callee // -- implementation of basp::instance::callee -------------------------------
void finalize_handshake(const node_id& nid, actor_id aid, void finalize_handshake(const node_id& nid, actor_id aid,
std::set<std::string>& sigs) override; std::set<std::string>& sigs) override;
// inherited from basp::instance::callee
void purge_state(const node_id& nid) override; void purge_state(const node_id& nid) override;
// inherited from basp::instance::callee
void proxy_announced(const node_id& nid, actor_id aid) override; void proxy_announced(const node_id& nid, actor_id aid) override;
// performs bookkeeping such as managing `spawn_servers`
void learned_new_node(const node_id& nid);
// inherited from basp::instance::callee
void learned_new_node_directly(const node_id& nid, void learned_new_node_directly(const node_id& nid,
bool was_indirectly_before) override; bool was_indirectly_before) override;
// inherited from basp::instance::callee
void learned_new_node_indirectly(const node_id& nid) override; void learned_new_node_indirectly(const node_id& nid) override;
// inherited from basp::instance::callee
buffer_type& get_buffer(connection_handle hdl) override; buffer_type& get_buffer(connection_handle hdl) override;
// inherited from basp::instance::callee
void flush(connection_handle hdl) override; void flush(connection_handle hdl) override;
// inherited from basp::instance::callee
void handle_heartbeat() override; void handle_heartbeat() override;
// inherited from basp::instance::callee
execution_unit* current_execution_unit() override; execution_unit* current_execution_unit() override;
// -- utility functions ------------------------------------------------------
/// Performs bookkeeping such as managing `spawn_servers`.
void learned_new_node(const node_id& nid);
/// Sets `this_context` by either creating or accessing state for `hdl`. /// Sets `this_context` by either creating or accessing state for `hdl`.
void set_context(connection_handle hdl); void set_context(connection_handle hdl);
/// Cleans up any state for `hdl`. /// Cleans up any state for `hdl`.
void cleanup(connection_handle hdl); void connection_cleanup(connection_handle hdl);
// pointer to ourselves /// Sends a basp::down_message message to a remote node.
broker* self; void send_basp_down_message(const node_id& nid, actor_id aid, error err);
// protocol instance of BASP // Sends basp::down_message to all nodes monitoring the terminated actor.
basp::instance instance; void handle_down_msg(down_msg&);
using ctx_map = std::unordered_map<connection_handle, basp::endpoint_context>; // -- disambiguation for functions found in multiple base classes ------------
actor_system& system() {
return super::system();
}
const actor_system_config& config() {
return system().config();
}
// -- member variables -------------------------------------------------------
// keeps context information for all open connections /// Protocol instance of BASP.
basp::instance instance;
/// Keeps context information for all open connections.
ctx_map ctx; ctx_map ctx;
// points to the current context for callbacks such as `make_proxy` /// points to the current context for callbacks.
basp::endpoint_context* this_context = nullptr; basp::endpoint_context* this_context;
// stores handles to spawn servers for other nodes; these servers /// Stores handles to spawn servers for other nodes. These servers are
// are spawned whenever the broker learns a new node ID and try to /// spawned whenever the broker learns a new node ID and tries to get a
// get a 'SpawnServ' instance on the remote side /// 'SpawnServ' instance on the remote side.
std::unordered_map<node_id, actor> spawn_servers; std::unordered_map<node_id, actor> spawn_servers;
/// Configures whether BASP automatically open new connections to optimize /// Configures whether BASP automatically open new connections to optimize
/// routing paths by forming a mesh between all nodes. /// routing paths by forming a mesh between all nodes.
bool automatic_connections = false; bool automatic_connections = false;
// timeout for delivery of pending messages of endpoints with ordering /// Returns the node identifier of the underlying BASP instance.
const std::chrono::milliseconds pending_to = std::chrono::milliseconds(100);
// returns the node identifier of the underlying BASP instance
const node_id& this_node() const { const node_id& this_node() const {
return instance.this_node(); return instance.this_node();
} }
using monitored_actor_map = /// Keeps track of nodes that monitor local actors.
std::unordered_map<actor_addr, std::unordered_set<node_id>>;
// keeps a list of nodes that monitor a particular local actor
monitored_actor_map monitored_actors; monitored_actor_map monitored_actors;
// sends a basp::down_message message to a remote node
void send_basp_down_message(const node_id& nid, actor_id aid, error err);
// sends basp::down_message to all nodes monitoring the terminated
// actor
void handle_down_msg(down_msg&);
static const char* name;
};
/// A broker implementation for the Binary Actor System Protocol (BASP).
class basp_broker : public stateful_actor<basp_broker_state, broker> {
public:
using super = stateful_actor<basp_broker_state, broker>;
explicit basp_broker(actor_config& cfg);
behavior make_behavior() override;
proxy_registry* proxy_registry_ptr() override;
resume_result resume(execution_unit*, size_t) override;
}; };
} // namespace io } // namespace io
} // namespace caf } // namespace caf
This diff is collapsed.
...@@ -200,17 +200,17 @@ public: ...@@ -200,17 +200,17 @@ public:
// implementation of the Binary Actor System Protocol // implementation of the Binary Actor System Protocol
basp::instance& instance() { basp::instance& instance() {
return aut()->state.instance; return aut()->instance;
} }
// our routing table (filled by BASP) // our routing table (filled by BASP)
basp::routing_table& tbl() { basp::routing_table& tbl() {
return aut()->state.instance.tbl(); return aut()->instance.tbl();
} }
// access to proxy instances // access to proxy instances
proxy_registry& proxies() { proxy_registry& proxies() {
return aut()->state.proxies(); return aut()->proxies();
} }
// stores the singleton pointer for convenience // stores the singleton pointer for convenience
......
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