add new (non-deprecated) access to dht stats, asynchronously via an alert

This commit is contained in:
Arvid Norberg 2015-01-17 17:02:58 +00:00
parent b9b657c3d4
commit 58d93e5aa1
15 changed files with 190 additions and 69 deletions

View File

@ -180,6 +180,11 @@ bool print_disk_stats = false;
// without having received a response (successful or failure) // without having received a response (successful or failure)
int num_outstanding_resume_data = 0; int num_outstanding_resume_data = 0;
#ifndef TORRENT_DISABLE_DHT
std::vector<libtorrent::dht_lookup> dht_active_requests;
std::vector<libtorrent::dht_routing_bucket> dht_routing_table;
#endif
torrent_view view; torrent_view view;
session_view ses_view; session_view ses_view;
@ -905,6 +910,14 @@ bool handle_alert(libtorrent::session& ses, libtorrent::alert* a
ses_view.update_counters(s->values, s->timestamp); ses_view.update_counters(s->values, s->timestamp);
return true; return true;
} }
#ifndef TORRENT_DISABLE_DHT
if (dht_stats_alert* p = alert_cast<dht_stats_alert>(a))
{
dht_active_requests.swap(p->active_requests);
dht_routing_table.swap(p->dht_routing_table);
}
#endif
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
if (torrent_need_cert_alert* p = alert_cast<torrent_need_cert_alert>(a)) if (torrent_need_cert_alert* p = alert_cast<torrent_need_cert_alert>(a))
@ -953,6 +966,7 @@ bool handle_alert(libtorrent::session& ses, libtorrent::alert* a
} }
#endif #endif
if (metadata_received_alert* p = alert_cast<metadata_received_alert>(a)) if (metadata_received_alert* p = alert_cast<metadata_received_alert>(a))
{ {
// if we have a monitor dir, save the .torrent file we just received in it // if we have a monitor dir, save the .torrent file we just received in it
@ -1618,6 +1632,7 @@ int main(int argc, char* argv[])
++tick; ++tick;
ses.post_torrent_updates(); ses.post_torrent_updates();
ses.post_session_stats(); ses.post_session_stats();
ses.post_dht_stats();
int terminal_width = 80; int terminal_width = 80;
int terminal_height = 50; int terminal_height = 50;
@ -1951,20 +1966,20 @@ int main(int argc, char* argv[])
cache_status cs; cache_status cs;
ses.get_cache_info(&cs, h, cache_flags); ses.get_cache_info(&cs, h, cache_flags);
// TODO: 3 introce some reasonable way of getting DHT stats
/*
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT
if (show_dht_status) if (show_dht_status)
{ {
// TODO: 3 expose these counters as performance counters
/*
snprintf(str, sizeof(str), "DHT nodes: %d DHT cached nodes: %d " snprintf(str, sizeof(str), "DHT nodes: %d DHT cached nodes: %d "
"total DHT size: %" PRId64 " total observers: %d\n" "total DHT size: %" PRId64 " total observers: %d\n"
, sess_stat.dht_nodes, sess_stat.dht_node_cache, sess_stat.dht_global_nodes , sess_stat.dht_nodes, sess_stat.dht_node_cache, sess_stat.dht_global_nodes
, sess_stat.dht_total_allocations); , sess_stat.dht_total_allocations);
out += str; out += str;
*/
int bucket = 0; int bucket = 0;
for (std::vector<dht_routing_bucket>::iterator i = sess_stat.dht_routing_table.begin() for (std::vector<dht_routing_bucket>::iterator i = dht_routing_table.begin()
, end(sess_stat.dht_routing_table.end()); i != end; ++i, ++bucket) , end(dht_routing_table.end()); i != end; ++i, ++bucket)
{ {
char const* progress_bar = char const* progress_bar =
"################################" "################################"
@ -1980,8 +1995,8 @@ int main(int argc, char* argv[])
out += str; out += str;
} }
for (std::vector<dht_lookup>::iterator i = sess_stat.active_requests.begin() for (std::vector<dht_lookup>::iterator i = dht_active_requests.begin()
, end(sess_stat.active_requests.end()); i != end; ++i) , end(dht_active_requests.end()); i != end; ++i)
{ {
snprintf(str, sizeof(str) snprintf(str, sizeof(str)
, " %10s [limit: %2d] " , " %10s [limit: %2d] "
@ -2003,7 +2018,6 @@ int main(int argc, char* argv[])
} }
} }
#endif #endif
*/
if (h.is_valid()) if (h.is_valid())
{ {
torrent_status const& s = view.get_active_torrent(); torrent_status const& s = view.get_active_torrent();

View File

@ -2266,9 +2266,88 @@ namespace libtorrent
error_code error; error_code error;
}; };
// holds statistics about a current dht_lookup operation.
// a DHT lookup is the travesal of nodes, looking up a
// set of target nodes in the DHT for retrieving and possibly
// storing information in the DHT
struct TORRENT_EXPORT dht_lookup
{
// string literal indicating which kind of lookup this is
char const* type;
// the number of outstanding request to individual nodes
// this lookup has right now
int outstanding_requests;
// the total number of requests that have timed out so far
// for this lookup
int timeouts;
// the total number of responses we have received for this
// lookup so far for this lookup
int responses;
// the branch factor for this lookup. This is the number of
// nodes we keep outstanding requests to in parallel by default.
// when nodes time out we may increase this.
int branch_factor;
// the number of nodes left that could be queries for this
// lookup. Many of these are likely to be part of the trail
// while performing the lookup and would never end up actually
// being queried.
int nodes_left;
// the number of seconds ago the
// last message was sent that's still
// outstanding
int last_sent;
// the number of outstanding requests
// that have exceeded the short timeout
// and are considered timed out in the
// sense that they increased the branch
// factor
int first_timeout;
};
// struct to hold information about a single DHT routing table bucket
struct TORRENT_EXPORT dht_routing_bucket
{
// the total number of nodes and replacement nodes
// in the routing table
int num_nodes;
int num_replacements;
// number of seconds since last activity
int last_active;
};
// contains current DHT state. Posted in response to session::post_dht_stats().
struct TORRENT_EXPORT dht_stats_alert : alert
{
// internal
dht_stats_alert()
: alert()
{}
TORRENT_DEFINE_ALERT(dht_stats_alert, 83);
const static int static_category = alert::stats_notification;
virtual std::string message() const;
// a vector of the currently running DHT lookups.
std::vector<dht_lookup> active_requests;
// contains information about every bucket in the DHT routing
// table.
std::vector<dht_routing_bucket> dht_routing_table;
};
#undef TORRENT_DEFINE_ALERT #undef TORRENT_DEFINE_ALERT
enum { num_alert_types = 83 }; enum { num_alert_types = 84 };
} }

