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)
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;
session_view ses_view;
@ -906,6 +911,14 @@ bool handle_alert(libtorrent::session& ses, libtorrent::alert* a
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
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
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
@ -1618,6 +1632,7 @@ int main(int argc, char* argv[])
++tick;
ses.post_torrent_updates();
ses.post_session_stats();
ses.post_dht_stats();
int terminal_width = 80;
int terminal_height = 50;
@ -1951,20 +1966,20 @@ int main(int argc, char* argv[])
cache_status cs;
ses.get_cache_info(&cs, h, cache_flags);
// TODO: 3 introce some reasonable way of getting DHT stats
/*
#ifndef TORRENT_DISABLE_DHT
if (show_dht_status)
{
// TODO: 3 expose these counters as performance counters
/*
snprintf(str, sizeof(str), "DHT nodes: %d DHT cached nodes: %d "
"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_total_allocations);
out += str;
*/
int bucket = 0;
for (std::vector<dht_routing_bucket>::iterator i = sess_stat.dht_routing_table.begin()
, end(sess_stat.dht_routing_table.end()); i != end; ++i, ++bucket)
for (std::vector<dht_routing_bucket>::iterator i = dht_routing_table.begin()
, end(dht_routing_table.end()); i != end; ++i, ++bucket)
{
char const* progress_bar =
"################################"
@ -1980,8 +1995,8 @@ int main(int argc, char* argv[])
out += str;
}
for (std::vector<dht_lookup>::iterator i = sess_stat.active_requests.begin()
, end(sess_stat.active_requests.end()); i != end; ++i)
for (std::vector<dht_lookup>::iterator i = dht_active_requests.begin()
, end(dht_active_requests.end()); i != end; ++i)
{
snprintf(str, sizeof(str)
, " %10s [limit: %2d] "
@ -2003,7 +2018,6 @@ int main(int argc, char* argv[])
}
}
#endif
*/
if (h.is_valid())
{
torrent_status const& s = view.get_active_torrent();

View File

@ -2266,9 +2266,88 @@ namespace libtorrent
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
enum { num_alert_types = 83 };
enum { num_alert_types = 84 };
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -36,67 +36,14 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/config.hpp"
#include <vector>
#ifndef TORRENT_NO_DEPRECATE
// for dht_lookup and dht_routing_bucket
#include "libtorrent/alert_types.hpp"
#endif
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
// holds counters and gauges for the uTP sockets
// 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();
}
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

View File

@ -266,6 +266,12 @@ namespace libtorrent { namespace dht
}
#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)
{
sent = m_sent_bytes;

View File

@ -565,7 +565,24 @@ time_duration node_impl::connection_timeout()
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
// TODO: 2 use the non deprecated function instead of this one
void node_impl::status(session_status& s)
{
mutex_t::scoped_lock l(m_mutex);

View File

@ -43,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/session_status.hpp"
#include "libtorrent/kademlia/node_id.hpp"
#include "libtorrent/time.hpp"
#include "libtorrent/alert_types.hpp" // for dht_routing_bucket
#include "libtorrent/invariant_check.hpp"
@ -93,7 +94,20 @@ int routing_table::bucket_limit(int bucket) const
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
// TODO: 2 use the non deprecated function instead of this one
void routing_table::status(session_status& s) const
{
int ignore;

View File

@ -587,6 +587,11 @@ namespace libtorrent
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
{
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());
}
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> ret;