Skip to content
This repository has been archived by the owner on Aug 19, 2019. It is now read-only.

Commit

Permalink
Memoize owner objects instead of querying the master all the time. (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
igorpeshansky authored Dec 20, 2017
1 parent 357355b commit 234ffbb
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 5 deletions.
39 changes: 34 additions & 5 deletions src/kubernetes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -527,13 +527,42 @@ json::value KubernetesReader::GetOwner(
const std::string api_version = owner_ref->Get<json::String>("apiVersion");
const std::string kind = owner_ref->Get<json::String>("kind");
const std::string name = owner_ref->Get<json::String>("name");
const auto path_component = KindPath(api_version, kind);
const std::string uid = owner_ref->Get<json::String>("uid");

// Even though we query by name, we should look up the owner by uid,
// to handle the case when an object is deleted and re-constructed.
const std::string encoded_ref = boost::algorithm::join(
std::vector<std::string>{api_version, kind, uid}, "/");

std::lock_guard<std::recursive_mutex> lock(mutex_);
auto found = owners_.emplace(std::piecewise_construct,
std::forward_as_tuple(encoded_ref),
std::forward_as_tuple());
json::value& owner = found.first->second;
if (found.second) { // Not found, inserted new.
const auto path_component = KindPath(api_version, kind);
#ifdef VERBOSE
LOG(DEBUG) << "KindPath returned {" << path_component.first << ", "
<< path_component.second << "}";
LOG(DEBUG) << "KindPath returned {" << path_component.first << ", "
<< path_component.second << "}";
#endif
return QueryMaster(path_component.first + "/namespaces/" + ns + "/" +
path_component.second + "/" + name);
owner = std::move(
QueryMaster(path_component.first + "/namespaces/" + ns + "/" +
path_component.second + "/" + name));
// Sanity check: because we are looking up by name, the object we get
// back might have a different uid.
const json::Object* owner_obj = owner->As<json::Object>();
const json::Object* metadata = owner_obj->Get<json::Object>("metadata");
const std::string owner_uid = metadata->Get<json::String>("uid");
if (owner_uid != uid) {
LOG(WARNING) << "Owner " << kind << "'" << name << "' (id " << uid
<< ") disappeared before we could query it. Found id "
<< owner_uid << " instead.";
owner.reset();
throw QueryException("Owner " + kind + " " + name + " (id " + uid +
") disappeared");
}
}
return owner->Clone();
}

json::value KubernetesReader::FindTopLevelOwner(
Expand Down
2 changes: 2 additions & 0 deletions src/kubernetes.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ class KubernetesReader {
// A memoized map from version to a map from kind to name.
mutable std::map<std::string, std::map<std::string, std::string>>
version_to_kind_to_name_;
// A memoized map from an encoded owner reference to the owner object.
mutable std::map<std::string, json::value> owners_;

const MetadataAgentConfiguration& config_;
Environment environment_;
Expand Down

0 comments on commit 234ffbb

Please sign in to comment.