From ffe56bdb2657d64eb43d663895a98a777f9cee61 Mon Sep 17 00:00:00 2001 From: arvidn Date: Fri, 15 Feb 2019 13:42:15 +0100 Subject: [PATCH 1/2] update documentation regarding recommendations of post_torrent_updates() --- docs/tuning.rst | 39 +++++++++------------------ include/libtorrent/session_handle.hpp | 12 +++++++++ 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/docs/tuning.rst b/docs/tuning.rst index d1998198a..484ad4a38 100644 --- a/docs/tuning.rst +++ b/docs/tuning.rst @@ -321,34 +321,21 @@ scalability In order to make more efficient use of the libtorrent interface when running a large number of torrents simultaneously, one can use the ``session::get_torrent_status()`` call -together with ``session::refresh_torrent_status()``. Keep in mind that every call into +together with ``session::post_torrent_updates()``. Keep in mind that every call into libtorrent that return some value have to block your thread while posting a message to -the main network thread and then wait for a response (calls that don't return any data -will simply post the message and then immediately return). The time this takes might -become significant once you reach a few hundred torrents (depending on how many calls -you make to each torrent and how often). ``get_torrent_status`` lets you query the -status of all torrents in a single call. This will actually loop through all torrents -and run a provided predicate function to determine whether or not to include it in -the returned vector. If you have a lot of torrents, you might want to update the status -of only certain torrents. For instance, you might only be interested in torrents that -are being downloaded. +the main network thread and then wait for a response. Calls that don't return any data +will simply post the message and then immediately return, performing the work +asynchonuously. The time this takes might become significant once you reach a +few hundred torrents, depending on how many calls you make to each torrent and how often. +``session::get_torrent_status()`` lets you query the status of all torrents in a single call. +This will actually loop through all torrents and run a provided predicate function to +determine whether or not to include it in the returned vector. -The intended use of these functions is to start off by calling ``get_torrent_status()`` -to get a list of all torrents that match your criteria. Then call ``refresh_torrent_status()`` -on that list. This will only refresh the status for the torrents in your list, and thus -ignore all other torrents you might be running. This may save a significant amount of -time, especially if the number of torrents you're interested in is small. In order to -keep your list of interested torrents up to date, you can either call ``get_torrent_status()`` -from time to time, to include torrents you might have become interested in since the last -time. In order to stop refreshing a certain torrent, simply remove it from the list. - -A more efficient way however, would be to subscribe to status alert notifications, and -update your list based on these alerts. There are alerts for when torrents are added, removed, -paused, resumed, completed etc. Doing this ensures that you only query status for the -minimal set of torrents you are actually interested in. - -To get an update with only the torrents that have changed since last time, call -``session::post_torrent_updates()``. +To use ``session::post_torrent_updates()`` torrents need to have the ``flag_update_subscribe`` +flag set. When post_torrent_updates() is called, a ``state_update_alert`` alert +is posted, with all the torrents that have updated since the last time this +function was called. The client have to keep its own state of all torrents, and +update it based on this alert. benchmarking ============ diff --git a/include/libtorrent/session_handle.hpp b/include/libtorrent/session_handle.hpp index 8bd2f2f03..b127a0e7d 100644 --- a/include/libtorrent/session_handle.hpp +++ b/include/libtorrent/session_handle.hpp @@ -151,6 +151,18 @@ namespace libtorrent // // Any torrent_status object whose ``handle`` member is not referring to // a valid torrent are ignored. + // + // The intended use of these functions is to start off by calling + // ``get_torrent_status()`` to get a list of all torrents that match your + // criteria. Then call ``refresh_torrent_status()`` on that list. This + // will only refresh the status for the torrents in your list, and thus + // ignore all other torrents you might be running. This may save a + // significant amount of time, especially if the number of torrents you're + // interested in is small. In order to keep your list of interested + // torrents up to date, you can either call ``get_torrent_status()`` from + // time to time, to include torrents you might have become interested in + // since the last time. In order to stop refreshing a certain torrent, + // simply remove it from the list. void get_torrent_status(std::vector* ret , boost::function const& pred , boost::uint32_t flags = 0) const; From c9d9371065295878b80eb776cce762e563a65f3f Mon Sep 17 00:00:00 2001 From: arvidn Date: Fri, 15 Feb 2019 13:55:21 +0100 Subject: [PATCH 2/2] add missing get_torrent_status() and refresh_torrent_status() to python binding --- bindings/python/src/session.cpp | 39 +++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/bindings/python/src/session.cpp b/bindings/python/src/session.cpp index 1c2969ec5..283b53155 100644 --- a/bindings/python/src/session.cpp +++ b/bindings/python/src/session.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #ifndef TORRENT_NO_DEPRECATE #include @@ -469,17 +470,49 @@ namespace list get_torrents(lt::session& s) { - list ret; std::vector torrents; { allow_threading_guard guard; torrents = s.get_torrents(); } + list ret; for (std::vector::iterator i = torrents.begin(); i != torrents.end(); ++i) - { ret.append(*i); + return ret; + } + + bool wrap_pred(object pred, torrent_status const& st) + { + return pred(st); + } + + list get_torrent_status(lt::session& s, object pred, int const flags) + { + std::vector torrents; + s.get_torrent_status(&torrents, boost::bind(&wrap_pred, pred, _1), flags); + + list ret; + for (std::vector::iterator i = torrents.begin(); i != torrents.end(); ++i) + ret.append(*i); + return ret; + } + + list refresh_torrent_status(lt::session& s, list in_torrents, int const flags) + { + std::vector torrents; + int const n = boost::python::len(in_torrents); + for (int i = 0; i < n; ++i) + torrents.push_back(extract(in_torrents[i])); + + { + allow_threading_guard guard; + s.refresh_torrent_status(&torrents, flags); } + + list ret; + for (std::vector::iterator i = torrents.begin(); i != torrents.end(); ++i) + ret.append(*i); return ret; } @@ -972,6 +1005,8 @@ void bind_session() .def("get_ip_filter", allow_threads(<::session::get_ip_filter)) .def("find_torrent", allow_threads(<::session::find_torrent)) .def("get_torrents", &get_torrents) + .def("get_torrent_status", &get_torrent_status, (arg("session"), arg("pred"), arg("flags") = 0)) + .def("refresh_torrent_status", &refresh_torrent_status, (arg("session"), arg("torrents"), arg("flags") = 0)) .def("pause", allow_threads(<::session::pause)) .def("resume", allow_threads(<::session::resume)) .def("is_paused", allow_threads(<::session::is_paused))