mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-16 07:02:30 +00:00
Run multiple session save requests in parallel.
This commit is contained in:
@@ -13,7 +13,6 @@
|
||||
|
||||
#include "control.h"
|
||||
#include "download.h"
|
||||
#include "download_store.h"
|
||||
#include "globals.h"
|
||||
#include "manager.h"
|
||||
#include "rpc/parse_commands.h"
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#include "control.h"
|
||||
#include "globals.h"
|
||||
#include "core/download.h"
|
||||
#include "core/download_store.h"
|
||||
#include "core/http_queue.h"
|
||||
#include "core/manager.h"
|
||||
#include "rpc/parse_commands.h"
|
||||
|
||||
+11
-15
@@ -22,10 +22,10 @@
|
||||
#include "view.h"
|
||||
#include "view_manager.h"
|
||||
|
||||
#include "dht_manager.h"
|
||||
#include "download.h"
|
||||
#include "download_list.h"
|
||||
#include "download_store.h"
|
||||
#include "core/dht_manager.h"
|
||||
#include "core/download.h"
|
||||
#include "core/download_list.h"
|
||||
#include "session/session_manager.h"
|
||||
#include "ui/root.h"
|
||||
|
||||
#define DL_TRIGGER_EVENT(download, event_name) \
|
||||
@@ -68,10 +68,8 @@ DownloadList::clear() {
|
||||
|
||||
void
|
||||
DownloadList::session_save() {
|
||||
unsigned int c = std::count_if(begin(), end(), [&](Download* d) { return control->core()->download_store()->save_resume(d); });
|
||||
|
||||
if (c != size())
|
||||
lt_log_print(torrent::LOG_ERROR, "Failed to save session torrents.");
|
||||
for (auto& download : *this)
|
||||
session_thread::manager()->save_resume_download(download);
|
||||
|
||||
control->dht_manager()->save_dht_cache();
|
||||
control->ui()->save_input_history();
|
||||
@@ -199,10 +197,10 @@ DownloadList::erase(iterator itr) {
|
||||
(*itr)->set_hash_failed(true);
|
||||
|
||||
close(*itr);
|
||||
|
||||
control->core()->download_store()->remove(*itr);
|
||||
session_thread::manager()->remove_download(*itr);
|
||||
|
||||
DL_TRIGGER_EVENT(*itr, "event.download.erased");
|
||||
|
||||
for (auto v : *control->view_manager())
|
||||
v->erase(*itr);
|
||||
|
||||
@@ -639,10 +637,8 @@ DownloadList::confirm_finished(Download* download) {
|
||||
// the download.
|
||||
//
|
||||
// Obsolete.
|
||||
if (!download->is_active() && rpc::call_command_value("session.on_completion") != 0) {
|
||||
// torrent::resume_save_progress(*download->download(), download->download()->bencode()->get_key("libtorrent_resume"));
|
||||
control->core()->download_store()->save_resume(download);
|
||||
}
|
||||
if (!download->is_active() && rpc::call_command_value("session.on_completion") != 0)
|
||||
session_thread::manager()->save_resume_download(download);
|
||||
|
||||
// Send the completed request before resuming so we don't reset the
|
||||
// up/downloaded baseline.
|
||||
@@ -655,7 +651,7 @@ DownloadList::confirm_finished(Download* download) {
|
||||
|
||||
if (find(infohash) == end())
|
||||
return;
|
||||
|
||||
|
||||
// if (download->resume_flags() != ~uint32_t())
|
||||
// throw torrent::internal_error("DownloadList::confirm_finished(...) download->resume_flags() != ~uint32_t().");
|
||||
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
// DownloadStore handles the saving and listing of session torrents.
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sstream>
|
||||
#include <unistd.h>
|
||||
#include <rak/error_number.h>
|
||||
#include <rak/path.h>
|
||||
#include <rak/string_manip.h>
|
||||
#include <torrent/utils/resume.h>
|
||||
#include <torrent/object.h>
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/torrent.h>
|
||||
#include <torrent/rate.h>
|
||||
#include <torrent/object_stream.h>
|
||||
|
||||
#include "download.h"
|
||||
#include "download_store.h"
|
||||
#include "rpc/parse_commands.h"
|
||||
#include "session/session_manager.h"
|
||||
#include "utils/directory.h"
|
||||
|
||||
namespace core {
|
||||
|
||||
bool
|
||||
DownloadStore::save(Download* d, int flags) {
|
||||
if (!session_thread::manager()->is_used())
|
||||
return true;
|
||||
|
||||
torrent::Object* resume_base = &d->download()->bencode()->get_key("libtorrent_resume");
|
||||
torrent::Object* rtorrent_base = &d->download()->bencode()->get_key("rtorrent");
|
||||
|
||||
// Move this somewhere else?
|
||||
rtorrent_base->insert_key("chunks_done", d->download()->file_list()->completed_chunks());
|
||||
rtorrent_base->insert_key("chunks_wanted", d->download()->data()->wanted_chunks());
|
||||
rtorrent_base->insert_key("total_uploaded", d->info()->up_rate()->total());
|
||||
rtorrent_base->insert_key("total_downloaded", d->info()->down_rate()->total());
|
||||
|
||||
// Don't save for completed torrents when we've cleared the uncertain_pieces.
|
||||
torrent::resume_save_progress(*d->download(), *resume_base);
|
||||
torrent::resume_save_uncertain_pieces(*d->download(), *resume_base);
|
||||
|
||||
torrent::resume_save_addresses(*d->download(), *resume_base);
|
||||
torrent::resume_save_file_priorities(*d->download(), *resume_base);
|
||||
torrent::resume_save_tracker_settings(*d->download(), *resume_base);
|
||||
|
||||
// Temp fixing of all flags, move to a better place:
|
||||
resume_base->set_flags(torrent::Object::flag_session_data);
|
||||
rtorrent_base->set_flags(torrent::Object::flag_session_data);
|
||||
|
||||
auto download_stream = std::unique_ptr<std::stringstream>();
|
||||
auto resume_stream = std::make_unique<std::stringstream>();
|
||||
auto rtorrent_stream = std::make_unique<std::stringstream>();
|
||||
|
||||
if (!(flags & flag_skip_static)) {
|
||||
download_stream = std::make_unique<std::stringstream>();
|
||||
torrent::object_write_bencode(&*download_stream, d->bencode(), torrent::Object::flag_session_data);
|
||||
|
||||
if (!download_stream->good())
|
||||
return false;
|
||||
}
|
||||
|
||||
torrent::object_write_bencode(&*resume_stream, resume_base, 0);
|
||||
|
||||
// TODO: Add logging.
|
||||
if (!resume_stream->good())
|
||||
return false;
|
||||
|
||||
torrent::object_write_bencode(&*rtorrent_stream, rtorrent_base, 0);
|
||||
|
||||
if (!rtorrent_stream->good())
|
||||
return false;
|
||||
|
||||
auto base_filename = create_filename(d);
|
||||
|
||||
session_thread::manager()->save_download(d, base_filename, std::move(download_stream), std::move(resume_stream), std::move(rtorrent_stream));
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DownloadStore::remove(Download* d) {
|
||||
session_thread::manager()->remove_download(d, create_filename(d));
|
||||
}
|
||||
|
||||
// This also needs to check that it isn't a directory.
|
||||
bool
|
||||
not_correct_format(const utils::directory_entry& entry) {
|
||||
return !DownloadStore::is_correct_format(entry.s_name);
|
||||
}
|
||||
|
||||
utils::Directory
|
||||
DownloadStore::get_formated_entries() {
|
||||
if (!session_thread::manager()->is_used())
|
||||
return utils::Directory();
|
||||
|
||||
utils::Directory d(session_thread::manager()->path());
|
||||
|
||||
if (!d.update(utils::Directory::update_hide_dot))
|
||||
throw torrent::storage_error("core::DownloadStore::update() could not open session directory: " + session_thread::manager()->path());
|
||||
|
||||
d.erase(std::remove_if(d.begin(), d.end(), [&](const utils::directory_entry& entry) { return not_correct_format(entry); }), d.end());
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
bool
|
||||
DownloadStore::is_correct_format(const std::string& f) {
|
||||
if (f.size() != 48 || f.substr(40) != ".torrent")
|
||||
return false;
|
||||
|
||||
for (std::string::const_iterator itr = f.begin(); itr != f.end() - 8; ++itr)
|
||||
if (!(*itr >= '0' && *itr <= '9') &&
|
||||
!(*itr >= 'A' && *itr <= 'F'))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string
|
||||
DownloadStore::create_filename(Download* d) {
|
||||
return session_thread::manager()->path() + rak::transform_hex(d->info()->hash().begin(), d->info()->hash().end()) + ".torrent";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#ifndef RTORRENT_CORE_DOWNLOAD_STORE_H
|
||||
#define RTORRENT_CORE_DOWNLOAD_STORE_H
|
||||
|
||||
#include <string>
|
||||
#include <torrent/common.h>
|
||||
|
||||
namespace utils {
|
||||
class Directory;
|
||||
}
|
||||
|
||||
namespace core {
|
||||
|
||||
class Download;
|
||||
|
||||
class DownloadStore {
|
||||
public:
|
||||
static const int flag_skip_static = 0x1;
|
||||
|
||||
bool save(Download* d, int flags);
|
||||
bool save_full(Download* d) { return save(d, 0); }
|
||||
bool save_resume(Download* d) { return save(d, flag_skip_static); }
|
||||
void remove(Download* d);
|
||||
|
||||
// Currently shows all entries in the correct format.
|
||||
utils::Directory get_formated_entries();
|
||||
|
||||
static bool is_correct_format(const std::string& f);
|
||||
|
||||
private:
|
||||
std::string create_filename(Download* d);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+2
-4
@@ -32,7 +32,6 @@
|
||||
#include "control.h"
|
||||
#include "core/download.h"
|
||||
#include "core/download_factory.h"
|
||||
#include "core/download_store.h"
|
||||
#include "core/http_queue.h"
|
||||
#include "core/manager.h"
|
||||
#include "core/view.h"
|
||||
@@ -50,11 +49,10 @@ Manager::push_log(const char* msg) {
|
||||
m_log_complete->lock_and_push_log(msg, strlen(msg), 0);
|
||||
}
|
||||
|
||||
Manager::Manager() :
|
||||
m_log_important(torrent::log_open_log_buffer("important")),
|
||||
Manager::Manager()
|
||||
: m_log_important(torrent::log_open_log_buffer("important")),
|
||||
m_log_complete(torrent::log_open_log_buffer("complete")) {
|
||||
|
||||
m_download_store = std::make_unique<DownloadStore>();
|
||||
m_download_list = std::make_unique<DownloadList>();
|
||||
m_file_status_cache = std::make_unique<FileStatusCache>();
|
||||
m_http_queue = std::make_unique<HttpQueue>();
|
||||
|
||||
@@ -21,7 +21,6 @@ class FileStatusCache;
|
||||
|
||||
namespace core {
|
||||
|
||||
class DownloadStore;
|
||||
class HttpQueue;
|
||||
|
||||
typedef std::map<std::string, torrent::ThrottlePair> ThrottleMap;
|
||||
@@ -37,7 +36,6 @@ public:
|
||||
~Manager();
|
||||
|
||||
DownloadList* download_list() { return m_download_list.get(); }
|
||||
DownloadStore* download_store() { return m_download_store.get(); }
|
||||
FileStatusCache* file_status_cache() { return m_file_status_cache.get(); }
|
||||
|
||||
HttpQueue* http_queue() { return m_http_queue.get(); }
|
||||
@@ -95,7 +93,6 @@ private:
|
||||
void receive_hashing_changed();
|
||||
|
||||
std::unique_ptr<DownloadList> m_download_list;
|
||||
std::unique_ptr<DownloadStore> m_download_store;
|
||||
std::unique_ptr<FileStatusCache> m_file_status_cache;
|
||||
std::unique_ptr<HttpQueue> m_http_queue;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user