Why CAF system.registry() should call erase(atom_value) automatically after put(atom_value)

159 views Asked by At

I want to use system.registry() in caf-0.15.7 to make actors system-wide available by name, when I put two actors to its name by calling put(atom_value, actor), my progress will not terminate automatically, and it will stop until I kill it.

However when I add erase() explicitly, it will exit.

Actually as CAF manual section 8 said:

Actors are removed automatically when they terminate.

And that's what I want. So I'm wondering whether it's a bug or not.

  • I am running on MacOS 10.13.4,
  • the compiler is Apple LLVM version 9.1.0 (clang-902.0.39.2).
  • CAF version: 0.15.7

For reproducing my results, please run the following c++ code:

#include <string>
#include <iostream>
#include "caf/all.hpp"
#include "caf/io/all.hpp"


using std::endl;
using std::string;
using namespace caf;

atom_value world_atom = atom("world_act");
atom_value hello_atom = atom("hello_act");

behavior world(event_based_actor *self) {

  return behavior {
    [=](const string &what) {
      aout(self) << "Message: " << what << endl;
      return std::string{"World"};
    }
  };
}

void hello(event_based_actor* self) {

  string out_msg{"Hello "};
  auto tmp = self->home_system().registry().get(world_atom);
  auto buddy = actor_cast<actor>(tmp);

  self->request(actor_cast<actor>(tmp), std::chrono::seconds(2), out_msg).then(
    [=] (const string& what) {
      aout(self) << "Message: " << what << endl;
    });
}

int main() {
  actor_system_config cfg;
  actor_system system{cfg};

  auto world_actor = system.spawn(world);
  system.registry().put(world_atom, world_actor);

  auto hello_actor = system.spawn(hello);
  system.registry().put(hello_atom, hello_actor);

  std::cout << "current running: " << system.registry().running() << endl;

  /* Uncomment the following three lines if you want to stop automatically */
//  getchar();
//  system.registry().erase(hello_atom);
//  system.registry().erase(world_atom);

  return 0;

}
1

There are 1 answers

0
neverlord On

Your process won't terminate, because CAF's actor system waits for all actors before shutting down. A usual CAF application uses main only to spin up actors.

Actors are removed automatically when they terminate.

And that's what I want.

The moment you remove your actors from the registry in your example, they become unreachable and terminate as a result. Once your actors all terminate, the actor system shuts down. However, your snippet never terminates the world actor explicitly, i.e., it never calls self->quit(). You could force it via anon_send_exit(world_actor, exit_reason::user_shutdown). Terminating it will also remove it from the registry, as stated in the manual.