uint16_t publish_local_groups(uint16_t port, const char* addr) { auto gn = spawn<group_nameserver, hidden>(); uint16_t result; try { result = publish(gn, port, addr); } catch (std::exception&) { anon_send_exit(gn, exit_reason::user_shutdown); throw; } middleman::instance()->add_shutdown_cb([gn] { anon_send_exit(gn, exit_reason::user_shutdown); }); return result; }
uint16_t publish_local_groups(uint16_t port, const char* addr) { auto group_nameserver = []() -> behavior { return { [](get_atom, const std::string& name) { return group::get("local", name); } }; }; auto gn = spawn<hidden>(group_nameserver); uint16_t result; try { result = publish(gn, port, addr); } catch (std::exception&) { anon_send_exit(gn, exit_reason::user_shutdown); throw; } middleman::instance()->add_shutdown_cb([gn] { anon_send_exit(gn, exit_reason::user_shutdown); }); return result; }
actor_system::~actor_system() { if (await_actors_before_shutdown_) await_all_actors_done(); // shutdown system-level servers anon_send_exit(spawn_serv_, exit_reason::user_shutdown); anon_send_exit(config_serv_, exit_reason::user_shutdown); // release memory as soon as possible spawn_serv_ = nullptr; config_serv_ = nullptr; registry_.erase(atom("SpawnServ")); registry_.erase(atom("ConfigServ")); // group module is the first one, relies on MM groups_.stop(); // stop modules in reverse order for (auto i = modules_.rbegin(); i != modules_.rend(); ++i) if (*i) (*i)->stop(); await_detached_threads(); registry_.stop(); logger_.stop(); CAF_SET_LOGGER_SYS(nullptr); }
void anon_send_exit(const ActorHandle& to, uint32_t reason) { anon_send_exit(to.address(), reason); }
trial<actor> spawn(message const& params) { auto schema_file = ""s; auto output = "-"s; auto r = params.extract_opts({ {"schema,s", "alternate schema file", schema_file}, {"write,w", "path to write events to", output}, {"uds,u", "treat -w as UNIX domain socket to connect to"} }); // Setup a custom schema. schema sch; if (!schema_file.empty()) { auto t = load_contents(schema_file); if (!t) return t.error(); auto s = to<schema>(*t); if (!s) return error{"failed to load schema"}; sch = std::move(*s); } // Facilitate actor shutdown when returning with error. actor snk; auto guard = make_scope_guard([&] { anon_send_exit(snk, exit::error); }); // The "pcap" and "bro" sink manually handle file output. All other // sources are file-based and we setup their input stream here. auto& format = params.get_as<std::string>(0); std::unique_ptr<std::ostream> out; if (!(format == "pcap" || format == "bro")) { if (r.opts.count("uds") > 0) { if (output == "-") return error{"cannot use stdout as UNIX domain socket"}; auto uds = util::unix_domain_socket::connect(output); if (!uds) return error{"failed to connect to UNIX domain socket at ", output}; auto remote_fd = uds.recv_fd(); // Blocks! out = std::make_unique<util::fdostream>(remote_fd); } else if (output == "-") { out = std::make_unique<util::fdostream>(1); // stdout } else { out = std::make_unique<std::ofstream>(output); } } if (format == "pcap") { #ifndef VAST_HAVE_PCAP return error{"not compiled with pcap support"}; #else auto flush = 10000u; r = r.remainder.extract_opts({ {"flush,f", "flush to disk after this many packets", flush} }); if (!r.error.empty()) return error{std::move(r.error)}; snk = caf::spawn<priority_aware>(pcap, sch, output, flush); #endif } else if (format == "bro") { snk = caf::spawn(bro, output); } else if (format == "csv") { snk = caf::spawn(csv, std::move(out)); } else if (format == "ascii") { snk = caf::spawn(ascii, std::move(out)); } else if (format == "json") { r = r.remainder.extract_opts({ {"flatten,f", "flatten records"} }); snk = caf::spawn(sink::json, std::move(out), r.opts.count("flatten") > 0); // FIXME: currently the "vast export" command cannot take sink parameters, // which is why we add a hacky convenience sink called "flat-json". We should // have a command line format akin to "vast export json -f query ...", // which would allow passing both sink and exporter arguments. } else if (format == "flat-json") { snk = caf::spawn(sink::json, std::move(out), true); } else { return error{"invalid export format: ", format}; } guard.disable(); return snk; }