Example #1
0
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");
    }
}
Example #2
0
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
  }
}
Example #4
0
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;
}