added block_uploaded_alert to allow client to track upload activity

This commit is contained in:
toinetoine 2017-07-02 17:41:38 +00:00 committed by Arvid Norberg
parent d32341b986
commit b1c3e12cd0
6 changed files with 94 additions and 2 deletions

View File

@ -1,3 +1,4 @@
* added alert for block being sent to the send buffer
* drop support for windows compilers without std::wstring * drop support for windows compilers without std::wstring
* implemented support for DHT infohash indexing, BEP51 * implemented support for DHT infohash indexing, BEP51
* removed deprecated support for file_base in file_storage * removed deprecated support for file_base in file_storage

View File

@ -2663,11 +2663,31 @@ namespace libtorrent {
aux::allocation_slot m_v6_nodes_idx; aux::allocation_slot m_v6_nodes_idx;
}; };
// This alert is posted when a block intended to be sent to a peer is placed in the
// send buffer. Note that if the connection is closed before the send buffer is sent,
// the alert may be posted without the bytes having been sent to the peer.
// It belongs to the ``progress_notification`` category.
struct TORRENT_EXPORT block_uploaded_alert final : peer_alert
{
// internal
block_uploaded_alert(aux::stack_allocator& alloc, torrent_handle h
, tcp::endpoint const& ep, peer_id const& peer_id, int block_num
, piece_index_t piece_num);
TORRENT_DEFINE_ALERT(block_uploaded_alert, 94)
static const int static_category = alert::progress_notification;
virtual std::string message() const override;
int const block_index;
piece_index_t const piece_index;
};
#undef TORRENT_DEFINE_ALERT_IMPL #undef TORRENT_DEFINE_ALERT_IMPL
#undef TORRENT_DEFINE_ALERT #undef TORRENT_DEFINE_ALERT
#undef TORRENT_DEFINE_ALERT_PRIO #undef TORRENT_DEFINE_ALERT_PRIO
enum { num_alert_types = 94 }; // this enum represents "max_alert_index" + 1 enum { num_alert_types = 95 }; // this enum represents "max_alert_index" + 1
} }
#endif #endif

View File

@ -537,6 +537,51 @@ TORRENT_TEST(torrent_completed_alert)
TEST_EQUAL(num_file_completed, 1); TEST_EQUAL(num_file_completed, 1);
} }
TORRENT_TEST(block_uploaded_alert)
{
// blocks[piece count][number of blocks per piece] (each block's element will
// be set to true when a block_uploaded_alert alert is received for that block)
std::vector<std::vector<bool>> blocks;
setup_swarm(2, swarm_test::upload
// add session
, [](lt::settings_pack& pack)
{
pack.set_int(lt::settings_pack::alert_mask,
alert::progress_notification | alert::status_notification);
}
// add torrent
, [](lt::add_torrent_params&) {}
// on alert
, [&](lt::alert const* a, lt::session&) {
if (auto at = lt::alert_cast<lt::add_torrent_alert>(a))
{
// init blocks vector, MUST happen before any block_uploaded_alert alerts
int blocks_per_piece = at->handle.torrent_file()->piece_length() / 0x4000;
blocks.resize(at->handle.torrent_file()->num_pieces(), std::vector<bool>(blocks_per_piece, false));
}
else if (auto at = lt::alert_cast<lt::block_uploaded_alert>(a))
{
TEST_EQUAL(blocks[at->piece_index][at->block_index], false);
blocks[at->piece_index][at->block_index] = true;
}
}
// terminate
, [](int, lt::session&) -> bool
{ return false; });
// ensure a block_uploaded_alert was received for each block in the torrent
TEST_CHECK(std::all_of(blocks.begin(), blocks.end(),
[](std::vector<bool> const& piece_row) {
return std::all_of(piece_row.begin(), piece_row.end(),
[](bool upload_alert_received) {
return upload_alert_received;
}
);
}
));
}
// template for testing running swarms with edge case settings // template for testing running swarms with edge case settings
template <typename SettingsFun> template <typename SettingsFun>
void test_settings(SettingsFun fun) void test_settings(SettingsFun fun)

View File

@ -2414,4 +2414,22 @@ namespace {
, m_v6_num_nodes, m_v6_nodes_idx); , m_v6_num_nodes, m_v6_nodes_idx);
} }
block_uploaded_alert::block_uploaded_alert(aux::stack_allocator& alloc, torrent_handle h
, tcp::endpoint const& ep, peer_id const& peer_id, int block_num
, piece_index_t piece_num)
: peer_alert(alloc, h, ep, peer_id)
, block_index(block_num)
, piece_index(piece_num)
{
TORRENT_ASSERT(block_index >= 0 && piece_index >= piece_index_t{0});
}
std::string block_uploaded_alert::message() const
{
char ret[200];
snprintf(ret, sizeof(ret), "%s block uploaded to a peer (piece: %u block: %u)"
, torrent_alert::message().c_str(), static_cast<int>(piece_index), block_index);
return ret;
}
} // namespace libtorrent } // namespace libtorrent

View File

@ -67,6 +67,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/aux_/alloca.hpp" #include "libtorrent/aux_/alloca.hpp"
#include "libtorrent/socket_type.hpp" #include "libtorrent/socket_type.hpp"
#include "libtorrent/performance_counters.hpp" // for counters #include "libtorrent/performance_counters.hpp" // for counters
#include "libtorrent/alert_manager.hpp" // for alert_manager
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS) #if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
#include "libtorrent/pe_crypto.hpp" #include "libtorrent/pe_crypto.hpp"
@ -2395,6 +2396,12 @@ namespace {
setup_send(); setup_send();
stats_counters().inc_stats_counter(counters::num_outgoing_piece); stats_counters().inc_stats_counter(counters::num_outgoing_piece);
if (t->alerts().should_post<block_uploaded_alert>())
{
t->alerts().emplace_alert<block_uploaded_alert>(t->get_handle(),
remote(), pid(), r.start / t->block_size() , r.piece);
}
} }
// -------------------------- // --------------------------

View File

@ -161,10 +161,11 @@ TORRENT_TEST(alerts_types)
TEST_ALERT_TYPE(dht_live_nodes_alert, 91, 0, alert::dht_notification); TEST_ALERT_TYPE(dht_live_nodes_alert, 91, 0, alert::dht_notification);
TEST_ALERT_TYPE(session_stats_header_alert, 92, 0, alert::stats_notification); TEST_ALERT_TYPE(session_stats_header_alert, 92, 0, alert::stats_notification);
TEST_ALERT_TYPE(dht_sample_infohashes_alert, 93, 0, alert::dht_operation_notification); TEST_ALERT_TYPE(dht_sample_infohashes_alert, 93, 0, alert::dht_operation_notification);
TEST_ALERT_TYPE(block_uploaded_alert, 94, 0, alert::progress_notification);
#undef TEST_ALERT_TYPE #undef TEST_ALERT_TYPE
TEST_EQUAL(num_alert_types, 94); TEST_EQUAL(num_alert_types, 95);
TEST_EQUAL(num_alert_types, count_alert_types); TEST_EQUAL(num_alert_types, count_alert_types);
} }