added test to measure peak download rate and introduced performance warning alert when disk buffer limit and request limit are reached

This commit is contained in:
Arvid Norberg 2008-08-19 15:04:14 +00:00
parent a134908bac
commit 37389e4fe4
8 changed files with 219 additions and 56 deletions

View File

@ -167,65 +167,66 @@
<li><a class="reference" href="#peer-error-alert" id="id144" name="id144">peer_error_alert</a></li>
<li><a class="reference" href="#invalid-request-alert" id="id145" name="id145">invalid_request_alert</a></li>
<li><a class="reference" href="#torrent-finished-alert" id="id146" name="id146">torrent_finished_alert</a></li>
<li><a class="reference" href="#metadata-failed-alert" id="id147" name="id147">metadata_failed_alert</a></li>
<li><a class="reference" href="#metadata-received-alert" id="id148" name="id148">metadata_received_alert</a></li>
<li><a class="reference" href="#fastresume-rejected-alert" id="id149" name="id149">fastresume_rejected_alert</a></li>
<li><a class="reference" href="#peer-blocked-alert" id="id150" name="id150">peer_blocked_alert</a></li>
<li><a class="reference" href="#storage-moved-alert" id="id151" name="id151">storage_moved_alert</a></li>
<li><a class="reference" href="#torrent-paused-alert" id="id152" name="id152">torrent_paused_alert</a></li>
<li><a class="reference" href="#torrent-resumed-alert" id="id153" name="id153">torrent_resumed_alert</a></li>
<li><a class="reference" href="#save-resume-data-alert" id="id154" name="id154">save_resume_data_alert</a></li>
<li><a class="reference" href="#save-resume-data-failed-alert" id="id155" name="id155">save_resume_data_failed_alert</a></li>
<li><a class="reference" href="#dispatcher" id="id156" name="id156">dispatcher</a></li>
<li><a class="reference" href="#performance-alert" id="id147" name="id147">performance_alert</a></li>
<li><a class="reference" href="#metadata-failed-alert" id="id148" name="id148">metadata_failed_alert</a></li>
<li><a class="reference" href="#metadata-received-alert" id="id149" name="id149">metadata_received_alert</a></li>
<li><a class="reference" href="#fastresume-rejected-alert" id="id150" name="id150">fastresume_rejected_alert</a></li>
<li><a class="reference" href="#peer-blocked-alert" id="id151" name="id151">peer_blocked_alert</a></li>
<li><a class="reference" href="#storage-moved-alert" id="id152" name="id152">storage_moved_alert</a></li>
<li><a class="reference" href="#torrent-paused-alert" id="id153" name="id153">torrent_paused_alert</a></li>
<li><a class="reference" href="#torrent-resumed-alert" id="id154" name="id154">torrent_resumed_alert</a></li>
<li><a class="reference" href="#save-resume-data-alert" id="id155" name="id155">save_resume_data_alert</a></li>
<li><a class="reference" href="#save-resume-data-failed-alert" id="id156" name="id156">save_resume_data_failed_alert</a></li>
<li><a class="reference" href="#dispatcher" id="id157" name="id157">dispatcher</a></li>
</ul>
</li>
<li><a class="reference" href="#exceptions" id="id157" name="id157">exceptions</a><ul>
<li><a class="reference" href="#invalid-handle" id="id158" name="id158">invalid_handle</a></li>
<li><a class="reference" href="#duplicate-torrent" id="id159" name="id159">duplicate_torrent</a></li>
<li><a class="reference" href="#invalid-encoding" id="id160" name="id160">invalid_encoding</a></li>
<li><a class="reference" href="#type-error" id="id161" name="id161">type_error</a></li>
<li><a class="reference" href="#invalid-torrent-file" id="id162" name="id162">invalid_torrent_file</a></li>
<li><a class="reference" href="#exceptions" id="id158" name="id158">exceptions</a><ul>
<li><a class="reference" href="#invalid-handle" id="id159" name="id159">invalid_handle</a></li>
<li><a class="reference" href="#duplicate-torrent" id="id160" name="id160">duplicate_torrent</a></li>
<li><a class="reference" href="#invalid-encoding" id="id161" name="id161">invalid_encoding</a></li>
<li><a class="reference" href="#type-error" id="id162" name="id162">type_error</a></li>
<li><a class="reference" href="#invalid-torrent-file" id="id163" name="id163">invalid_torrent_file</a></li>
</ul>
</li>
<li><a class="reference" href="#storage-interface" id="id163" name="id163">storage_interface</a><ul>
<li><a class="reference" href="#initialize" id="id164" name="id164">initialize()</a></li>
<li><a class="reference" href="#read" id="id165" name="id165">read()</a></li>
<li><a class="reference" href="#write" id="id166" name="id166">write()</a></li>
<li><a class="reference" href="#id12" id="id167" name="id167">move_storage()</a></li>
<li><a class="reference" href="#verify-resume-data" id="id168" name="id168">verify_resume_data()</a></li>
<li><a class="reference" href="#write-resume-data" id="id169" name="id169">write_resume_data()</a></li>
<li><a class="reference" href="#move-slot" id="id170" name="id170">move_slot()</a></li>
<li><a class="reference" href="#swap-slots" id="id171" name="id171">swap_slots()</a></li>
<li><a class="reference" href="#swap-slots3" id="id172" name="id172">swap_slots3()</a></li>
<li><a class="reference" href="#hash-for-slot" id="id173" name="id173">hash_for_slot()</a></li>
<li><a class="reference" href="#release-files" id="id174" name="id174">release_files()</a></li>
<li><a class="reference" href="#delete-files" id="id175" name="id175">delete_files()</a></li>
<li><a class="reference" href="#storage-interface" id="id164" name="id164">storage_interface</a><ul>
<li><a class="reference" href="#initialize" id="id165" name="id165">initialize()</a></li>
<li><a class="reference" href="#read" id="id166" name="id166">read()</a></li>
<li><a class="reference" href="#write" id="id167" name="id167">write()</a></li>
<li><a class="reference" href="#id12" id="id168" name="id168">move_storage()</a></li>
<li><a class="reference" href="#verify-resume-data" id="id169" name="id169">verify_resume_data()</a></li>
<li><a class="reference" href="#write-resume-data" id="id170" name="id170">write_resume_data()</a></li>
<li><a class="reference" href="#move-slot" id="id171" name="id171">move_slot()</a></li>
<li><a class="reference" href="#swap-slots" id="id172" name="id172">swap_slots()</a></li>
<li><a class="reference" href="#swap-slots3" id="id173" name="id173">swap_slots3()</a></li>
<li><a class="reference" href="#hash-for-slot" id="id174" name="id174">hash_for_slot()</a></li>
<li><a class="reference" href="#release-files" id="id175" name="id175">release_files()</a></li>
<li><a class="reference" href="#delete-files" id="id176" name="id176">delete_files()</a></li>
</ul>
</li>
<li><a class="reference" href="#magnet-links" id="id176" name="id176">magnet links</a></li>
<li><a class="reference" href="#queuing" id="id177" name="id177">queuing</a><ul>
<li><a class="reference" href="#downloading" id="id178" name="id178">downloading</a></li>
<li><a class="reference" href="#seeding" id="id179" name="id179">seeding</a></li>
<li><a class="reference" href="#magnet-links" id="id177" name="id177">magnet links</a></li>
<li><a class="reference" href="#queuing" id="id178" name="id178">queuing</a><ul>
<li><a class="reference" href="#downloading" id="id179" name="id179">downloading</a></li>
<li><a class="reference" href="#seeding" id="id180" name="id180">seeding</a></li>
</ul>
</li>
<li><a class="reference" href="#fast-resume" id="id180" name="id180">fast resume</a><ul>
<li><a class="reference" href="#file-format" id="id181" name="id181">file format</a></li>
<li><a class="reference" href="#fast-resume" id="id181" name="id181">fast resume</a><ul>
<li><a class="reference" href="#file-format" id="id182" name="id182">file format</a></li>
</ul>
</li>
<li><a class="reference" href="#threads" id="id182" name="id182">threads</a></li>
<li><a class="reference" href="#storage-allocation" id="id183" name="id183">storage allocation</a><ul>
<li><a class="reference" href="#sparse-allocation" id="id184" name="id184">sparse allocation</a></li>
<li><a class="reference" href="#full-allocation" id="id185" name="id185">full allocation</a></li>
<li><a class="reference" href="#compact-allocation" id="id186" name="id186">compact allocation</a></li>
<li><a class="reference" href="#threads" id="id183" name="id183">threads</a></li>
<li><a class="reference" href="#storage-allocation" id="id184" name="id184">storage allocation</a><ul>
<li><a class="reference" href="#sparse-allocation" id="id185" name="id185">sparse allocation</a></li>
<li><a class="reference" href="#full-allocation" id="id186" name="id186">full allocation</a></li>
<li><a class="reference" href="#compact-allocation" id="id187" name="id187">compact allocation</a></li>
</ul>
</li>
<li><a class="reference" href="#extensions" id="id187" name="id187">extensions</a><ul>
<li><a class="reference" href="#metadata-from-peers" id="id188" name="id188">metadata from peers</a></li>
<li><a class="reference" href="#http-seeding" id="id189" name="id189">HTTP seeding</a></li>
<li><a class="reference" href="#extensions" id="id188" name="id188">extensions</a><ul>
<li><a class="reference" href="#metadata-from-peers" id="id189" name="id189">metadata from peers</a></li>
<li><a class="reference" href="#http-seeding" id="id190" name="id190">HTTP seeding</a></li>
</ul>
</li>
<li><a class="reference" href="#filename-checks" id="id190" name="id190">filename checks</a></li>
<li><a class="reference" href="#acknowledgments" id="id191" name="id191">acknowledgments</a></li>
<li><a class="reference" href="#filename-checks" id="id191" name="id191">filename checks</a></li>
<li><a class="reference" href="#acknowledgments" id="id192" name="id192">acknowledgments</a></li>
</ul>
</div>
<div class="section">
@ -3717,6 +3718,10 @@ pieces are completed.</td>
<tr><td><tt class="docutils literal"><span class="pre">ip_block_notification</span></tt></td>
<td>Alerts when a peer is blocked by the ip blocker or port blocker.</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">performance_warning</span></tt></td>
<td>Alerts when some limit is reached that might limit the download
or upload rate.</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">all_categories</span></tt></td>
<td>The full bitmask, representing all available categories.</td>
</tr>
@ -3747,6 +3752,7 @@ public:
status_notification = <em>implementation defined</em>,
progress_notification = <em>implementation defined</em>,
ip_block_notification = <em>implementation defined</em>,
performance_warning = <em>implementation defined</em>,
all_categories = <em>implementation defined</em>
};
@ -4063,6 +4069,25 @@ torrent in question.</p>
<p>There are no additional data members in this alert.</p>
</div>
<div class="section">
<h2><a id="performance-alert" name="performance-alert">performance_alert</a></h2>
<p>This alert is generated when a limit is reached that might have a negative impact on
upload or download rate performance.</p>
<pre class="literal-block">
struct performance_alert: torrent_alert
{
// ...
enum performance_warning_t
{
outstanding_disk_buffer_limit_reached,
outstanding_request_limit_reached,
};
performance_warning_t warning_code;
};
</pre>
</div>
<div class="section">
<h2><a id="metadata-failed-alert" name="metadata-failed-alert">metadata_failed_alert</a></h2>
<p>This alert is generated when the metadata has been completely received and the info-hash
failed to match it. i.e. the metadata that was received was corrupt. libtorrent will

