1 #pragma once
2 
3 #include "measurementtask.h"
4 
5 class ProgressTask : public MeasurementTask {
6 public:
7     ProgressTask(const std::string &label, const std::string &ticket_string,
8                  const HttpHost &server,
9                  unsigned int no_conn = 4, unsigned int max_conn = 20,
10                  double duration = 10.0, double timeout = 25.0) :
MeasurementTask(label,ticket_string,server,no_conn,max_conn,timeout)11         MeasurementTask(label, ticket_string, server, no_conn, max_conn, timeout),
12         byte_count(0),
13         current_load_size(50000),
14         load_size_check(no_conn + 2),
15         current_duration(0.0),
16         current_mbps(0.0) {
17             if (duration < 2.0)
18                 tot_duration = 2.0;
19             else if (duration > 20.0)
20                 tot_duration = 20.0;
21             else
22                 tot_duration = duration;
23     }
24 
25     bool requestComplete(HttpClientConnection *) override;
26 
notifyBytesAndDuration(uint64_t count,double duration)27     void notifyBytesAndDuration(uint64_t count, double duration) {
28         double mbps = addOverheadMbps(count, duration);
29         doTestProgress(mbps, duration, currentNoConnections());
30     }
31 
notifyBytesLoaded(size_t n)32     void notifyBytesLoaded(size_t n) {
33         byte_count += n;
34     }
35 
36     // If you want to use the threadSendCount/threadRecvCount methods, you
37     // should call the below method in your start() method:
notifyStarted()38     void notifyStarted() {
39         thread_send_count = SocketConnection::totBytesSent();
40         thread_recv_count = SocketConnection::totBytesReceived();
41     }
42 
connectionLost()43     void connectionLost() override {
44         // We're dead. If more than half the test was completed,
45         // we keep the result.
46         if (current_duration > tot_duration*0.5)
47             setResult(fValue(current_mbps));
48         else
49             setResult("-1");
50     }
51 
set_speedlimit(double limit_mbps)52     void set_speedlimit(double limit_mbps) {
53         speedlimit_mbps = (limit_mbps < 0.5) ? 0.5 : limit_mbps;
54         if (speedlimit_mbps < 5.0)
55             current_load_size = 5000;
56     }
57 
58     size_t loadSize();
59 
currentDuration()60     double currentDuration() const {
61         return current_duration;
62     }
currentProgress()63     double currentProgress() const {
64         return current_duration/tot_duration;
65     }
currentMbps()66     double currentMbps() const {
67         return current_mbps;
68     }
69 protected:
byteCount()70     uint64_t byteCount() {
71         return byte_count;
72     }
73 
74     // Return total number of bytes sent through all sockets in the current
75     // thread since last call to notifyStarted():
threadSendCount()76     uint64_t threadSendCount() {
77         return SocketConnection::totBytesSent() - thread_send_count;
78     }
79 
80     // Return total number of bytes received from all sockets in the current
81     // thread since last call to notifyStarted():
threadRecvCount()82     uint64_t threadRecvCount() {
83         return SocketConnection::totBytesReceived() - thread_recv_count;
84     }
85 
addOverheadMbps(uint64_t n,double s)86     static double addOverheadMbps(uint64_t n, double s) {
87         if (s <= 0.0)
88             return 0.0;
89 
90         double mbps = n / s * 0.000008;
91         if (mbps > 8.0)
92             return (mbps * 1.02 + 0.16);
93         else
94             return mbps * 1.04;
95     }
96     void doTestProgress(double mbps, double duration, unsigned int no_conn);
soonFinished()97     bool soonFinished() const {
98         return soon_finished;
99     }
100 
101 private:
102     uint64_t byte_count, thread_send_count = 0, thread_recv_count = 0;
103     size_t current_load_size;
104     unsigned int load_size_check, no_started_loads = 0;
105     double tot_duration, current_duration, current_mbps;
106     double speedlimit_mbps = 0.0;
107     bool soon_finished = false;
108 };
109