1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

Recent updates in storage (#667)

* Fix error handling in Torrent.cpp, improve choosing peers for upload

* Various improvements in storage daemon

"get-pieces-info"
Store "added at"
Improve calculating up/down speed
Improve TL protocol for future compatibility
Remove empty directories on "--remove-files"
Better windows support
Debug logs in PeerActor
More restrictions on TorrentInfo
Bugfixes

* Global speed limits for download and upload

+bugfix

* Reset download/upload speed on changing settings or completion

* Exclude some system files in TorrentCreator
This commit is contained in:
SpyCheese 2023-04-07 12:50:07 +00:00 committed by GitHub
parent e3af63e6c0
commit bb21f732fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 974 additions and 213 deletions

View file

@ -50,6 +50,29 @@ void StorageManager::start_up() {
db_ = std::make_shared<db::DbType>(
std::make_shared<td::RocksDb>(td::RocksDb::open(db_root_ + "/torrent-db").move_as_ok()));
db::db_get<ton_api::storage_db_config>(
*db_, create_hash_tl_object<ton_api::storage_db_key_config>(), true,
[SelfId = actor_id(this)](td::Result<tl_object_ptr<ton_api::storage_db_config>> R) {
if (R.is_error()) {
LOG(ERROR) << "Failed to load config from db: " << R.move_as_error();
td::actor::send_closure(SelfId, &StorageManager::loaded_config_from_db, nullptr);
} else {
td::actor::send_closure(SelfId, &StorageManager::loaded_config_from_db, R.move_as_ok());
}
});
}
void StorageManager::loaded_config_from_db(tl_object_ptr<ton_api::storage_db_config> config) {
if (config) {
LOG(INFO) << "Loaded config from DB. Speed limits: download=" << config->download_speed_limit_
<< ", upload=" << config->upload_speed_limit_;
download_speed_limit_ = config->download_speed_limit_;
upload_speed_limit_ = config->upload_speed_limit_;
td::actor::send_closure(download_speed_limiter_, &SpeedLimiter::set_max_speed, download_speed_limit_);
td::actor::send_closure(upload_speed_limiter_, &SpeedLimiter::set_max_speed, upload_speed_limit_);
}
db::db_get<ton_api::storage_db_torrentList>(
*db_, create_hash_tl_object<ton_api::storage_db_key_torrentList>(), true,
[SelfId = actor_id(this)](td::Result<tl_object_ptr<ton_api::storage_db_torrentList>> R) {
@ -79,6 +102,7 @@ void StorageManager::load_torrents_from_db(std::vector<td::Bits256> torrents) {
client_mode_, overlays_, adnl_, rldp_);
NodeActor::load_from_db(
db_, hash, create_callback(hash, entry.closing_state), PeerManager::create_callback(entry.peer_manager.get()),
SpeedLimiters{download_speed_limiter_.get(), upload_speed_limiter_.get()},
[SelfId = actor_id(this), hash,
promise = ig.get_promise()](td::Result<td::actor::ActorOwn<NodeActor>> R) mutable {
td::actor::send_closure(SelfId, &StorageManager::loaded_torrent_from_db, hash, std::move(R));
@ -162,9 +186,9 @@ td::Status StorageManager::add_torrent_impl(Torrent torrent, bool start_download
client_mode_, overlays_, adnl_, rldp_);
auto context = PeerManager::create_callback(entry.peer_manager.get());
LOG(INFO) << "Added torrent " << hash.to_hex() << " , root_dir = " << torrent.get_root_dir();
entry.actor =
td::actor::create_actor<NodeActor>("Node", 1, std::move(torrent), create_callback(hash, entry.closing_state),
std::move(context), db_, start_download, allow_upload);
entry.actor = td::actor::create_actor<NodeActor>(
"Node", 1, std::move(torrent), create_callback(hash, entry.closing_state), std::move(context), db_,
SpeedLimiters{download_speed_limiter_.get(), upload_speed_limiter_.get()}, start_download, allow_upload);
return td::Status::OK();
}
@ -210,6 +234,18 @@ void StorageManager::get_all_torrents(td::Promise<std::vector<td::Bits256>> prom
promise.set_result(std::move(result));
}
void StorageManager::db_store_config() {
auto config = create_tl_object<ton_api::storage_db_config>();
config->download_speed_limit_ = download_speed_limit_;
config->upload_speed_limit_ = upload_speed_limit_;
db_->set(create_hash_tl_object<ton_api::storage_db_key_config>(), serialize_tl_object(config, true),
[](td::Result<td::Unit> R) {
if (R.is_error()) {
LOG(ERROR) << "Failed to save config to db: " << R.move_as_error();
}
});
}
void StorageManager::db_store_torrent_list() {
std::vector<td::Bits256> torrents;
for (const auto& p : torrents_) {
@ -259,19 +295,55 @@ void StorageManager::load_from(td::Bits256 hash, td::optional<TorrentMeta> meta,
std::move(promise));
}
static bool try_rm_empty_dir(const std::string& path) {
auto stat = td::stat(path);
if (stat.is_error() || !stat.ok().is_dir_) {
return true;
}
size_t cnt = 0;
td::WalkPath::run(path, [&](td::CSlice name, td::WalkPath::Type type) {
if (type != td::WalkPath::Type::ExitDir) {
++cnt;
}
if (cnt < 2) {
return td::WalkPath::Action::Continue;
} else {
return td::WalkPath::Action::Abort;
}
}).ignore();
if (cnt == 1) {
td::rmdir(path).ignore();
return true;
}
return false;
}
void StorageManager::on_torrent_closed(Torrent torrent, std::shared_ptr<TorrentEntry::ClosingState> closing_state) {
if (!closing_state->removing) {
return;
}
if (closing_state->remove_files && torrent.inited_header()) {
// Ignore all errors: files may just not exist
size_t files_count = torrent.get_files_count().unwrap();
for (size_t i = 0; i < files_count; ++i) {
std::string path = torrent.get_file_path(i);
td::unlink(path).ignore();
// TODO: Check errors, remove empty directories
std::string name = torrent.get_file_name(i).str();
for (int j = (int)name.size() - 1; j >= 0; --j) {
if (name[j] == '/') {
name.resize(j + 1);
if (!try_rm_empty_dir(torrent.get_root_dir() + '/' + torrent.get_header().dir_name + '/' + name)) {
break;
}
}
}
if (!torrent.get_header().dir_name.empty()) {
try_rm_empty_dir(torrent.get_root_dir() + '/' + torrent.get_header().dir_name);
}
}
}
td::rmrf(db_root_ + "/torrent-files/" + torrent.get_hash().to_hex()).ignore();
std::string path = db_root_ + "/torrent-files/" + torrent.get_hash().to_hex();
td::rmrf(path).ignore();
NodeActor::cleanup_db(db_, torrent.get_hash(),
[promise = std::move(closing_state->promise)](td::Result<td::Unit> R) mutable {
if (R.is_error()) {
@ -292,4 +364,28 @@ void StorageManager::get_peers_info(td::Bits256 hash,
td::actor::send_closure(entry->actor, &NodeActor::get_peers_info, std::move(promise));
}
void StorageManager::get_speed_limits(td::Promise<std::pair<double, double>> promise) {
promise.set_result(std::make_pair(download_speed_limit_, upload_speed_limit_));
}
void StorageManager::set_download_speed_limit(double max_speed) {
if (max_speed < 0.0) {
max_speed = -1.0;
}
LOG(INFO) << "Set download speed limit to " << max_speed;
download_speed_limit_ = max_speed;
td::actor::send_closure(download_speed_limiter_, &SpeedLimiter::set_max_speed, max_speed);
db_store_config();
}
void StorageManager::set_upload_speed_limit(double max_speed) {
if (max_speed < 0.0) {
max_speed = -1.0;
}
LOG(INFO) << "Set upload speed limit to " << max_speed;
upload_speed_limit_ = max_speed;
td::actor::send_closure(upload_speed_limiter_, &SpeedLimiter::set_max_speed, max_speed);
db_store_config();
}
} // namespace ton