View File

@ -3793,6 +3793,9 @@ is a bitmask with the following bits:
+--------------------------------+---------------------------------------------------------------------+
| ``ip_block_notification`` | Alerts when a peer is blocked by the ip blocker or port blocker. |
+--------------------------------+---------------------------------------------------------------------+
| ``performance_warning`` | Alerts when some limit is reached that might limit the download |
| | or upload rate. |
+--------------------------------+---------------------------------------------------------------------+
| ``all_categories`` | The full bitmask, representing all available categories. |
+--------------------------------+---------------------------------------------------------------------+
@ -3826,6 +3829,7 @@ is its synopsis:
status_notification = *implementation defined*,
progress_notification = *implementation defined*,
ip_block_notification = *implementation defined*,
performance_warning = *implementation defined*,
all_categories = *implementation defined*
};
@ -4205,6 +4209,28 @@ torrent in question.
There are no additional data members in this alert.
performance_alert
-----------------
This alert is generated when a limit is reached that might have a negative impact on
upload or download rate performance.
::
struct performance_alert: torrent_alert
{
// ...
enum performance_warning_t
{
outstanding_disk_buffer_limit_reached,
outstanding_request_limit_reached,
};
performance_warning_t warning_code;
};
metadata_failed_alert
---------------------

View File

