void peer::link(const actor_addr& lhs, const actor_addr& rhs) { // this message is sent from default_actor_proxy in link_to and // establish_backling to cause the original actor (sender) to establish // a link to ptr as well CPPA_LOG_TRACE(CPPA_TARG(lhs, to_string) << ", " << CPPA_TARG(rhs, to_string)); CPPA_LOG_ERROR_IF(!lhs, "received 'LINK' from invalid sender"); CPPA_LOG_ERROR_IF(!rhs, "received 'LINK' with invalid receiver"); if (!lhs || !rhs) return; auto locally_link_proxy = [](const actor_addr& proxy, const actor_addr& addr) { // again, no need to to use a dynamic_cast here auto ptr = static_cast<actor_proxy*>(detail::raw_access::get(proxy)); ptr->local_link_to(addr); }; switch ((lhs.is_remote() ? 0x10 : 0x00) | (rhs.is_remote() ? 0x01 : 0x00)) { case 0x00: // both local case 0x11: // both remote detail::raw_access::get(lhs)->link_to(rhs); break; case 0x10: // sender is remote locally_link_proxy(lhs, rhs); break; case 0x01: // receiver is remote locally_link_proxy(rhs, lhs); break; default: CPPA_LOG_ERROR("logic error"); } }
void peer::unlink(const actor_addr& lhs, const actor_addr& rhs) { CPPA_LOG_TRACE(CPPA_TARG(lhs, to_string) << ", " << CPPA_TARG(rhs, to_string)); CPPA_LOG_ERROR_IF(!lhs, "received 'UNLINK' from invalid sender"); CPPA_LOG_ERROR_IF(!rhs, "received 'UNLINK' with invalid target"); if (!lhs || !rhs) return; auto locally_unlink_proxy = [](const actor_addr& proxy, const actor_addr& addr) { // again, no need to to use a dynamic_cast here auto ptr = static_cast<actor_proxy*>(detail::raw_access::get(proxy)); ptr->local_unlink_from(addr); }; switch ((lhs.is_remote() ? 0x10 : 0x00) | (rhs.is_remote() ? 0x01 : 0x00)) { case 0x00: // both local case 0x11: // both remote detail::raw_access::get(lhs)->unlink_from(rhs); break; case 0x10: // sender is remote locally_unlink_proxy(lhs, rhs); break; case 0x01: // receiver is remote locally_unlink_proxy(rhs, lhs); break; default: CPPA_LOG_ERROR("logic error"); } }
void actor_namespace::write(serializer* sink, const actor_addr& addr) { CAF_ASSERT(sink != nullptr); if (! addr) { node_id::host_id_type zero; std::fill(zero.begin(), zero.end(), 0); sink->write_value(static_cast<actor_id>(0)); // actor id sink->write_raw(node_id::host_id_size, zero.data()); // host id sink->write_value(static_cast<uint32_t>(0)); // process id } else { // register locally running actors to be able to deserialize them later if (! addr.is_remote()) { auto reg = detail::singletons::get_actor_registry(); reg->put(addr.id(), actor_cast<abstract_actor_ptr>(addr)); } auto pinf = addr.node(); sink->write_value(addr.id()); // actor id sink->write_raw(node_id::host_id_size, pinf.host_id().data()); // host id sink->write_value(pinf.process_id()); // process id } }
bool instance::dispatch(const actor_addr& sender, const actor_addr& receiver, message_id mid, const message& msg) { CAF_LOG_TRACE(""); CAF_ASSERT(receiver.is_remote()); auto path = lookup(receiver->node()); if (! path) { notify<hook::message_sending_failed>(sender, receiver, mid, msg); return false; } auto writer = make_callback([&](serializer& sink) { msg.serialize(sink); }); header hdr{message_type::dispatch_message, 0, mid.integer_value(), sender ? sender->node() : this_node(), receiver->node(), sender ? sender->id() : invalid_actor_id, receiver->id()}; write(path->wr_buf, hdr, &writer); flush(*path); notify<hook::message_sent>(sender, path->next_hop, receiver, mid, msg); return true; }