-
Notifications
You must be signed in to change notification settings - Fork 202
Env amends #436
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
base: main
Are you sure you want to change the base?
Env amends #436
Changes from 5 commits
e5de787
25b2e25
689333c
c0db109
02e9357
5c4a52c
d4a0c77
f4c2fcd
fcff38c
d7b10fb
013684e
913da36
ce296e6
cb627f5
9527d1c
597c92d
20f86eb
be0d50f
9eb0112
70fb469
15a5cd5
9745dfd
534f20c
d7658c5
9104caf
a72f975
3bf8ae1
b58cee8
aa90bd5
a1c6a02
b6d124c
0fb628b
e270a41
d9fbe30
91697dd
3a7ba79
06e5646
f97e8f6
163c241
1c2b223
b67e081
98e429d
1856c59
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -228,6 +228,9 @@ RecursiveDirectoryDelete(const char* dir) | |
|
|
||
| EnvironmentManager::EnvironmentManager() | ||
| { | ||
| LOG_MESSAGE( | ||
| TRITONSERVER_LOG_VERBOSE, | ||
| "EnvironmentManager constructor: initializing Python env manager"); | ||
| char tmp_dir_template[PATH_MAX + 1]; | ||
| strcpy(tmp_dir_template, "/tmp/python_env_XXXXXX"); | ||
|
|
||
|
|
@@ -239,13 +242,14 @@ EnvironmentManager::EnvironmentManager() | |
| strcpy(base_path_, tmp_dir_template); | ||
| } | ||
|
|
||
| std::string | ||
| EnvironmentManager::ExtractIfNotExtracted(std::string env_path) | ||
| std::shared_ptr< | ||
| Environment> // TODO: write logic with shared and weak ptrs in this method | ||
| EnvironmentManager::ExtractIfNotExtracted(const std::string& env_path) | ||
| { | ||
| // Lock the mutex. Only a single thread should modify the map. | ||
| std::lock_guard<std::mutex> lk(mutex_); | ||
| char canonical_env_path[PATH_MAX + 1]; | ||
|
|
||
| char canonical_env_path[PATH_MAX + 1]; | ||
| char* err = realpath(env_path.c_str(), canonical_env_path); | ||
| if (err == nullptr) { | ||
| throw PythonBackendException( | ||
|
|
@@ -270,19 +274,24 @@ EnvironmentManager::ExtractIfNotExtracted(std::string env_path) | |
| "not contain compressed path. Path: ") + | ||
| canonical_env_path) | ||
| .c_str()); | ||
| return canonical_env_path; | ||
| return nullptr; | ||
| } | ||
| 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; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need three identical variables 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: |
||
| const auto env_itr = env_map_[env_key]; | ||
| std::shared_ptr<Environment> env; | ||
| if (env_itr != env_map_.end()) { | ||
| env = env_itr->second.lock(); | ||
| // Check if the environment has been modified and would | ||
| // 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). | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. old comment that is need to be deleted
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. notice it |
||
| if (env->LastModifiedTime() == last_modified_time) { | ||
| env_extracted = true; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could store
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But this is done this way already, am I right? |
||
| } else { | ||
| // Environment file has been updated. Need to clear | ||
| // the previously extracted environment and extract | ||
| // the environment to the same destination directory. | ||
| RecursiveDirectoryDelete(env_itr->second.first.c_str()); | ||
| re_extraction = true; | ||
| } | ||
| } | ||
|
|
@@ -291,44 +300,84 @@ EnvironmentManager::ExtractIfNotExtracted(std::string env_path) | |
| if (!env_extracted) { | ||
| LOG_MESSAGE( | ||
| TRITONSERVER_LOG_VERBOSE, | ||
| (std::string("Extracting Python execution env ") + canonical_env_path) | ||
| (std::string("Extracting Python execution env ") + | ||
| canonical_env_path) | ||
| .c_str()); | ||
|
|
||
| std::string dst_env_path; | ||
| if (re_extraction) { | ||
| dst_env_path = env_map_[canonical_env_path].first; | ||
| dst_env_path = env->Path(); | ||
| } else { | ||
| dst_env_path = | ||
| std::string(base_path_) + "/" + std::to_string(env_map_.size()); | ||
| std::string(base_path_) + "/" + std::to_string(env_path_counter_); | ||
| ++env_path_counter_; | ||
| } | ||
|
|
||
| std::string canonical_env_path_str(canonical_env_path); | ||
|
|
||
| int status = | ||
| mkdir(dst_env_path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); | ||
| if (status == 0) { | ||
| ExtractTarFile(canonical_env_path_str, dst_env_path); | ||
| } else { | ||
| throw PythonBackendException( | ||
| std::string("Failed to create environment directory for '") + | ||
| dst_env_path.c_str() + "'."); | ||
| } | ||
| if (re_extraction) { | ||
| // Just update the last modified timestamp | ||
| env_map_[canonical_env_path].second = last_modified_time; | ||
| if (re_extraction ) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's merge this condition with the condition on line 308 |
||
| // Just replace with new environment (by updated source) | ||
| env->Update(last_modified_time); | ||
| } else { | ||
| // Add the path to the list of environments | ||
| env_map_.insert({canonical_env_path, {dst_env_path, last_modified_time}}); | ||
| // 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); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need a separate method for this? Let's pass it into the Environment constructor |
||
| env_map_.insert({env_key, new_env}); | ||
| } | ||
| return dst_env_path; | ||
| } else { | ||
| return env_map_.find(canonical_env_path)->second.first; | ||
| } | ||
|
|
||
| return env; | ||
| } | ||
|
|
||
| EnvironmentManager::~EnvironmentManager() | ||
| { | ||
| RecursiveDirectoryDelete(base_path_); | ||
| } | ||
|
|
||
| Environment::Environment( | ||
| const std::string& source, const std::string& path, | ||
| const time_t& last_modified_time) | ||
| : source_(source), path_(path), | ||
| last_modified_time_(std::to_string(last_modified_time)) | ||
| { | ||
| Extract(); | ||
| } | ||
|
|
||
| void | ||
| Environment::Extract() | ||
| { | ||
| int status = | ||
| mkdir(dst_env_path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); | ||
| if (status != 0) { | ||
| throw PythonBackendException( | ||
| std::string("Failed to create environment directory for '") + | ||
| dst_env_path.c_str() + "'."); | ||
| } | ||
| ExtractTarFile(source_, path_); | ||
| } | ||
|
|
||
| void | ||
| Environment::Update(const time_t& last_modified_time) | ||
| { | ||
| Delete(); | ||
| Extract(); | ||
| last_modified_time_ = last_modified_time; | ||
| } | ||
|
|
||
| void | ||
| Environment::Delete() | ||
| { | ||
| RecursiveDirectoryDelete(path_.c_str()); | ||
| } | ||
|
|
||
| Environment::~Environment() | ||
| { | ||
| if (manager_ != nullptr) { | ||
| manager_->env_map_.erase(source_); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This map is protected by a mutex inside |
||
| } | ||
| Delete(); | ||
| } | ||
|
|
||
|
|
||
| #endif | ||
|
|
||
| }}} // namespace triton::backend::python | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,7 @@ | |
| #pragma once | ||
| #include <climits> | ||
| #include <map> | ||
| #include <memory> | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for what |
||
| #include <mutex> | ||
| #include <string> | ||
|
|
||
|
|
@@ -46,17 +47,46 @@ bool FileExists(std::string& path); | |
| // | ||
| #ifndef _WIN32 | ||
| class EnvironmentManager { | ||
| std::map<std::string, std::pair<std::string, time_t>> env_map_; | ||
| char base_path_[PATH_MAX + 1]; | ||
| std::mutex mutex_; | ||
|
|
||
| public: | ||
| class Environment { | ||
| public: | ||
| friend class EnvironmentManager; | ||
| Environment( | ||
| const std::string& source, const std::string& path, | ||
| const time_t& last_modified_time); | ||
| void SetManager(EnvironmentManager* manager) { manager_ = manager; } | ||
|
|
||
| void Update(const time_t& last_modified_time); | ||
|
|
||
| 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(); } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Useless operator |
||
|
|
||
| private: | ||
| void Extract(); | ||
| void Delete(); | ||
|
|
||
| std::string source_; | ||
| std::string path_; | ||
| time_t last_modified_time_; | ||
|
|
||
| EnvironmentManager* manager_ = nullptr; | ||
| }; | ||
|
|
||
| EnvironmentManager(); | ||
|
|
||
| // Extracts the tar.gz file in the 'env_path' if it has not been | ||
| // already extracted. | ||
| std::string ExtractIfNotExtracted(std::string env_path); | ||
| std::shared_ptr<Environment> ExtractIfNotExtracted( | ||
| const std::string& env_path); | ||
| ~EnvironmentManager(); | ||
|
|
||
| private: | ||
| size_t env_path_counter_ = 0; | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. useless field
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. obviously not! |
||
| std::map<std::string, std::weak_ptr<Environment>> env_map_; | ||
| char base_path_[PATH_MAX + 1]; | ||
| std::mutex mutex_; | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe rename to point out that this mutex is for map asynchronous safety
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. leave it for readability |
||
| }; | ||
| #endif | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's drop the useless comment here