)]}'
{"oslo_utils/speedutils.py":[{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"587395fbff258f681c7032a41239d46b67b09697","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"from oslo_utils import timeutils"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"if sys.version_info[0:2] \u003d\u003d (2, 6):"},{"line_number":26,"context_line":"    _PY26 \u003d True"},{"line_number":27,"context_line":"else:"},{"line_number":28,"context_line":"    _PY26 \u003d False"}],"source_content_type":"text/x-python","patch_set":8,"id":"9aa53dc9_f0f013ff","line":25,"updated":"2015-04-10 12:51:18.000000000","message":"You should write:\n\n_PY26 \u003d sys.version_info \u003c (2, 7)","commit_id":"ca7e08c6af4e93b1d925856e8971b88413a8290f"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"6f096fa379bfec514a48c10b28c954c4c20fe4c8","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"from oslo_utils import timeutils"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"if sys.version_info[0:2] \u003d\u003d (2, 6):"},{"line_number":26,"context_line":"    _PY26 \u003d True"},{"line_number":27,"context_line":"else:"},{"line_number":28,"context_line":"    _PY26 \u003d False"}],"source_content_type":"text/x-python","patch_set":8,"id":"7aaa499b_ed991121","line":25,"in_reply_to":"9aa53dc9_f0f013ff","updated":"2015-04-10 18:47:13.000000000","message":"No longer needed with using monotonic (or time.time).","commit_id":"ca7e08c6af4e93b1d925856e8971b88413a8290f"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"587395fbff258f681c7032a41239d46b67b09697","unresolved":false,"context_lines":[{"line_number":47,"context_line":"                        refresh_rate_seconds * initial_bucket_size)"},{"line_number":48,"context_line":"        self._items_per_tic \u003d items_per_second * refresh_rate_seconds"},{"line_number":49,"context_line":"        self._next_fill \u003d (timeutils.utcnow() +"},{"line_number":50,"context_line":"                           datetime.timedelta(seconds\u003drefresh_rate_seconds))"},{"line_number":51,"context_line":"        self._sleep \u003d sleep_func"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def _check_fill(self):"}],"source_content_type":"text/x-python","patch_set":8,"id":"9aa53dc9_b0228b50","line":50,"updated":"2015-04-10 12:51:18.000000000","message":"I don\u0027t think that datetime is the right format for such task. There are crazy stuff like DST and leap seconds, just use a number of seconds (see my comment below for time.monotonic).","commit_id":"ca7e08c6af4e93b1d925856e8971b88413a8290f"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"21ab196270290cb4d3939197a949e62923d553e4","unresolved":false,"context_lines":[{"line_number":47,"context_line":"                        refresh_rate_seconds * initial_bucket_size)"},{"line_number":48,"context_line":"        self._items_per_tic \u003d items_per_second * refresh_rate_seconds"},{"line_number":49,"context_line":"        self._next_fill \u003d (timeutils.utcnow() +"},{"line_number":50,"context_line":"                           datetime.timedelta(seconds\u003drefresh_rate_seconds))"},{"line_number":51,"context_line":"        self._sleep \u003d sleep_func"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    def _check_fill(self):"}],"source_content_type":"text/x-python","patch_set":8,"id":"7aaa499b_c7b5147f","line":50,"in_reply_to":"9aa53dc9_b0228b50","updated":"2015-04-10 17:46:28.000000000","message":"Will do.","commit_id":"ca7e08c6af4e93b1d925856e8971b88413a8290f"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"587395fbff258f681c7032a41239d46b67b09697","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        now \u003d timeutils.utcnow()"},{"line_number":58,"context_line":"        if now \u003e self._next_fill:"},{"line_number":59,"context_line":"            d \u003d now - self._next_fill"},{"line_number":60,"context_line":"            tics \u003d 1 + int(self._total_seconds(d) / self._refresh_rate_seconds)"},{"line_number":61,"context_line":"            self._bucket \u003d self._bucket + (tics * self._items_per_tic)"},{"line_number":62,"context_line":"            secs \u003d tics * self._refresh_rate_seconds"},{"line_number":63,"context_line":"            self._next_fill \u003d (self._next_fill +"}],"source_content_type":"text/x-python","patch_set":8,"id":"9aa53dc9_90cd4787","line":60,"updated":"2015-04-10 12:51:18.000000000","message":"You may round with math.ceil:\n\ntics \u003d int(math.ceil(self._total_seconds(d) / self._refresh_rate_seconds))\n\nOn Python 3, math.ceil returns an int, but it returns  a float on Python 2.","commit_id":"ca7e08c6af4e93b1d925856e8971b88413a8290f"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"587395fbff258f681c7032a41239d46b67b09697","unresolved":false,"context_lines":[{"line_number":77,"context_line":"            sz \u003d chunk_size_cb(chunk)"},{"line_number":78,"context_line":"            self._check_fill()"},{"line_number":79,"context_line":"            if sz \u003e self._bucket:"},{"line_number":80,"context_line":"                now \u003d timeutils.utcnow()"},{"line_number":81,"context_line":"                tics \u003d int((sz - self._bucket) / self._items_per_tic)"},{"line_number":82,"context_line":"                tm_diff \u003d self._next_fill - now"},{"line_number":83,"context_line":"                secs \u003d tics * self._refresh_rate_seconds"}],"source_content_type":"text/x-python","patch_set":8,"id":"9aa53dc9_5050dfd3","line":80,"updated":"2015-04-10 12:51:18.000000000","message":"It may be more reliable to use a monotonic clock here. Python 3.3 has time.monotonic().\n\nUse maybe in the constructor:\n\nself._timer \u003d getattr(time, \u0027monotonic\u0027, time.time)\n\nMaybe make it configurable (and use this code ^^ by default).","commit_id":"ca7e08c6af4e93b1d925856e8971b88413a8290f"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"21ab196270290cb4d3939197a949e62923d553e4","unresolved":false,"context_lines":[{"line_number":77,"context_line":"            sz \u003d chunk_size_cb(chunk)"},{"line_number":78,"context_line":"            self._check_fill()"},{"line_number":79,"context_line":"            if sz \u003e self._bucket:"},{"line_number":80,"context_line":"                now \u003d timeutils.utcnow()"},{"line_number":81,"context_line":"                tics \u003d int((sz - self._bucket) / self._items_per_tic)"},{"line_number":82,"context_line":"                tm_diff \u003d self._next_fill - now"},{"line_number":83,"context_line":"                secs \u003d tics * self._refresh_rate_seconds"}],"source_content_type":"text/x-python","patch_set":8,"id":"7aaa499b_a7ba086d","line":80,"in_reply_to":"9aa53dc9_5050dfd3","updated":"2015-04-10 17:46:28.000000000","message":"Agreed.","commit_id":"ca7e08c6af4e93b1d925856e8971b88413a8290f"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"e59d23cc46163b0342372d8d5c0c08cab7c5fa49","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    A wrapper object that uses the `token bucket`_ algorithm to limit the"},{"line_number":32,"context_line":"    rate at which values comes out of an iterable. This can be used to limit"},{"line_number":33,"context_line":"    the consumption speed of iteration of some other iterator (or iterable)."},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    .. _token bucket: http://en.wikipedia.org/wiki/Token_bucket"},{"line_number":36,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":10,"id":"7aaa499b_42ed568a","line":33,"updated":"2015-04-13 08:16:42.000000000","message":"The API is not obvious for me. You should write a short example, maybe with a theoric downloader. I don\u0027t understand the meaning of \"items_per_second\": what is \"an item\"? What is the purpose of the \"initial_bucket_size\" parameter?","commit_id":"9c04fbc84b709d6b092cf27643963d3ea3d741d1"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"7acf64fc54b69cfbcc7d16159d13838471f4ba23","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    A wrapper object that uses the `token bucket`_ algorithm to limit the"},{"line_number":32,"context_line":"    rate at which values comes out of an iterable. This can be used to limit"},{"line_number":33,"context_line":"    the consumption speed of iteration of some other iterator (or iterable)."},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    .. _token bucket: http://en.wikipedia.org/wiki/Token_bucket"},{"line_number":36,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":10,"id":"7aaa499b_1a19bc88","line":33,"in_reply_to":"7aaa499b_42ed568a","updated":"2015-04-14 15:25:43.000000000","message":"I\u0027ll write example to make it more clear, since I agree, initially its not :)","commit_id":"9c04fbc84b709d6b092cf27643963d3ea3d741d1"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"e59d23cc46163b0342372d8d5c0c08cab7c5fa49","unresolved":false,"context_lines":[{"line_number":56,"context_line":"        if now \u003e self._next_fill:"},{"line_number":57,"context_line":"            d \u003d now - self._next_fill"},{"line_number":58,"context_line":"            tics \u003d int(math.ceil(d / self._refresh_rate_seconds))"},{"line_number":59,"context_line":"            self._bucket \u003d self._bucket + (tics * self._items_per_tic)"},{"line_number":60,"context_line":"            secs \u003d tics * self._refresh_rate_seconds"},{"line_number":61,"context_line":"            self._next_fill \u003d self._next_fill + secs"},{"line_number":62,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"7aaa499b_8230fe57","line":59,"updated":"2015-04-13 08:16:42.000000000","message":"Hum, you may write self._bucket +\u003d","commit_id":"9c04fbc84b709d6b092cf27643963d3ea3d741d1"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"e59d23cc46163b0342372d8d5c0c08cab7c5fa49","unresolved":false,"context_lines":[{"line_number":58,"context_line":"            tics \u003d int(math.ceil(d / self._refresh_rate_seconds))"},{"line_number":59,"context_line":"            self._bucket \u003d self._bucket + (tics * self._items_per_tic)"},{"line_number":60,"context_line":"            secs \u003d tics * self._refresh_rate_seconds"},{"line_number":61,"context_line":"            self._next_fill \u003d self._next_fill + secs"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"    def speed_limit_iter(self, itr, chunk_size_cb\u003dNone):"},{"line_number":64,"context_line":"        \"\"\"Return an iterator/generator which limits after each iteration."}],"source_content_type":"text/x-python","patch_set":10,"id":"7aaa499b_423af637","line":61,"updated":"2015-04-13 08:16:42.000000000","message":"Ditto: self._next_fill +\u003d tics * self._refresh_rate_seconds","commit_id":"9c04fbc84b709d6b092cf27643963d3ea3d741d1"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"e59d23cc46163b0342372d8d5c0c08cab7c5fa49","unresolved":false,"context_lines":[{"line_number":83,"context_line":"                    secs +\u003d tm_diff"},{"line_number":84,"context_line":"                self._sleep(secs)"},{"line_number":85,"context_line":"                self._check_fill()"},{"line_number":86,"context_line":"            self._bucket \u003d self._bucket - sz"},{"line_number":87,"context_line":"            yield chunk"}],"source_content_type":"text/x-python","patch_set":10,"id":"7aaa499b_629f3204","line":86,"updated":"2015-04-13 08:16:42.000000000","message":"You may write: self._bucket -\u003d sz","commit_id":"9c04fbc84b709d6b092cf27643963d3ea3d741d1"},{"author":{"_account_id":4190,"name":"lifeless","email":"robertc@robertcollins.net","username":"lifeless"},"change_message_id":"759364577e94da2f3c596c2b50e406b1d05373d6","unresolved":false,"context_lines":[{"line_number":88,"context_line":"                 initial_bucket_size\u003d1,"},{"line_number":89,"context_line":"                 # Made a keyword argument, so one could replace this"},{"line_number":90,"context_line":"                 # with a eventlet.sleep or other idling function..."},{"line_number":91,"context_line":"                 sleep_func\u003dtime.sleep):"},{"line_number":92,"context_line":"        self._refresh_rate_seconds \u003d refresh_rate_seconds"},{"line_number":93,"context_line":"        self._bucket \u003d (items_per_second *"},{"line_number":94,"context_line":"                        refresh_rate_seconds * initial_bucket_size)"}],"source_content_type":"text/x-python","patch_set":12,"id":"7a016987_0911065d","line":91,"updated":"2015-05-23 00:28:56.000000000","message":"This would be a lot easier to read like so:\n\n def __init__(\n         self, items_per_second, refresh_rate_seconds\u003d0.01,\n         initial_bucket_size\u003d1, sleep_func\u003dtime.sleep):\n     \"\"\"Create a SpeedLimit.\n\n     :param items_per_second: X, Y, Z\n     :param refresh_rate_seconds: A, B, C\n     \"\"\"","commit_id":"6c5b1e2c74c589c1574ea89beb2bd768d4a8aa39"}]}
