Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shutdown node when component startup fails #1028

Merged
merged 3 commits into from
Aug 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ Every entry has a category for which we use the following visual abbreviations:

## Unreleased

- 🐞 VAST did not terminate when a critical component failed during startup.
VAST now binds the lifetime of the node to all critical components.
[#1028](https://github.com/tenzir/vast/pull/1028)

- 🐞 VAST would overwrite existing on-disk state data when encountering a partial
read during startup. This state-corrupting behavior no longer exists.
[#1026](https://github.com/tenzir/vast/pull/1026)
Expand Down
14 changes: 14 additions & 0 deletions libvast/src/system/component_registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,20 @@ bool component_registry::remove(const caf::actor& comp) {
return false;
}

const std::string*
component_registry::find_label_for(const caf::actor& comp) const {
auto pred = [&](auto& x) { return x.second.actor == comp; };
auto i = std::find_if(components_.begin(), components_.end(), pred);
return i != components_.end() ? &i->first : nullptr;
}

const std::string*
component_registry::find_type_for(const caf::actor& comp) const {
auto pred = [&](auto& x) { return x.second.actor == comp; };
auto i = std::find_if(components_.begin(), components_.end(), pred);
return i != components_.end() ? &i->second.type : nullptr;
}

caf::actor component_registry::find_by_label(std::string_view label) const {
// TODO: remove string conversion in with C++20 transparent keys.
if (auto i = components_.find(std::string{label}); i != components_.end())
Expand Down
9 changes: 9 additions & 0 deletions libvast/src/system/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,15 @@ caf::behavior node(node_actor* self, std::string name, path dir,
self->set_down_handler([=](const down_msg& msg) {
VAST_DEBUG(self, "got DOWN from", msg.source);
auto component = caf::actor_cast<caf::actor>(msg.source);
auto type = self->state.registry.find_type_for(component);
// All monitored components are in the registry.
VAST_ASSERT(type != nullptr);
if (is_singleton(*type)) {
auto label = self->state.registry.find_label_for(component);
VAST_ASSERT(label != nullptr); // Per the above assertion.
VAST_ERROR(self, "got DOWN from", *label, "; initiating shutdown");
self->send_exit(self, caf::exit_reason::user_shutdown);
}
self->state.registry.remove(component);
});
// Terminate deterministically on shutdown.
Expand Down
12 changes: 12 additions & 0 deletions libvast/vast/system/component_registry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@ class component_registry {
/// @returns `true` iff the component was deleted successfully.
bool remove(const caf::actor& comp);

/// Finds the label of a given component actor.
/// @param comp The component actor.
/// @returns A pointer to the name of the label of *comp* or `nullptr` if
/// *comp* is not known.
const std::string* find_label_for(const caf::actor& comp) const;

/// Finds the type of a given component actor.
/// @param comp The component actor.
/// @returns A pointer to the name of the type of *comp* or `nullptr` if
/// *comp* is not known.
const std::string* find_type_for(const caf::actor& comp) const;

/// Locates a component by label.
/// @param label The label of the component to lookup.
/// @returns The respective component actor if found.
Expand Down