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;
}
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.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 callsself->quit()
. You could force it viaanon_send_exit(world_actor, exit_reason::user_shutdown)
. Terminating it will also remove it from the registry, as stated in the manual.