Env amends#436
Conversation
| std::string | ||
| EnvironmentManager::ExtractIfNotExtracted(std::string env_path) | ||
| std::shared_ptr<Environment> // TODO: write logic with shared and weak ptrs in this method | ||
| EnvironmentManager::GetEnvironment(ModelState* model_state) |
There was a problem hiding this comment.
I think EnvironmentManager doesn't need to know about model_state
| const auto env_itr = env_map_.find(canonical_env_path); | ||
|
|
||
| std::string model_id = model_state.GetModelId(); | ||
| std::string env_key = model_state->Name() + "-" + model_id; |
There was a problem hiding this comment.
Why do we need to add model name here? Multiple models could refer to the same environment
| // need to be extracted again. | ||
| if (env_itr->second.second == last_modified_time) { | ||
| // need to be extracted again (or the current environment has no owners anymore). | ||
| if (env_itr->second.first.expired()) { |
There was a problem hiding this comment.
This condition is executed only if env has already been destroyed and model has to recreate it
Also, when deleting the environment, we want to remove its key from the map
In this case, we can’t derive the environment directory name from the map size, because that could cause environments to overwrite each other.
| if (env_itr->second.first.expired()) { | ||
| env_map_.erase(env_itr); | ||
| } else if (env_itr->second.second == last_modified_time) { | ||
| env_extracted = true; |
There was a problem hiding this comment.
We could store last_modified_time in Environment structure
| canonical_env_path) | ||
| .c_str()); | ||
| return canonical_env_path; | ||
| return std::make_shared<Environment>(canonical_env_path, canonical_env_path); |
There was a problem hiding this comment.
We should return nullptr here instead
| std::string dst_env_path; | ||
| if (re_extraction) { | ||
| dst_env_path = env_map_[canonical_env_path].first; | ||
| dst_env_path = env_map_[env_key].first; |
There was a problem hiding this comment.
I don't think this will compile
It's better to call the ->Path() method here
| } | ||
|
|
||
| Environment::Environment(const std::string& source, const std::string& path) : source_(source), path_(path) { | ||
| if (source == path) { |
There was a problem hiding this comment.
Let's check this condition before creating the object.
Also, in this case, destructor will be called with an invalid Path value
| #include <mutex> | ||
| #include <string> | ||
|
|
||
| #include "python_be.h" |
There was a problem hiding this comment.
We don't need this include if we remove model_state from the GetEnvironment signature
| model_state->StateForBackend()->env_manager->ExtractIfNotExtracted( | ||
| python_execution_env_); | ||
| python_execution_env_ = | ||
| std::move(model_state->StateForBackend()->env_manager->GetEnvironment(model_state)); |
There was a problem hiding this comment.
We don't need this std::move here because copy elision will work here
| if (re_extraction) { | ||
| // Just update the last modified timestamp | ||
| env_map_[canonical_env_path].second = last_modified_time; | ||
| if (re_extraction ) { |
There was a problem hiding this comment.
Let's merge this condition with the condition on line 308
| // Add the environment to the list of environments | ||
| env = std::make_shared<Environment>( | ||
| canonical_env_path_str, dst_env_path, last_modified_time); | ||
| env->SetManager(this); |
There was a problem hiding this comment.
Why do we need a separate method for this? Let's pass it into the Environment constructor
| Environment::~Environment() | ||
| { | ||
| if (manager_ != nullptr) { | ||
| manager_->env_map_.erase(source_); |
There was a problem hiding this comment.
This map is protected by a mutex inside manager_
Let's add a method inside EnvironmentManager struct that locks the mutex and erases environment from the map.
| const std::string& Source() const { return source_; } | ||
| const std::string& Path() const { return path_; } | ||
| const time_t& LastModifiedTime() const { return last_modified_time_; } | ||
| explicit operator std::string() const { return Path(); } |
| const auto env_itr = env_map_.find(canonical_env_path); | ||
|
|
||
| std::string canonical_env_path_str(canonical_env_path); | ||
| std::string env_key = canonical_env_path_str; |
There was a problem hiding this comment.
Why do we need three identical variables canonical_env_path_str, env_key and canonical_env_path?
I would write something like this:
std::string canonical_env_path = [&]{
char canonical_env_path[PATH_MAX + 1];
char* err = realpath(env_path.c_str(), canonical_env_path);
if (err == nullptr) {
throw PythonBackendException(
std::string("Failed to get the canonical path for ") + env_path + ".");
}
return std::string(canonical_env_path);
}();And drop the other variables: canonical_env_path_str, env_key
| // anymore). | ||
|
|
||
| if (env == nullptr) { | ||
| // refer to case when env was not loaded |
There was a problem hiding this comment.
We will enter this condition if an environment with such a key existed and was dropped earlier
Not because the environment hasn't been loaded yet
There was a problem hiding this comment.
it simulates when env was not loaded, because we are deleting notice about it in map
There was a problem hiding this comment.
I said: "refers to case", but not "this is case when"
| EnvironmentManager::ExtractIfNotExtracted(std::string env_path) | ||
|
|
||
| std::shared_ptr< | ||
| Environment> // TODO: write logic with shared and weak ptrs in this method |
| } | ||
| const auto env_itr = env_map_.find(canonical_env_path); | ||
|
|
||
| std::string& env_key = canonical_env_path; |
|
|
||
| std::string canonical_env_path_str(canonical_env_path); | ||
| if (!re_extraction) { | ||
| env->AddOwner(); |
There was a problem hiding this comment.
We should increment reference count on each ExtractIfNotExtracted call
| } | ||
| const auto env_itr = env_map_.find(canonical_env_path); | ||
|
|
||
| return EnvironmentGuard(*this, canonical_env_path); |
There was a problem hiding this comment.
Let's create environment here and pass it explicitly to the constructor
No description provided.