Ticket #1166: rate-computation-refactoring-2.dpatch

File rate-computation-refactoring-2.dpatch, 7.5 KB (added by francois, at 2010-08-15T14:51:04Z)
Line 
1Sun Aug 15 16:19:33 CEST 2010  francois@ctrlaltdel.ch
2  * web: refactor rate computation, fixes #1166
3
4New patches:
5
6[web: refactor rate computation, fixes #1166
7francois@ctrlaltdel.ch**20100815141933
8 Ignore-this: d25491858e137894142eaa67c75b0439
9] {
10hunk ./src/allmydata/test/test_web.py 90
11     ds.add_segment_request(2, now+4)
12     ds.add_segment_request(3, now+5)
13 
14+    # simulate a segment which gets delivered faster than a system clock tick (ticket #1166)
15+    ds.add_segment_request(4, now)
16+    ds.add_segment_delivery(4, now, 0, 140, 0.5)
17+
18     e = ds.add_dyhb_sent("serverid_a", now)
19     e.finished([1,2], now+1)
20     e = ds.add_dyhb_sent("serverid_b", now+2) # left unfinished
21hunk ./src/allmydata/test/test_web.py 3176
22         self.failUnlessReallyEqual(common.abbreviate_time(0.000123), "123us")
23         self.failUnlessReallyEqual(common.abbreviate_time(-123000), "-123000000000us")
24 
25+    def test_compute_rate(self):
26+        self.failUnlessReallyEqual(common.compute_rate(None, None), None)
27+        self.failUnlessReallyEqual(common.compute_rate(None, 1), None)
28+        self.failUnlessReallyEqual(common.compute_rate(250000, None), None)
29+        self.failUnlessReallyEqual(common.compute_rate(250000, 0), None)
30+        self.failUnlessReallyEqual(common.compute_rate(250000, 10), 25000.0)
31+        self.failUnlessReallyEqual(common.compute_rate(0, 10), 0.0)
32+        self.shouldFail(AssertionError, "test_compute_rate", "",
33+                        common.compute_rate, -100, 10)
34+        self.shouldFail(AssertionError, "test_compute_rate", "",
35+                        common.compute_rate, 100, -10)
36+
37+        # Sanity check
38+        rate = common.compute_rate(10*1000*1000, 1)
39+        self.failUnlessReallyEqual(common.abbreviate_rate(rate), "10.00MBps")
40+
41     def test_abbreviate_rate(self):
42         self.failUnlessReallyEqual(common.abbreviate_rate(None), "")
43         self.failUnlessReallyEqual(common.abbreviate_rate(1234000), "1.23MBps")
44hunk ./src/allmydata/web/common.py 93
45         return "%.1fms" % (1000*s)
46     return "%.0fus" % (1000000*s)
47 
48+def compute_rate(bytes, seconds):
49+    if bytes is None:
50+      return None
51+
52+    if seconds is None or seconds == 0:
53+      return None
54+
55+    # negative values don't make sense here
56+    assert bytes > -1
57+    assert seconds > 0
58+
59+    return 1.0 * bytes / seconds
60+
61 def abbreviate_rate(data):
62     # 21.8kBps, 554.4kBps 4.37MBps
63     if data is None:
64hunk ./src/allmydata/web/status.py 8
65 from nevow import rend, inevow, tags as T
66 from allmydata.util import base32, idlib
67 from allmydata.web.common import getxmlfile, get_arg, \
68-     abbreviate_time, abbreviate_rate, abbreviate_size, plural
69+     abbreviate_time, abbreviate_rate, abbreviate_size, plural, compute_rate
70 from allmydata.interfaces import IUploadStatus, IDownloadStatus, \
71      IPublishStatus, IRetrieveStatus, IServermapUpdaterStatus
72 
73hunk ./src/allmydata/web/status.py 113
74         def _convert(r):
75             file_size = r.file_size
76             time = r.timings.get(name)
77-            if time is None:
78-                return None
79-            try:
80-                return 1.0 * file_size / time
81-            except ZeroDivisionError:
82-                return None
83+            return compute_rate(file_size, time)
84         d.addCallback(_convert)
85         return d
86 
87hunk ./src/allmydata/web/status.py 135
88             file_size = r.file_size
89             time1 = r.timings.get("cumulative_encoding")
90             time2 = r.timings.get("cumulative_sending")
91-            if (file_size is None or time1 is None or time2 is None):
92-                return None
93-            try:
94-                return 1.0 * file_size / (time1+time2)
95-            except ZeroDivisionError:
96+            if (time1 is None or time2 is None):
97                 return None
98hunk ./src/allmydata/web/status.py 137
99+            else:
100+                return compute_rate(file_size, time1+time2)
101         d.addCallback(_convert)
102         return d
103 
104hunk ./src/allmydata/web/status.py 147
105         def _convert(r):
106             fetch_size = r.ciphertext_fetched
107             time = r.timings.get("cumulative_fetch")
108-            if (fetch_size is None or time is None):
109-                return None
110-            try:
111-                return 1.0 * fetch_size / time
112-            except ZeroDivisionError:
113-                return None
114+            return compute_rate(fetch_size, time)
115         d.addCallback(_convert)
116         return d
117 
118hunk ./src/allmydata/web/status.py 299
119         def _convert(r):
120             file_size = r.file_size
121             time = r.timings.get(name)
122-            if time is None:
123-                return None
124-            try:
125-                return 1.0 * file_size / time
126-            except ZeroDivisionError:
127-                return None
128+            return compute_rate(file_size, time)
129         d.addCallback(_convert)
130         return d
131 
132hunk ./src/allmydata/web/status.py 419
133             (start, length, requesttime, finishtime, bytes, decrypt, paused) = r_ev
134             if finishtime is not None:
135                 rtt = finishtime - requesttime - paused
136-                speed = self.render_rate(None, 1.0 * bytes / rtt)
137+                speed = self.render_rate(None, compute_rate(bytes, rtt))
138                 rtt = self.render_time(None, rtt)
139                 decrypt = self.render_time(None, decrypt)
140                 paused = self.render_time(None, paused)
141hunk ./src/allmydata/web/status.py 445
142             elif etype == "delivery":
143                 if reqtime[0] == segnum:
144                     segtime = when - reqtime[1]
145-                    speed = self.render_rate(None, 1.0 * seglen / segtime)
146+                    speed = self.render_rate(None, compute_rate(seglen, segtime))
147                     segtime = self.render_time(None, segtime)
148                 else:
149                     segtime, speed = "", ""
150hunk ./src/allmydata/web/status.py 581
151     def _get_rate(self, data, name):
152         file_size = self.retrieve_status.get_size()
153         time = self.retrieve_status.timings.get(name)
154-        if time is None or file_size is None:
155-            return None
156-        try:
157-            return 1.0 * file_size / time
158-        except ZeroDivisionError:
159-            return None
160+        return compute_rate(file_size, time)
161 
162     def data_time_total(self, ctx, data):
163         return self.retrieve_status.timings.get("total")
164hunk ./src/allmydata/web/status.py 682
165     def _get_rate(self, data, name):
166         file_size = self.publish_status.get_size()
167         time = self.publish_status.timings.get(name)
168-        if time is None:
169-            return None
170-        try:
171-            return 1.0 * file_size / time
172-        except ZeroDivisionError:
173-            return None
174+        return compute_rate(file_size, time)
175 
176     def data_time_total(self, ctx, data):
177         return self.publish_status.timings.get("total")
178}
179
180Context:
181
182[docs: doc of the download status page
183zooko@zooko.com**20100814054117
184 Ignore-this: a82ec33da3c39a7c0d47a7a6b5f81bbb
185 ref: http://tahoe-lafs.org/trac/tahoe-lafs/ticket/1169#comment:1
186] 
187[docs: NEWS: edit English usage, remove ticket numbers for regressions vs. 1.7.1 that were fixed again before 1.8.0c2
188zooko@zooko.com**20100811071758
189 Ignore-this: 993f5a1e6a9535f5b7a0bd77b93b66d0
190] 
191[docs: NEWS: more detail about new-downloader
192zooko@zooko.com**20100811071303
193 Ignore-this: 9f07da4dce9d794ce165aae287f29a1e
194] 
195[TAG allmydata-tahoe-1.8.0c2
196david-sarah@jacaranda.org**20100810073847
197 Ignore-this: c37f732b0e45f9ebfdc2f29c0899aeec
198] 
199Patch bundle hash:
200b4ab71199038ab152460740736728178902a5d8c