@ -82,6 +82,7 @@ namespace libtorrent {
status_notification = 0x40,
progress_notification = 0x80,
ip_block_notification = 0x100,
performance_warning = 0x200,
all_categories = 0xffffffff
};

View File

@ -151,6 +151,42 @@ namespace libtorrent
int index;
};
struct TORRENT_EXPORT performance_alert: torrent_alert
{
enum performance_warning_t
{
outstanding_disk_buffer_limit_reached,
outstanding_request_limit_reached,
};
performance_alert(torrent_handle const& h
, performance_warning_t w)
: torrent_alert(h)
, warning_code(w)
{}
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new performance_alert(*this)); }
virtual char const* what() const { return "performance warning"; }
virtual std::string message() const
{
static char const* warning_str[] =
{
"max outstanding disk writes reached",
"max outstanding piece requests reached",
};
return torrent_alert::message() + ": performance warning: "
+ warning_str[warning_code];
}
const static int static_category = alert::performance_warning;
virtual int category() const { return static_category; }
performance_warning_t warning_code;
};
struct TORRENT_EXPORT state_changed_alert: torrent_alert
{
state_changed_alert(torrent_handle const& h

View File

@ -1643,6 +1643,13 @@ namespace libtorrent
TORRENT_ASSERT(m_channel_state[download_channel] == peer_info::bw_idle);
m_download_queue.erase(b);
if (m_outstanding_writing_bytes >= m_ses.settings().max_outstanding_disk_bytes_per_connection
&& t->alerts().should_post<performance_alert>())
{
t->alerts().post_alert(performance_alert(t->get_handle()
, performance_alert::outstanding_disk_buffer_limit_reached));
}
if (!m_download_queue.empty())
{
m_timeout_extend = (std::max)(m_timeout_extend
@ -2765,6 +2772,13 @@ namespace libtorrent
m_desired_queue_size = m_max_out_request_queue;
if (m_desired_queue_size < min_request_queue)
m_desired_queue_size = min_request_queue;
if (m_desired_queue_size == m_max_out_request_queue
&& t->alerts().should_post<performance_alert>())
{
t->alerts().post_alert(performance_alert(t->get_handle()
, performance_alert::outstanding_request_limit_reached));
}
}
if (!m_download_queue.empty()

View File

@ -196,14 +196,14 @@ boost::intrusive_ptr<T> clone_ptr(boost::intrusive_ptr<T> const& ptr)
return boost::intrusive_ptr<T>(new T(*ptr));
}
boost::intrusive_ptr<torrent_info> create_torrent(std::ostream* file, int piece_size)
boost::intrusive_ptr<torrent_info> create_torrent(std::ostream* file, int piece_size, int num_pieces)
{
char const* tracker_url = "http://non-existent-name.com/announce";
using namespace boost::filesystem;
file_storage fs;
int total_size = 2 * 1024 * 1024;
int total_size = piece_size * num_pieces;
fs.add_file(path("temporary"), total_size);
libtorrent::create_torrent t(fs, piece_size);
t.add_tracker(tracker_url);
@ -253,7 +253,7 @@ setup_transfer(session* ses1, session* ses2, session* ses3
{
create_directory("./tmp1" + suffix);
std::ofstream file(("./tmp1" + suffix + "/temporary").c_str());
t = ::create_torrent(&file, piece_size);
t = ::create_torrent(&file, piece_size, 1024 / 8);
file.close();
if (clear_files)
{

View File

@ -42,7 +42,7 @@ void print_alerts(libtorrent::session& ses, char const* name
, bool allow_no_torrents = false);
void test_sleep(int millisec);
boost::intrusive_ptr<libtorrent::torrent_info> create_torrent(std::ostream* file = 0, int piece_size = 16 * 1024);
boost::intrusive_ptr<libtorrent::torrent_info> create_torrent(std::ostream* file = 0, int piece_size = 16 * 1024, int num_pieces = 1024 / 8);
boost::tuple<libtorrent::torrent_handle, libtorrent::torrent_handle
, libtorrent::torrent_handle>

View File

@ -45,12 +45,64 @@ POSSIBILITY OF SUCH DAMAGE.
using boost::filesystem::remove_all;
using boost::filesystem::exists;
using boost::filesystem::create_directory;
using namespace libtorrent;
using boost::tuples::ignore;
// test the maximum transfer rate
void test_rate()
{
session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48575, 49000));
session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49575, 50000));
torrent_handle tor1;
torrent_handle tor2;
create_directory("./tmp1_transfer");
std::ofstream file("./tmp1_transfer/temporary");
boost::intrusive_ptr<torrent_info> t = ::create_torrent(&file, 4 * 1024 * 1024, 50);
file.close();
boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0
, true, false, true, "_transfer", 0, &t);
ses1.set_alert_mask(alert::all_categories & ~alert::progress_notification);
ses2.set_alert_mask(alert::all_categories & ~alert::progress_notification);
ptime start = time_now();
for (int i = 0; i < 40; ++i)
{
print_alerts(ses1, "ses1");
print_alerts(ses2, "ses2");
torrent_status st1 = tor1.status();
torrent_status st2 = tor2.status();
std::cerr
<< "up: \033[33m" << st1.upload_payload_rate / 1000000.f << "MB/s "
<< " down: \033[32m" << st2.download_payload_rate / 1000000.f << "MB/s "
<< "\033[0m" << int(st2.progress * 100) << "% "
<< std::endl;
if (st1.paused) break;
if (tor2.is_seed()) break;
test_sleep(1000);
}
TEST_CHECK(tor2.is_seed());
time_duration dt = time_now() - start;
std::cerr << "downloaded " << t->total_size() << " bytes "
"in " << (total_milliseconds(dt) / 1000.f) << " seconds" << std::endl;
std::cerr << "average download rate: " << (t->total_size() / total_milliseconds(dt))
<< " kB/s" << std::endl;
}
void test_transfer()
{
using namespace libtorrent;
using boost::tuples::ignore;
session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48075, 49000));
session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49075, 50000));
@ -72,7 +124,7 @@ void test_transfer()
// test using piece sizes smaller than 16kB
boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0
, true, false, true, "_transfer", 8 * 1024, &t);
, true, false, true, "_transfer", 8 * 1024, &t);
// set half of the pieces to priority 0
int num_pieces = tor2.get_torrent_info().num_pieces();
@ -83,9 +135,6 @@ void test_transfer()
ses1.set_alert_mask(alert::all_categories & ~alert::progress_notification);
ses2.set_alert_mask(alert::all_categories & ~alert::progress_notification);
tor1.resume();
tor2.resume();
for (int i = 0; i < 30; ++i)
{
print_alerts(ses1, "ses1");
@ -158,6 +207,7 @@ void test_transfer()
p.save_path = "./tmp2_transfer";
p.resume_data = &resume_data;
tor2 = ses2.add_torrent(p);
ses2.set_alert_mask(alert::all_categories & ~alert::progress_notification);
tor2.prioritize_pieces(priorities);
std::cout << "resetting priorities" << std::endl;
tor2.resume();
@ -224,8 +274,19 @@ int test_main()
try { remove_all("./tmp1_transfer"); } catch (std::exception&) {}
try { remove_all("./tmp2_transfer"); } catch (std::exception&) {}
#ifdef NDEBUG
// test rate only makes sense in release mode
test_rate();
try { remove_all("./tmp1_transfer"); } catch (std::exception&) {}
try { remove_all("./tmp2_transfer"); } catch (std::exception&) {}
#endif
test_transfer();
try { remove_all("./tmp1_transfer"); } catch (std::exception&) {}
try { remove_all("./tmp2_transfer"); } catch (std::exception&) {}
return 0;
}