1 | Sun Aug 15 16:19:33 CEST 2010 francois@ctrlaltdel.ch |
---|
2 | * web: refactor rate computation, fixes #1166 |
---|
3 | |
---|
4 | New patches: |
---|
5 | |
---|
6 | [web: refactor rate computation, fixes #1166 |
---|
7 | francois@ctrlaltdel.ch**20100815141933 |
---|
8 | Ignore-this: d25491858e137894142eaa67c75b0439 |
---|
9 | ] { |
---|
10 | hunk ./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 |
---|
21 | hunk ./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") |
---|
44 | hunk ./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: |
---|
64 | hunk ./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 | |
---|
73 | hunk ./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 | |
---|
87 | hunk ./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 |
---|
98 | hunk ./src/allmydata/web/status.py 137 |
---|
99 | + else: |
---|
100 | + return compute_rate(file_size, time1+time2) |
---|
101 | d.addCallback(_convert) |
---|
102 | return d |
---|
103 | |
---|
104 | hunk ./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 | |
---|
118 | hunk ./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 | |
---|
132 | hunk ./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) |
---|
141 | hunk ./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 = "", "" |
---|
150 | hunk ./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") |
---|
164 | hunk ./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 | |
---|
180 | Context: |
---|
181 | |
---|
182 | [docs: doc of the download status page |
---|
183 | zooko@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 |
---|
188 | zooko@zooko.com**20100811071758 |
---|
189 | Ignore-this: 993f5a1e6a9535f5b7a0bd77b93b66d0 |
---|
190 | ] |
---|
191 | [docs: NEWS: more detail about new-downloader |
---|
192 | zooko@zooko.com**20100811071303 |
---|
193 | Ignore-this: 9f07da4dce9d794ce165aae287f29a1e |
---|
194 | ] |
---|
195 | [TAG allmydata-tahoe-1.8.0c2 |
---|
196 | david-sarah@jacaranda.org**20100810073847 |
---|
197 | Ignore-this: c37f732b0e45f9ebfdc2f29c0899aeec |
---|
198 | ] |
---|
199 | Patch bundle hash: |
---|
200 | b4ab71199038ab152460740736728178902a5d8c |
---|