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);
}
Exemple #4
0
void anon_send_exit(const ActorHandle& to, uint32_t reason) {
  anon_send_exit(to.address(), reason);
}
Exemple #5
0
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;
}