View File

@ -417,6 +417,7 @@ namespace libtorrent
, boost::uint32_t flags) const; , boost::uint32_t flags) const;
void post_torrent_updates(); void post_torrent_updates();
void post_session_stats(); void post_session_stats();
void post_dht_stats();
std::vector<torrent_handle> get_torrents() const; std::vector<torrent_handle> get_torrents() const;

View File

@ -73,6 +73,7 @@ namespace libtorrent { namespace dht
struct dht_tracker; struct dht_tracker;
// TODO: 3 remove these
TORRENT_EXTRA_EXPORT void intrusive_ptr_add_ref(dht_tracker const*); TORRENT_EXTRA_EXPORT void intrusive_ptr_add_ref(dht_tracker const*);
TORRENT_EXTRA_EXPORT void intrusive_ptr_release(dht_tracker const*); TORRENT_EXTRA_EXPORT void intrusive_ptr_release(dht_tracker const*);
@ -117,6 +118,8 @@ namespace libtorrent { namespace dht
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
void dht_status(session_status& s); void dht_status(session_status& s);
#endif #endif
void dht_status(std::vector<dht_routing_bucket>& table
, std::vector<dht_lookup>& requests);
void network_stats(int& sent, int& received); void network_stats(int& sent, int& received);
@ -163,6 +166,7 @@ namespace libtorrent { namespace dht
udp::resolver m_host_resolver; udp::resolver m_host_resolver;
// sent and received bytes since queried last time // sent and received bytes since queried last time
// TODO: 3 these members are probably unnecessary
int m_sent_bytes; int m_sent_bytes;
int m_received_bytes; int m_received_bytes;

View File

@ -61,6 +61,7 @@ namespace libtorrent {
struct alert_dispatcher; struct alert_dispatcher;
class alert; class alert;
struct counters; struct counters;
struct dht_routing_bucket;
} }
namespace libtorrent { namespace dht namespace libtorrent { namespace dht
@ -275,6 +276,9 @@ public:
m_running_requests.erase(a); m_running_requests.erase(a);
} }
void status(std::vector<dht_routing_bucket>& table
, std::vector<dht_lookup>& requests);
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
void status(libtorrent::session_status& s); void status(libtorrent::session_status& s);
#endif #endif

View File

@ -51,12 +51,13 @@ POSSIBILITY OF SUCH DAMAGE.
#include <libtorrent/time.hpp> #include <libtorrent/time.hpp>
#include <boost/unordered_set.hpp> #include <boost/unordered_set.hpp>
#ifndef TORRENT_NO_DEPRECATE
namespace libtorrent namespace libtorrent
{ {
#ifndef TORRENT_NO_DEPRECATE
struct session_status; struct session_status;
}
#endif #endif
struct dht_routing_bucket;
}
namespace libtorrent { namespace dht namespace libtorrent { namespace dht
{ {
@ -96,6 +97,8 @@ public:
void status(session_status& s) const; void status(session_status& s) const;
#endif #endif
void status(std::vector<dht_routing_bucket>& s) const;
void node_failed(node_id const& id, udp::endpoint const& ep); void node_failed(node_id const& id, udp::endpoint const& ep);
// adds an endpoint that will never be added to // adds an endpoint that will never be added to

View File

@ -227,6 +227,9 @@ namespace libtorrent
dht_get_out, dht_get_out,
dht_put_in, dht_put_in,
dht_put_out, dht_put_out,
// TODO: 3 these counters are redundant with dht_bytes_in and dht_bytes_out
// remove them
sent_dht_bytes, sent_dht_bytes,
recv_dht_bytes, recv_dht_bytes,

View File

@ -365,6 +365,9 @@ namespace libtorrent
// For more information, see the session-statistics_ section. // For more information, see the session-statistics_ section.
void post_session_stats(); void post_session_stats();
// This will cause a dht_stats_alert to be posted.
void post_dht_stats();
// internal // internal
io_service& get_io_service(); io_service& get_io_service();

View File

@ -36,67 +36,14 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/config.hpp" #include "libtorrent/config.hpp"
#include <vector> #include <vector>
#ifndef TORRENT_NO_DEPRECATE
// for dht_lookup and dht_routing_bucket
#include "libtorrent/alert_types.hpp"
#endif
namespace libtorrent namespace libtorrent
{ {
// holds statistics about a current dht_lookup operation.
// a DHT lookup is the travesal of nodes, looking up a
// set of target nodes in the DHT for retrieving and possibly
// storing information in the DHT
struct TORRENT_EXPORT dht_lookup
{
// string literal indicating which kind of lookup this is
char const* type;
// the number of outstanding request to individual nodes
// this lookup has right now
int outstanding_requests;
// the total number of requests that have timed out so far
// for this lookup
int timeouts;
// the total number of responses we have received for this
// lookup so far for this lookup
int responses;
// the branch factor for this lookup. This is the number of
// nodes we keep outstanding requests to in parallel by default.
// when nodes time out we may increase this.
int branch_factor;
// the number of nodes left that could be queries for this
// lookup. Many of these are likely to be part of the trail
// while performing the lookup and would never end up actually
// being queried.
int nodes_left;
// the number of seconds ago the
// last message was sent that's still
// outstanding
int last_sent;
// the number of outstanding requests
// that have exceeded the short timeout
// and are considered timed out in the
// sense that they increased the branch
// factor
int first_timeout;
};
// TODO: 3 add accessors to query the DHT state (post the result as an alert)
// holds dht routing table stats
struct TORRENT_EXPORT dht_routing_bucket
{
// the total number of nodes and replacement nodes
// in the routing table
int num_nodes;
int num_replacements;
// number of seconds since last activity
int last_active;
};
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
// holds counters and gauges for the uTP sockets // holds counters and gauges for the uTP sockets
// deprecated in 1.1 in favor of session_stats counters, which is a more // deprecated in 1.1 in favor of session_stats counters, which is a more

View File

@ -735,5 +735,14 @@ namespace libtorrent {
return "Local Service Discovery error: " + error.message(); return "Local Service Discovery error: " + error.message();
} }
std::string dht_stats_alert::message() const
{
char buf[2048];
snprintf(buf, sizeof(buf), "DHT stats: reqs: %d buckets: %d"
, int(active_requests.size())
, int(dht_routing_table.size()));
return buf;
}
} // namespace libtorrent } // namespace libtorrent

View File

@ -266,6 +266,12 @@ namespace libtorrent { namespace dht
} }
#endif #endif
void dht_tracker::dht_status(std::vector<dht_routing_bucket>& table
, std::vector<dht_lookup>& requests)
{
m_dht.status(table, requests);
}
void dht_tracker::network_stats(int& sent, int& received) void dht_tracker::network_stats(int& sent, int& received)
{ {
sent = m_sent_bytes; sent = m_sent_bytes;

View File

@ -565,7 +565,24 @@ time_duration node_impl::connection_timeout()
return d; return d;
} }
void node_impl::status(std::vector<dht_routing_bucket>& table
, std::vector<dht_lookup>& requests)
{
mutex_t::scoped_lock l(m_mutex);
m_table.status(table);
for (std::set<traversal_algorithm*>::iterator i = m_running_requests.begin()
, end(m_running_requests.end()); i != end; ++i)
{
requests.push_back(dht_lookup());
dht_lookup& l = requests.back();
(*i)->status(l);
}
}
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
// TODO: 2 use the non deprecated function instead of this one
void node_impl::status(session_status& s) void node_impl::status(session_status& s)
{ {
mutex_t::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);

View File

@ -43,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/session_status.hpp" #include "libtorrent/session_status.hpp"
#include "libtorrent/kademlia/node_id.hpp" #include "libtorrent/kademlia/node_id.hpp"
#include "libtorrent/time.hpp" #include "libtorrent/time.hpp"
#include "libtorrent/alert_types.hpp" // for dht_routing_bucket
#include "libtorrent/invariant_check.hpp" #include "libtorrent/invariant_check.hpp"
@ -93,7 +94,20 @@ int routing_table::bucket_limit(int bucket) const
return m_bucket_size; return m_bucket_size;
} }
void routing_table::status(std::vector<dht_routing_bucket>& s) const
{
for (table_t::const_iterator i = m_buckets.begin()
, end(m_buckets.end()); i != end; ++i)
{
dht_routing_bucket b;
b.num_nodes = i->live_nodes.size();
b.num_replacements = i->replacements.size();
s.push_back(b);
}
}
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
// TODO: 2 use the non deprecated function instead of this one
void routing_table::status(session_status& s) const void routing_table::status(session_status& s) const
{ {
int ignore; int ignore;

View File

@ -587,6 +587,11 @@ namespace libtorrent
TORRENT_ASYNC_CALL(post_session_stats); TORRENT_ASYNC_CALL(post_session_stats);
} }
void session::post_dht_stats()
{
TORRENT_ASYNC_CALL(post_dht_stats);
}
std::vector<torrent_handle> session::get_torrents() const std::vector<torrent_handle> session::get_torrents() const
{ {
return TORRENT_SYNC_CALL_RET(std::vector<torrent_handle>, get_torrents); return TORRENT_SYNC_CALL_RET(std::vector<torrent_handle>, get_torrents);

View File

@ -4395,6 +4395,18 @@ retry:
m_alerts.post_alert_ptr(alert.release()); m_alerts.post_alert_ptr(alert.release());
} }
void session_impl::post_dht_stats()
{
std::auto_ptr<dht_stats_alert> alert(new dht_stats_alert());
#ifndef TORRENT_DISABLE_DHT
if (m_dht)
m_dht->dht_status(alert->dht_routing_table, alert->active_requests);
#endif
m_alerts.post_alert_ptr(alert.release());
}
std::vector<torrent_handle> session_impl::get_torrents() const std::vector<torrent_handle> session_impl::get_torrents() const
{ {
std::vector<torrent_handle> ret; std::vector<torrent_handle> ret;