)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bbc99b58153848e031f6f9e84b5de5ca8419be24","unresolved":false,"context_lines":[{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Instead of trying to lock path/.lock, utils.lock_path() now tries to lock"},{"line_number":15,"context_line":"files path/.lock-X, where X is in the range (0, N), N being the limit for"},{"line_number":16,"context_line":"the number of locks allowed for the path. The default value of limit is"},{"line_number":17,"context_line":"set to 1."},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"Change-Id: I3c3193344c7a57a8a4fc7932d1b10e702efd3572"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":11,"id":"3f4b6375_c3afed27","line":17,"range":{"start_line":16,"start_character":42,"end_line":17,"end_character":8},"updated":"2017-10-25 21:26:38.000000000","message":"On the off-chance we have to re-roll this, it may be worth calling out that this preserves the prior default behavior of replication_one_per_device.","commit_id":"e199192caefef068b5bf57da8b878e0bc82e3453"}],"doc/source/deployment_guide.rst":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"338d378680dddcbff758be1d27f8a62f3e0a1950","unresolved":false,"context_lines":[{"line_number":600,"context_line":"replication_concurrency        4                      Set to restrict the number of"},{"line_number":601,"context_line":"                                                      concurrent incoming SSYNC"},{"line_number":602,"context_line":"                                                      requests; set to 0 for unlimited"},{"line_number":603,"context_line":"replication_concurrency_per_device 1                  Set to restrict the number of"},{"line_number":604,"context_line":"                                                      concurrent incoming REPLICATION"},{"line_number":605,"context_line":"                                                      requests per device; set to 0 for"},{"line_number":606,"context_line":"                                                      unlimited requests per devices."}],"source_content_type":"text/x-rst","patch_set":3,"id":"9a30ddce_63edd424","line":603,"updated":"2017-03-09 03:13:50.000000000","message":"gah, table alignment - there has got to be a better way!?","commit_id":"e458e8bdd67cc8e05b0a73935b43e16ac87d1488"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"50b0c19716a785101928de33ea08c2166bccaf9b","unresolved":false,"context_lines":[{"line_number":612,"context_line":"                                                      concurrent incoming SSYNC"},{"line_number":613,"context_line":"                                                      requests; set to 0 for unlimited"},{"line_number":614,"context_line":"replication_concurrency_per_device 1                  Set to restrict the number of"},{"line_number":615,"context_line":"                                                      concurrent incoming REPLICATION"},{"line_number":616,"context_line":"                                                      requests per device; set to 0 for"},{"line_number":617,"context_line":"                                                      unlimited requests per devices."},{"line_number":618,"context_line":"                                                      This can help control I/O to each"}],"source_content_type":"text/x-rst","patch_set":8,"id":"3f4b6375_0f079f1a","line":615,"range":{"start_line":615,"start_character":74,"end_line":615,"end_character":85},"updated":"2017-10-24 12:42:27.000000000","message":"SSYNC","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"cdefe898131a477bb0f9ad054d2cc5f3c63fa756","unresolved":false,"context_lines":[{"line_number":612,"context_line":"                                                      concurrent incoming SSYNC"},{"line_number":613,"context_line":"                                                      requests; set to 0 for unlimited"},{"line_number":614,"context_line":"replication_concurrency_per_device 1                  Set to restrict the number of"},{"line_number":615,"context_line":"                                                      concurrent incoming REPLICATION"},{"line_number":616,"context_line":"                                                      requests per device; set to 0 for"},{"line_number":617,"context_line":"                                                      unlimited requests per devices."},{"line_number":618,"context_line":"                                                      This can help control I/O to each"}],"source_content_type":"text/x-rst","patch_set":8,"id":"3f4b6375_01eacbaa","line":615,"range":{"start_line":615,"start_character":74,"end_line":615,"end_character":85},"in_reply_to":"3f4b6375_0f079f1a","updated":"2017-10-24 15:23:47.000000000","message":"Done","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"}],"etc/object-server.conf-sample":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"785ed83ef80c0a3a453fb39725bfe414badf0740","unresolved":false,"context_lines":[{"line_number":143,"context_line":"# I/O to each device. This does not override replication_concurrency described"},{"line_number":144,"context_line":"# above, so you may need to adjust both parameters depending on your hardware"},{"line_number":145,"context_line":"# or network capacity."},{"line_number":146,"context_line":"# replication_concurrency_per_device \u003d 1"},{"line_number":147,"context_line":"#"},{"line_number":148,"context_line":"# Number of seconds to wait for an existing replication device lock before"},{"line_number":149,"context_line":"# giving up."}],"source_content_type":"application/octet-stream","patch_set":2,"id":"9a30ddce_cf825552","line":146,"updated":"2017-03-08 00:05:59.000000000","message":"yup +1 for this deprecation strategy","commit_id":"5050693ec40e1eebaf1c0d00066b37474d290b0d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"50b0c19716a785101928de33ea08c2166bccaf9b","unresolved":false,"context_lines":[{"line_number":161,"context_line":"# object replicator when configured to use ssync."},{"line_number":162,"context_line":"# replication_concurrency \u003d 4"},{"line_number":163,"context_line":"#"},{"line_number":164,"context_line":"# Set to restrict the number of concurrent incoming REPLICATION requests per"},{"line_number":165,"context_line":"# device; set to 0 for unlimited requests per device. This can help control"},{"line_number":166,"context_line":"# I/O to each device. This does not override replication_concurrency described"},{"line_number":167,"context_line":"# above, so you may need to adjust both parameters depending on your hardware"}],"source_content_type":"application/octet-stream","patch_set":8,"id":"3f4b6375_cf2987e6","line":164,"range":{"start_line":164,"start_character":52,"end_line":164,"end_character":63},"updated":"2017-10-24 12:42:27.000000000","message":"SSYNC","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"cdefe898131a477bb0f9ad054d2cc5f3c63fa756","unresolved":false,"context_lines":[{"line_number":161,"context_line":"# object replicator when configured to use ssync."},{"line_number":162,"context_line":"# replication_concurrency \u003d 4"},{"line_number":163,"context_line":"#"},{"line_number":164,"context_line":"# Set to restrict the number of concurrent incoming REPLICATION requests per"},{"line_number":165,"context_line":"# device; set to 0 for unlimited requests per device. This can help control"},{"line_number":166,"context_line":"# I/O to each device. This does not override replication_concurrency described"},{"line_number":167,"context_line":"# above, so you may need to adjust both parameters depending on your hardware"}],"source_content_type":"application/octet-stream","patch_set":8,"id":"3f4b6375_e1d20f00","line":164,"range":{"start_line":164,"start_character":52,"end_line":164,"end_character":63},"in_reply_to":"3f4b6375_cf2987e6","updated":"2017-10-24 15:23:47.000000000","message":"Done","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"61df7a269071e74bb632b8ea20cd8f48bb9b2357","unresolved":false,"context_lines":[{"line_number":166,"context_line":"# I/O to each device. This does not override replication_concurrency described"},{"line_number":167,"context_line":"# above, so you may need to adjust both parameters depending on your hardware"},{"line_number":168,"context_line":"# or network capacity."},{"line_number":169,"context_line":"# replication_concurrency_per_device \u003d 1"},{"line_number":170,"context_line":"#"},{"line_number":171,"context_line":"# Number of seconds to wait for an existing replication device lock before"},{"line_number":172,"context_line":"# giving up."}],"source_content_type":"application/octet-stream","patch_set":11,"id":"3f4b6375_03f505ed","line":169,"updated":"2017-10-25 21:07:46.000000000","message":"What happens if this is negative? Oh, I see I already +2\u0027ed some follow-up :P","commit_id":"e199192caefef068b5bf57da8b878e0bc82e3453"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4672467f1f04c0797984f703ae119ca35e6bfbef","unresolved":false,"context_lines":[{"line_number":166,"context_line":"# I/O to each device. This does not override replication_concurrency described"},{"line_number":167,"context_line":"# above, so you may need to adjust both parameters depending on your hardware"},{"line_number":168,"context_line":"# or network capacity."},{"line_number":169,"context_line":"# replication_concurrency_per_device \u003d 1"},{"line_number":170,"context_line":"#"},{"line_number":171,"context_line":"# Number of seconds to wait for an existing replication device lock before"},{"line_number":172,"context_line":"# giving up."}],"source_content_type":"application/octet-stream","patch_set":11,"id":"3f4b6375_e32d3a95","line":169,"in_reply_to":"3f4b6375_03f505ed","updated":"2017-10-26 09:18:52.000000000","message":"Ideally I\u0027d like us to have a config_whole_number_value method similar to [1]. There\u0027s a few places where I\u0027m sure we\u0027d benefit from that. It\u0027s the kind of constraints checking that oslo config would have I expect.\n\n[1] https://github.com/openstack/swift/blob/3bccdd554e2fd17a0857da533e217fcb16730b39/swift/common/utils.py#L371-L383","commit_id":"e199192caefef068b5bf57da8b878e0bc82e3453"}],"swift/common/utils.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"785ed83ef80c0a3a453fb39725bfe414badf0740","unresolved":false,"context_lines":[{"line_number":2265,"context_line":"                    sleep(sleep_time)"},{"line_number":2266,"context_line":"                    time_slept +\u003d sleep_time"},{"line_number":2267,"context_line":"                    continue  # \"while True\" loop"},{"line_number":2268,"context_line":"                break  # \"while True\" loop"},{"line_number":2269,"context_line":"        yield True"},{"line_number":2270,"context_line":"    finally:"},{"line_number":2271,"context_line":"        for fd in fds:"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a30ddce_cf74159e","line":2268,"updated":"2017-03-08 00:05:59.000000000","message":"normally when I find myself stuck in this pattern it\u0027s a strong signal it\u0027s time for a method extraction:\n\n    diff --git a/swift/common/utils.py b/swift/common/utils.py\n    index f661318..5615515 100644\n    --- a/swift/common/utils.py\n    +++ b/swift/common/utils.py\n    @@ -2253,6 +2253,17 @@ def get_zero_indexed_base_string(base, index):\n         return return_string\n     \n     \n    +def _get_any_lock(fds):\n    +    for fd in fds:\n    +        try:\n    +            fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)\n    +            return True\n    +        except IOError as err:\n    +            if err.errno !\u003d errno.EAGAIN:\n    +                raise\n    +    return False\n    +\n    +\n     @contextmanager\n     def lock_path(directory, timeout\u003d10, timeout_class\u003dNone, limit\u003d1):\n         \"\"\"\n    @@ -2285,20 +2296,13 @@ def lock_path(directory, timeout\u003d10, timeout_class\u003dNone, limit\u003d1):\n         try:\n             with timeout_class(timeout, lockpath):\n                 while True:\n    -                for fd in fds:\n    -                    try:\n    -                        fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)\n    -                        break  # \"for fd\" loop\n    -                    except IOError as err:\n    -                        if err.errno !\u003d errno.EAGAIN:\n    -                            raise\n    -                else:\n    -                    if time_slept \u003e slowdown_at:\n    -                        sleep_time \u003d slower_sleep_time\n    -                    sleep(sleep_time)\n    -                    time_slept +\u003d sleep_time\n    -                    continue  # \"while True\" loop\n    -                break  # \"while True\" loop\n    +                got_lock \u003d _get_any_lock(fds)\n    +                if got_lock:\n    +                    break\n    +                if time_slept \u003e slowdown_at:\n    +                    sleep_time \u003d slower_sleep_time\n    +                sleep(sleep_time)\n    +                time_slept +\u003d sleep_time\n             yield True\n         finally:\n             for fd in fds:","commit_id":"5050693ec40e1eebaf1c0d00066b37474d290b0d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"50b0c19716a785101928de33ea08c2166bccaf9b","unresolved":false,"context_lines":[{"line_number":2250,"context_line":"                   + HASH_PATH_SUFFIX).hexdigest()"},{"line_number":2251,"context_line":""},{"line_number":2252,"context_line":""},{"line_number":2253,"context_line":"def get_zero_indexed_base_string(base, index):"},{"line_number":2254,"context_line":"    \"\"\""},{"line_number":2255,"context_line":"    This allows the caller to make a list of things with indexes, where the"},{"line_number":2256,"context_line":"    first item (zero indexed) is just the bare base string, and subsequent"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_9ac4eb92","line":2253,"range":{"start_line":2253,"start_character":4,"end_line":2253,"end_character":32},"updated":"2017-10-24 12:42:27.000000000","message":"nit: the \u0027zero\u0027 part of the method name doesn\u0027t make sense to me - the method returns an indexed string, the index for zero being a special case.","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"50b0c19716a785101928de33ea08c2166bccaf9b","unresolved":false,"context_lines":[{"line_number":2256,"context_line":"    first item (zero indexed) is just the bare base string, and subsequent"},{"line_number":2257,"context_line":"    indexes are appended \u0027-1\u0027, \u0027-2\u0027, etc."},{"line_number":2258,"context_line":""},{"line_number":2259,"context_line":"    i.e."},{"line_number":2260,"context_line":""},{"line_number":2261,"context_line":"    lock, 0 \u003d\u003e lock"},{"line_number":2262,"context_line":"    lock, 1 \u003d\u003e lock-1"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_0f5aff81","line":2259,"range":{"start_line":2259,"start_character":4,"end_line":2259,"end_character":8},"updated":"2017-10-24 12:42:27.000000000","message":"should probably be \u0027e.g.\u0027","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"cdefe898131a477bb0f9ad054d2cc5f3c63fa756","unresolved":false,"context_lines":[{"line_number":2256,"context_line":"    first item (zero indexed) is just the bare base string, and subsequent"},{"line_number":2257,"context_line":"    indexes are appended \u0027-1\u0027, \u0027-2\u0027, etc."},{"line_number":2258,"context_line":""},{"line_number":2259,"context_line":"    i.e."},{"line_number":2260,"context_line":""},{"line_number":2261,"context_line":"    lock, 0 \u003d\u003e lock"},{"line_number":2262,"context_line":"    lock, 1 \u003d\u003e lock-1"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_a1d8971d","line":2259,"range":{"start_line":2259,"start_character":4,"end_line":2259,"end_character":8},"in_reply_to":"3f4b6375_0f5aff81","updated":"2017-10-24 15:23:47.000000000","message":"Done","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"50b0c19716a785101928de33ea08c2166bccaf9b","unresolved":false,"context_lines":[{"line_number":2262,"context_line":"    lock, 1 \u003d\u003e lock-1"},{"line_number":2263,"context_line":"    lock, 2 \u003d\u003e lock-2"},{"line_number":2264,"context_line":""},{"line_number":2265,"context_line":"    :param base: a string, the base string, when index is 0 (or None) this is"},{"line_number":2266,"context_line":"                 the identity function."},{"line_number":2267,"context_line":"    :param index: a digit, typically an integer (or None), for values greater"},{"line_number":2268,"context_line":"                  than 0 this digit is appended to the base string separated by"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_2fcedb2d","line":2265,"range":{"start_line":2265,"start_character":42,"end_line":2265,"end_character":43},"updated":"2017-10-24 12:42:27.000000000","message":";","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"cdefe898131a477bb0f9ad054d2cc5f3c63fa756","unresolved":false,"context_lines":[{"line_number":2262,"context_line":"    lock, 1 \u003d\u003e lock-1"},{"line_number":2263,"context_line":"    lock, 2 \u003d\u003e lock-2"},{"line_number":2264,"context_line":""},{"line_number":2265,"context_line":"    :param base: a string, the base string, when index is 0 (or None) this is"},{"line_number":2266,"context_line":"                 the identity function."},{"line_number":2267,"context_line":"    :param index: a digit, typically an integer (or None), for values greater"},{"line_number":2268,"context_line":"                  than 0 this digit is appended to the base string separated by"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_81d59be7","line":2265,"range":{"start_line":2265,"start_character":42,"end_line":2265,"end_character":43},"in_reply_to":"3f4b6375_2fcedb2d","updated":"2017-10-24 15:23:47.000000000","message":"Done","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"50b0c19716a785101928de33ea08c2166bccaf9b","unresolved":false,"context_lines":[{"line_number":2268,"context_line":"                  than 0 this digit is appended to the base string separated by"},{"line_number":2269,"context_line":"                  a hyphen."},{"line_number":2270,"context_line":""},{"line_number":2271,"context_line":"    This helper function is also how object storage policy indexed resources"},{"line_number":2272,"context_line":"    are enumerated, e.g."},{"line_number":2273,"context_line":""},{"line_number":2274,"context_line":"    object.ring.gz"},{"line_number":2275,"context_line":"    object-1.ring.gz"},{"line_number":2276,"context_line":"    object-2.ring.gz"},{"line_number":2277,"context_line":"    \"\"\""},{"line_number":2278,"context_line":"    if index \u003d\u003d 0 or index is None:"},{"line_number":2279,"context_line":"        return_string \u003d base"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_0fe8bf79","line":2276,"range":{"start_line":2271,"start_character":4,"end_line":2276,"end_character":20},"updated":"2017-10-24 12:42:27.000000000","message":"param definitions usually come last in the docstring, although sphinx seems happy for them not to be.\n\nI\u0027m not sure this text adds much to the examples above, plus the example values here (object-1.ring.gz) are not values of this function.","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"cdefe898131a477bb0f9ad054d2cc5f3c63fa756","unresolved":false,"context_lines":[{"line_number":2268,"context_line":"                  than 0 this digit is appended to the base string separated by"},{"line_number":2269,"context_line":"                  a hyphen."},{"line_number":2270,"context_line":""},{"line_number":2271,"context_line":"    This helper function is also how object storage policy indexed resources"},{"line_number":2272,"context_line":"    are enumerated, e.g."},{"line_number":2273,"context_line":""},{"line_number":2274,"context_line":"    object.ring.gz"},{"line_number":2275,"context_line":"    object-1.ring.gz"},{"line_number":2276,"context_line":"    object-2.ring.gz"},{"line_number":2277,"context_line":"    \"\"\""},{"line_number":2278,"context_line":"    if index \u003d\u003d 0 or index is None:"},{"line_number":2279,"context_line":"        return_string \u003d base"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_61085f91","line":2276,"range":{"start_line":2271,"start_character":4,"end_line":2276,"end_character":20},"in_reply_to":"3f4b6375_0fe8bf79","updated":"2017-10-24 15:23:47.000000000","message":"Done","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"50b0c19716a785101928de33ea08c2166bccaf9b","unresolved":false,"context_lines":[{"line_number":2275,"context_line":"    object-1.ring.gz"},{"line_number":2276,"context_line":"    object-2.ring.gz"},{"line_number":2277,"context_line":"    \"\"\""},{"line_number":2278,"context_line":"    if index \u003d\u003d 0 or index is None:"},{"line_number":2279,"context_line":"        return_string \u003d base"},{"line_number":2280,"context_line":"    else:"},{"line_number":2281,"context_line":"        return_string \u003d base + \"-%d\" % int(index)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_9a206b4a","line":2278,"range":{"start_line":2278,"start_character":4,"end_line":2278,"end_character":34},"updated":"2017-10-24 12:42:27.000000000","message":"nit: if index \u003d \u00270\u0027 we get back base-0 - now this method is in utils might be worth tightening up to require an int value","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"50b0c19716a785101928de33ea08c2166bccaf9b","unresolved":false,"context_lines":[{"line_number":2310,"context_line":"        lock cannot be granted within the timeout. Will be"},{"line_number":2311,"context_line":"        constructed as timeout_class(timeout, lockpath). Default:"},{"line_number":2312,"context_line":"        LockTimeout"},{"line_number":2313,"context_line":"    \"\"\""},{"line_number":2314,"context_line":"    if timeout_class is None:"},{"line_number":2315,"context_line":"        timeout_class \u003d swift.common.exceptions.LockTimeout"},{"line_number":2316,"context_line":"    mkdirs(directory)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_5a1673f3","line":2313,"range":{"start_line":2313,"start_character":4,"end_line":2313,"end_character":7},"updated":"2017-10-24 12:42:27.000000000","message":"param limit missing","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"50b0c19716a785101928de33ea08c2166bccaf9b","unresolved":false,"context_lines":[{"line_number":2317,"context_line":"    lockpath \u003d \u0027%s/.lock\u0027 % directory"},{"line_number":2318,"context_line":"    fds \u003d [os.open(get_zero_indexed_base_string(lockpath, i),"},{"line_number":2319,"context_line":"                   os.O_WRONLY | os.O_CREAT)"},{"line_number":2320,"context_line":"           for i in range(limit)]"},{"line_number":2321,"context_line":"    sleep_time \u003d 0.01"},{"line_number":2322,"context_line":"    slower_sleep_time \u003d max(timeout * 0.01, sleep_time)"},{"line_number":2323,"context_line":"    slowdown_at \u003d timeout * 0.01"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_1aa8fb8a","line":2320,"range":{"start_line":2320,"start_character":26,"end_line":2320,"end_character":31},"updated":"2017-10-24 12:42:27.000000000","message":"might be worth forcing *min* limit to 1","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bbc99b58153848e031f6f9e84b5de5ca8419be24","unresolved":false,"context_lines":[{"line_number":2280,"context_line":"                   + HASH_PATH_SUFFIX).hexdigest()"},{"line_number":2281,"context_line":""},{"line_number":2282,"context_line":""},{"line_number":2283,"context_line":"def get_zero_indexed_base_string(base, index):"},{"line_number":2284,"context_line":"    \"\"\""},{"line_number":2285,"context_line":"    This allows the caller to make a list of things with indexes, where the"},{"line_number":2286,"context_line":"    first item (zero indexed) is just the bare base string, and subsequent"}],"source_content_type":"text/x-python","patch_set":11,"id":"3f4b6375_43f65d65","line":2283,"updated":"2017-10-25 21:26:38.000000000","message":"OK... so this is useful in that we can preserve existing locks in a rolling-upgrade sort of a way? So if there\u0027s one process that has some old value of N (say, 1, because it used the old config option) and you push out a new config with a value of M (\u003e N -- 2, say), new processes get to take advantage of the new increased limit immediately.\n\nWhat about if you\u0027re *decreasing* the limit? I guess you need to wait for *all* the old processes to restart to know that it took effect?\n\nOr am I missing the point entirely?","commit_id":"e199192caefef068b5bf57da8b878e0bc82e3453"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4672467f1f04c0797984f703ae119ca35e6bfbef","unresolved":false,"context_lines":[{"line_number":2280,"context_line":"                   + HASH_PATH_SUFFIX).hexdigest()"},{"line_number":2281,"context_line":""},{"line_number":2282,"context_line":""},{"line_number":2283,"context_line":"def get_zero_indexed_base_string(base, index):"},{"line_number":2284,"context_line":"    \"\"\""},{"line_number":2285,"context_line":"    This allows the caller to make a list of things with indexes, where the"},{"line_number":2286,"context_line":"    first item (zero indexed) is just the bare base string, and subsequent"}],"source_content_type":"text/x-python","patch_set":11,"id":"3f4b6375_03d5f643","line":2283,"in_reply_to":"3f4b6375_43f65d65","updated":"2017-10-26 09:18:52.000000000","message":"That\u0027s how I understand it. Also, the fact that a new process is using a larger limit does not benefit older processes.\n\nNothing is enforcing a mutually respected limit on locks across processes or even callers that choose to use different limits. I tried to articulate something useful to tht effect here:\nhttps://review.openstack.org/#/c/514682/3/swift/common/utils.py","commit_id":"e199192caefef068b5bf57da8b878e0bc82e3453"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"61df7a269071e74bb632b8ea20cd8f48bb9b2357","unresolved":false,"context_lines":[{"line_number":2360,"context_line":"        yield True"},{"line_number":2361,"context_line":"    finally:"},{"line_number":2362,"context_line":"        for fd in fds:"},{"line_number":2363,"context_line":"            os.close(fd)"},{"line_number":2364,"context_line":""},{"line_number":2365,"context_line":""},{"line_number":2366,"context_line":"@contextmanager"}],"source_content_type":"text/x-python","patch_set":11,"id":"3f4b6375_d127b6c9","line":2363,"updated":"2017-10-25 21:07:46.000000000","message":"The \"equivalent code\" listed at https://docs.python.org/2/library/os.html#os.closerange makes me wonder if this should be\n\n for fd in fds:\n     try:\n         os.close(fd)\n     except OSError:\n         pass\n\nI\u0027m not sure it matters, though?","commit_id":"e199192caefef068b5bf57da8b878e0bc82e3453"}],"swift/obj/diskfile.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2c9a8d66618e1f1bce5097b0379cdb73c16245d","unresolved":false,"context_lines":[{"line_number":563,"context_line":"            if config_true_value(replication_one_per_device):"},{"line_number":564,"context_line":"                self.replication_concurrency_per_device \u003d 1"},{"line_number":565,"context_line":"            else:"},{"line_number":566,"context_line":"                self.replication_concurrency_per_device \u003d 0"},{"line_number":567,"context_line":"        self.replication_lock_timeout \u003d int(conf.get("},{"line_number":568,"context_line":"            \u0027replication_lock_timeout\u0027, 15))"},{"line_number":569,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"ba2be162_d8dc9275","line":566,"updated":"2017-03-02 19:53:00.000000000","message":"this looks about right","commit_id":"16e02692cbebe1a5538cce67fbe90ceee06a6734"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d2c9a8d66618e1f1bce5097b0379cdb73c16245d","unresolved":false,"context_lines":[{"line_number":1147,"context_line":"                            except IOError as err:"},{"line_number":1148,"context_line":"                                if err.errno !\u003d errno.EAGAIN:"},{"line_number":1149,"context_line":"                                    raise"},{"line_number":1150,"context_line":"                    sleep(0.01)"},{"line_number":1151,"context_line":"        else:"},{"line_number":1152,"context_line":"            yield True"},{"line_number":1153,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"ba2be162_f80156b0","line":1150,"updated":"2017-03-02 19:53:00.000000000","message":"I was somehow thinking we could leverage something like the Semaphore infrastructure.\n\nit looks like this is inlining the lock_path stuff but with support for multiple locks.  I think it would be better for this logic to be in an externally testable utility function.","commit_id":"16e02692cbebe1a5538cce67fbe90ceee06a6734"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"785ed83ef80c0a3a453fb39725bfe414badf0740","unresolved":false,"context_lines":[{"line_number":586,"context_line":"            self.logger.warn(\u0027Option DEFAULT/replication_one_per_device is \u0027"},{"line_number":587,"context_line":"                             \u0027deprecated and will be removed in a future \u0027"},{"line_number":588,"context_line":"                             \u0027version. Update your configuration to use option\u0027"},{"line_number":589,"context_line":"                             \u0027 DEFAULT/replication_concurrency_per_device.\u0027)"},{"line_number":590,"context_line":"            if config_true_value(replication_one_per_device):"},{"line_number":591,"context_line":"                self.replication_concurrency_per_device \u003d 1"},{"line_number":592,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a30ddce_8fba1d22","line":589,"updated":"2017-03-08 00:05:59.000000000","message":"I\u0027m +1 on this for the deprecation strategy","commit_id":"5050693ec40e1eebaf1c0d00066b37474d290b0d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"50b0c19716a785101928de33ea08c2166bccaf9b","unresolved":false,"context_lines":[{"line_number":628,"context_line":"        replication_one_per_device \u003d conf.get(\u0027replication_one_per_device\u0027)"},{"line_number":629,"context_line":"        if replication_concurrency_per_device is None \\"},{"line_number":630,"context_line":"                and replication_one_per_device is not None:"},{"line_number":631,"context_line":"            self.logger.warning(\u0027Option DEFAULT/replication_one_per_device is \u0027"},{"line_number":632,"context_line":"                                \u0027deprecated and will be removed in a future \u0027"},{"line_number":633,"context_line":"                                \u0027version. Update your configuration to use \u0027"},{"line_number":634,"context_line":"                                \u0027option \u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_0ce8cd79","line":631,"range":{"start_line":631,"start_character":40,"end_line":631,"end_character":48},"updated":"2017-10-24 12:42:27.000000000","message":"delete \u0027DEFAULT/\u0027 ?\n\nI\u0027m not sure why the DEFAULT/ prefix is here - this option is not defined in the DEFAULT section, and I don\u0027t think we generally try to denote the section of that an option belongs to where we have other deprecation warnings.","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"cdefe898131a477bb0f9ad054d2cc5f3c63fa756","unresolved":false,"context_lines":[{"line_number":628,"context_line":"        replication_one_per_device \u003d conf.get(\u0027replication_one_per_device\u0027)"},{"line_number":629,"context_line":"        if replication_concurrency_per_device is None \\"},{"line_number":630,"context_line":"                and replication_one_per_device is not None:"},{"line_number":631,"context_line":"            self.logger.warning(\u0027Option DEFAULT/replication_one_per_device is \u0027"},{"line_number":632,"context_line":"                                \u0027deprecated and will be removed in a future \u0027"},{"line_number":633,"context_line":"                                \u0027version. Update your configuration to use \u0027"},{"line_number":634,"context_line":"                                \u0027option \u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_c1f8337c","line":631,"range":{"start_line":631,"start_character":40,"end_line":631,"end_character":48},"in_reply_to":"3f4b6375_0ce8cd79","updated":"2017-10-24 15:23:47.000000000","message":"Done","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"50b0c19716a785101928de33ea08c2166bccaf9b","unresolved":false,"context_lines":[{"line_number":638,"context_line":"            else:"},{"line_number":639,"context_line":"                replication_concurrency_per_device \u003d 0"},{"line_number":640,"context_line":"        elif replication_one_per_device is not None:"},{"line_number":641,"context_line":"            self.logger.warning(\u0027Option DEFAULT/replication_one_per_device \u0027"},{"line_number":642,"context_line":"                                \u0027ignored as \u0027"},{"line_number":643,"context_line":"                                \u0027DEFAULT/replication_concurrency_per_device \u0027"},{"line_number":644,"context_line":"                                \u0027is defined\u0027)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_ecec5190","line":641,"range":{"start_line":641,"start_character":40,"end_line":641,"end_character":48},"updated":"2017-10-24 12:42:27.000000000","message":"ditto","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"cdefe898131a477bb0f9ad054d2cc5f3c63fa756","unresolved":false,"context_lines":[{"line_number":638,"context_line":"            else:"},{"line_number":639,"context_line":"                replication_concurrency_per_device \u003d 0"},{"line_number":640,"context_line":"        elif replication_one_per_device is not None:"},{"line_number":641,"context_line":"            self.logger.warning(\u0027Option DEFAULT/replication_one_per_device \u0027"},{"line_number":642,"context_line":"                                \u0027ignored as \u0027"},{"line_number":643,"context_line":"                                \u0027DEFAULT/replication_concurrency_per_device \u0027"},{"line_number":644,"context_line":"                                \u0027is defined\u0027)"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_a1f1b797","line":641,"range":{"start_line":641,"start_character":40,"end_line":641,"end_character":48},"in_reply_to":"3f4b6375_ecec5190","updated":"2017-10-24 15:23:47.000000000","message":"Done","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"beffabbb5d9b6735ffb8209de14c29e7384f843b","unresolved":false,"context_lines":[{"line_number":645,"context_line":"            self.replication_concurrency_per_device \u003d 1"},{"line_number":646,"context_line":"        else:"},{"line_number":647,"context_line":"            self.replication_concurrency_per_device \u003d int("},{"line_number":648,"context_line":"                replication_concurrency_per_device)"},{"line_number":649,"context_line":"        self.replication_lock_timeout \u003d int(conf.get("},{"line_number":650,"context_line":"            \u0027replication_lock_timeout\u0027, 15))"},{"line_number":651,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"3f4b6375_c4e38f33","line":648,"updated":"2017-10-25 06:09:02.000000000","message":"Maybe it\u0027s just me, but this took we a while to grok, and its because of the difference between `self.replication_concurrency_per_device` and `replication_concurrency_per_device`.\n\nNOTE: the self.\n\nWhich I overlooked on the first reading. It\u0027s good and works, but my brain took a while to properly pattern match. I wonder if a smaller or simply different local variable could have been used.\n\nBut this isn\u0027t even a NIT, cause this is great, just a word of warning for other reviewers :) Or a failure for my simple brain :P","commit_id":"e199192caefef068b5bf57da8b878e0bc82e3453"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4672467f1f04c0797984f703ae119ca35e6bfbef","unresolved":false,"context_lines":[{"line_number":645,"context_line":"            self.replication_concurrency_per_device \u003d 1"},{"line_number":646,"context_line":"        else:"},{"line_number":647,"context_line":"            self.replication_concurrency_per_device \u003d int("},{"line_number":648,"context_line":"                replication_concurrency_per_device)"},{"line_number":649,"context_line":"        self.replication_lock_timeout \u003d int(conf.get("},{"line_number":650,"context_line":"            \u0027replication_lock_timeout\u0027, 15))"},{"line_number":651,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"3f4b6375_c326be68","line":648,"in_reply_to":"3f4b6375_23a48107","updated":"2017-10-26 09:18:52.000000000","message":"I had fun reformatting the deployment guide to handle the length of this option :) Strictly it is used for ssync, so ssync_concurrency_per_device would work but I suspect ops think more about replication as a \u0027thing\u0027  than ssync.","commit_id":"e199192caefef068b5bf57da8b878e0bc82e3453"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"61df7a269071e74bb632b8ea20cd8f48bb9b2357","unresolved":false,"context_lines":[{"line_number":645,"context_line":"            self.replication_concurrency_per_device \u003d 1"},{"line_number":646,"context_line":"        else:"},{"line_number":647,"context_line":"            self.replication_concurrency_per_device \u003d int("},{"line_number":648,"context_line":"                replication_concurrency_per_device)"},{"line_number":649,"context_line":"        self.replication_lock_timeout \u003d int(conf.get("},{"line_number":650,"context_line":"            \u0027replication_lock_timeout\u0027, 15))"},{"line_number":651,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"3f4b6375_23a48107","line":648,"in_reply_to":"3f4b6375_c4e38f33","updated":"2017-10-25 21:07:46.000000000","message":"I\u0027d be in favor of something shorter, I mostly get\n\n replicat..._per_device\n\nout of the two config-value names and they all kinda run together. Since we never use replication_one_per_device outside of this block, maybe it\u0027d even be safe to just call it legacy_config_value or something to be completely different? Maybe that\u0027s too disconnected from the original value for other\u0027s tastes.\n\nI\u0027m pretty sure this is all correct as-is, though, so like you I\u0027m not really knocking it.","commit_id":"e199192caefef068b5bf57da8b878e0bc82e3453"}],"test/probe/test_replication_servers_working.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"785ed83ef80c0a3a453fb39725bfe414badf0740","unresolved":false,"context_lines":[{"line_number":27,"context_line":"from swift.common.utils import readconf"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"EXCLUDE_FILES \u003d [\u0027hashes.pkl\u0027, \u0027hashes.invalid\u0027,"},{"line_number":30,"context_line":"                 \u0027.lock-0\u0027, \u0027.lock-1\u0027, \u0027.lock-2\u0027, \u0027.lock-3\u0027]"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"def collect_info(path_list):"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a30ddce_cf9b35c8","line":30,"updated":"2017-03-08 00:05:59.000000000","message":"probably just need to convert this a regex sort of pattern - I think these lock files will show up for all of whatever concurrency the developer has configured.","commit_id":"5050693ec40e1eebaf1c0d00066b37474d290b0d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bbc99b58153848e031f6f9e84b5de5ca8419be24","unresolved":false,"context_lines":[{"line_number":27,"context_line":"from test.probe.common import ReplProbeTest"},{"line_number":28,"context_line":"from swift.common.utils import readconf"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"EXCLUDE_FILES \u003d re.compile(\u0027^(hashes\\.(pkl|invalid)|lock(-\\d+)?)$\u0027)"},{"line_number":31,"context_line":""},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"def collect_info(path_list):"}],"source_content_type":"text/x-python","patch_set":11,"id":"3f4b6375_03486584","line":30,"range":{"start_line":30,"start_character":36,"end_line":30,"end_character":37},"updated":"2017-10-25 21:26:38.000000000","message":"Oh, good:\n\n \u003e\u003e\u003e \u0027\\.\u0027\n \u0027\\\\.\u0027","commit_id":"e199192caefef068b5bf57da8b878e0bc82e3453"}],"test/unit/common/test_utils.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"50b0c19716a785101928de33ea08c2166bccaf9b","unresolved":false,"context_lines":[{"line_number":937,"context_line":"            with utils.lock_path(tmpdir, 0.1):"},{"line_number":938,"context_line":"                exc \u003d None"},{"line_number":939,"context_line":"                success \u003d False"},{"line_number":940,"context_line":"                try:"},{"line_number":941,"context_line":"                    with utils.lock_path(tmpdir, 0.1):"},{"line_number":942,"context_line":"                        success \u003d True"},{"line_number":943,"context_line":"                except LockTimeout as err:"},{"line_number":944,"context_line":"                    exc \u003d err"},{"line_number":945,"context_line":"                self.assertTrue(exc is not None)"},{"line_number":946,"context_line":"                self.assertTrue(not success)"},{"line_number":947,"context_line":""},{"line_number":948,"context_line":"            # 2 locks with limit\u003d2 must succeed"},{"line_number":949,"context_line":"            with utils.lock_path(tmpdir, 0.1, limit\u003d2):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_da1023ab","line":946,"range":{"start_line":940,"start_character":16,"end_line":946,"end_character":44},"updated":"2017-10-24 12:42:27.000000000","message":"this can all be handled using with \n\n  self.assertRaises(LockTimeout):\n      with utils.lock_path(tmpdir, 0.1):\n          pass","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bbc99b58153848e031f6f9e84b5de5ca8419be24","unresolved":false,"context_lines":[{"line_number":932,"context_line":"        self.assertEqual(utils.get_zero_indexed_base_string(\u0027something\u0027, 1),"},{"line_number":933,"context_line":"                         \u0027something-1\u0027)"},{"line_number":934,"context_line":"        self.assertRaises(ValueError, utils.get_zero_indexed_base_string,"},{"line_number":935,"context_line":"                          \u0027something\u0027, \u0027not_integer\u0027)"},{"line_number":936,"context_line":""},{"line_number":937,"context_line":"    def test_lock_path(self):"},{"line_number":938,"context_line":"        tmpdir \u003d mkdtemp()"}],"source_content_type":"text/x-python","patch_set":11,"id":"3f4b6375_e3ce6961","line":935,"updated":"2017-10-25 21:26:38.000000000","message":"What about negative values?\n\n something--1\n\n? *shrug* As long as it\u0027s a unique output I suppose.","commit_id":"e199192caefef068b5bf57da8b878e0bc82e3453"}],"test/unit/obj/test_diskfile.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"785ed83ef80c0a3a453fb39725bfe414badf0740","unresolved":false,"context_lines":[{"line_number":894,"context_line":""},{"line_number":895,"context_line":"    def test_replication_lock_on(self):"},{"line_number":896,"context_line":"        # Double check settings"},{"line_number":897,"context_line":"        self.df_mgr.replication_concurrency_per_device \u003d 1"},{"line_number":898,"context_line":"        self.df_mgr.replication_lock_timeout \u003d 0.1"},{"line_number":899,"context_line":"        dev_path \u003d os.path.join(self.testdir, self.existing_device1)"},{"line_number":900,"context_line":"        with self.df_mgr.replication_lock(self.existing_device1):"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a30ddce_af9b6171","line":897,"updated":"2017-03-08 00:05:59.000000000","message":"I\u0027m all for pushing the majority of tests into the new way - but where are the test\u0027s for the legacy case of df_mgr.replication_one_per_device \u003d True?\n\nyeah I feel like this diff:\n\n    diff --git a/swift/obj/diskfile.py b/swift/obj/diskfile.py\n    index c3b9969..fce3a1b 100644\n    --- a/swift/obj/diskfile.py\n    +++ b/swift/obj/diskfile.py\n    @@ -581,16 +581,6 @@ class BaseDiskFileManager(object):\n             self.reclaim_age \u003d int(conf.get(\u0027reclaim_age\u0027, DEFAULT_RECLAIM_AGE))\n             self.replication_concurrency_per_device \u003d int(\n                 conf.get(\u0027replication_concurrency_per_device\u0027, 1))\n    -        replication_one_per_device \u003d conf.get(\u0027replication_one_per_device\u0027)\n    -        if replication_one_per_device is not None:\n    -            self.logger.warn(\u0027Option DEFAULT/replication_one_per_device is \u0027\n    -                             \u0027deprecated and will be removed in a future \u0027\n    -                             \u0027version. Update your configuration to use option\u0027\n    -                             \u0027 DEFAULT/replication_concurrency_per_device.\u0027)\n    -            if config_true_value(replication_one_per_device):\n    -                self.replication_concurrency_per_device \u003d 1\n    -            else:\n    -                self.replication_concurrency_per_device \u003d 0\n             self.replication_lock_timeout \u003d int(conf.get(\n                 \u0027replication_lock_timeout\u0027, 15))\n     \n\nShould cause\n\n    nosetests swift/test/unit/obj/test_diskfile.py\n\n... to exit non-zero ... but it doesn\u0027t seem to?","commit_id":"5050693ec40e1eebaf1c0d00066b37474d290b0d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"785ed83ef80c0a3a453fb39725bfe414badf0740","unresolved":false,"context_lines":[{"line_number":913,"context_line":""},{"line_number":914,"context_line":"    def test_replication_lock_off(self):"},{"line_number":915,"context_line":"        # Double check settings"},{"line_number":916,"context_line":"        self.df_mgr.replication_concurrency_per_device \u003d 2"},{"line_number":917,"context_line":"        self.df_mgr.replication_lock_timeout \u003d 0.1"},{"line_number":918,"context_line":"        dev_path \u003d os.path.join(self.testdir, self.existing_device1)"},{"line_number":919,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9a30ddce_2f869113","line":916,"updated":"2017-03-08 00:05:59.000000000","message":"I don\u0027t think this configuration really matches the name of the test","commit_id":"5050693ec40e1eebaf1c0d00066b37474d290b0d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"785ed83ef80c0a3a453fb39725bfe414badf0740","unresolved":false,"context_lines":[{"line_number":7609,"context_line":"            # simulate rebalanced part doing post-rsync REPLICATE"},{"line_number":7610,"context_line":"            os.unlink(hashfile_path)"},{"line_number":7611,"context_line":"            part_dir \u003d os.path.dirname(hashfile_path)"},{"line_number":7612,"context_line":"            for i in range(4):"},{"line_number":7613,"context_line":"                try:"},{"line_number":7614,"context_line":"                    os.unlink(os.path.join(part_dir, \u0027.lock-%d\u0027 % i))"},{"line_number":7615,"context_line":"                except OSError as err:"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a30ddce_0f270d65","line":7612,"updated":"2017-03-08 00:05:59.000000000","message":"near as I can tell:\n\nset([dfm.replication_concurrency_per_device for dfm in self.df_router.policy_to_manager.values()]) \u003d\u003d {1,}","commit_id":"5050693ec40e1eebaf1c0d00066b37474d290b0d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"50b0c19716a785101928de33ea08c2166bccaf9b","unresolved":false,"context_lines":[{"line_number":964,"context_line":"        mgr \u003d diskfile.DiskFileManager(conf, FakeLogger())"},{"line_number":965,"context_line":"        self.assertEqual(mgr.replication_concurrency_per_device, 1)"},{"line_number":966,"context_line":""},{"line_number":967,"context_line":"        conf \u003d dict(replication_concurrency_per_device\u003d2, **self.conf)"},{"line_number":968,"context_line":"        mgr \u003d diskfile.DiskFileManager(conf, FakeLogger())"},{"line_number":969,"context_line":"        self.assertEqual(mgr.replication_concurrency_per_device, 2)"},{"line_number":970,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_f5c9b0ab","line":967,"range":{"start_line":967,"start_character":55,"end_line":967,"end_character":56},"updated":"2017-10-24 12:42:27.000000000","message":"the actual conf dict read from conf files has string values","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"cdefe898131a477bb0f9ad054d2cc5f3c63fa756","unresolved":false,"context_lines":[{"line_number":964,"context_line":"        mgr \u003d diskfile.DiskFileManager(conf, FakeLogger())"},{"line_number":965,"context_line":"        self.assertEqual(mgr.replication_concurrency_per_device, 1)"},{"line_number":966,"context_line":""},{"line_number":967,"context_line":"        conf \u003d dict(replication_concurrency_per_device\u003d2, **self.conf)"},{"line_number":968,"context_line":"        mgr \u003d diskfile.DiskFileManager(conf, FakeLogger())"},{"line_number":969,"context_line":"        self.assertEqual(mgr.replication_concurrency_per_device, 2)"},{"line_number":970,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_e140cfa7","line":967,"range":{"start_line":967,"start_character":55,"end_line":967,"end_character":56},"in_reply_to":"3f4b6375_f5c9b0ab","updated":"2017-10-24 15:23:47.000000000","message":"Done","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"50b0c19716a785101928de33ea08c2166bccaf9b","unresolved":false,"context_lines":[{"line_number":1002,"context_line":""},{"line_number":1003,"context_line":"    def test_replication_lock_on(self):"},{"line_number":1004,"context_line":"        # Double check settings"},{"line_number":1005,"context_line":"        self.df_mgr.replication_concurrency_per_device \u003d 1"},{"line_number":1006,"context_line":"        self.df_mgr.replication_lock_timeout \u003d 0.1"},{"line_number":1007,"context_line":"        dev_path \u003d os.path.join(self.testdir, self.existing_device)"},{"line_number":1008,"context_line":"        with self.df_mgr.replication_lock(self.existing_device):"}],"source_content_type":"text/x-python","patch_set":8,"id":"3f4b6375_15320c60","line":1005,"range":{"start_line":1005,"start_character":32,"end_line":1005,"end_character":44},"updated":"2017-10-24 12:42:27.000000000","message":"ok. we have checked backwards compatibility above i.e. the deprecated option sets concurrency to 0 or 1, so now it\u0027s ok to change these follwoing tests to check only the new option.","commit_id":"e63aa35200529838d8fdf8f477e0cc9ef143aeeb"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"bbc99b58153848e031f6f9e84b5de5ca8419be24","unresolved":false,"context_lines":[{"line_number":1057,"context_line":"            self.assertTrue(lock_exc is None)"},{"line_number":1058,"context_line":"            self.assertTrue(exc is not None)"},{"line_number":1059,"context_line":""},{"line_number":1060,"context_line":"        # 3 locks must succeed"},{"line_number":1061,"context_line":"        with self.df_mgr.replication_lock(self.existing_device):"},{"line_number":1062,"context_line":"            with self.df_mgr.replication_lock(self.existing_device):"},{"line_number":1063,"context_line":"                lock_exc \u003d None"}],"source_content_type":"text/x-python","patch_set":11,"id":"3f4b6375_03df453a","line":1060,"updated":"2017-10-25 21:26:38.000000000","message":"Three is basically unlimited, right? ;-)\n\nI wonder if it\u0027d be better to see that we *never* call lock_path?","commit_id":"e199192caefef068b5bf57da8b878e0bc82e3453"}],"test/unit/obj/test_server.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"785ed83ef80c0a3a453fb39725bfe414badf0740","unresolved":false,"context_lines":[{"line_number":6988,"context_line":""},{"line_number":6989,"context_line":"    def find_files(self):"},{"line_number":6990,"context_line":"        ignore_files \u003d {\u0027.lock-0\u0027, \u0027.lock-1\u0027,\u0027.lock-2\u0027,\u0027.lock-3\u0027,"},{"line_number":6991,"context_line":"                        \u0027hashes.invalid\u0027}"},{"line_number":6992,"context_line":"        found_files \u003d defaultdict(list)"},{"line_number":6993,"context_line":"        for root, dirs, files in os.walk(self.devices):"},{"line_number":6994,"context_line":"            for filename in files:"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a30ddce_6fe32906","line":6991,"updated":"2017-03-08 00:05:59.000000000","message":"yeah, pretty sure most of those locks won\u0027t exist in his context","commit_id":"5050693ec40e1eebaf1c0d00066b37474d290b0d"}],"test/unit/obj/test_ssync.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"785ed83ef80c0a3a453fb39725bfe414badf0740","unresolved":false,"context_lines":[{"line_number":53,"context_line":"        conf \u003d {"},{"line_number":54,"context_line":"            \u0027devices\u0027: self.rx_testdir,"},{"line_number":55,"context_line":"            \u0027mount_check\u0027: \u0027false\u0027,"},{"line_number":56,"context_line":"            \u0027replication_concurrency_per_device\u0027: \u00270\u0027,"},{"line_number":57,"context_line":"            \u0027log_requests\u0027: \u0027false\u0027}"},{"line_number":58,"context_line":"        self.rx_logger \u003d debug_logger()"},{"line_number":59,"context_line":"        self.rx_controller \u003d server.ObjectController(conf, self.rx_logger)"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a30ddce_8fc93d7b","line":56,"updated":"2017-03-08 00:05:59.000000000","message":"well still need some kind of test coverage on the legacy configuration case - that\u0027s a good portion of the new code in this change?","commit_id":"5050693ec40e1eebaf1c0d00066b37474d290b0d"}],"test/unit/obj/test_ssync_receiver.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"785ed83ef80c0a3a453fb39725bfe414badf0740","unresolved":false,"context_lines":[{"line_number":53,"context_line":"        self.conf \u003d {"},{"line_number":54,"context_line":"            \u0027devices\u0027: self.testdir,"},{"line_number":55,"context_line":"            \u0027mount_check\u0027: \u0027false\u0027,"},{"line_number":56,"context_line":"            \u0027replication_concurrency_per_device\u0027: \u00270\u0027,"},{"line_number":57,"context_line":"            \u0027log_requests\u0027: \u0027false\u0027}"},{"line_number":58,"context_line":"        utils.mkdirs(os.path.join(self.testdir, \u0027device\u0027, \u0027partition\u0027))"},{"line_number":59,"context_line":"        self.controller \u003d server.ObjectController(self.conf)"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a30ddce_ef92b94a","line":56,"updated":"2017-03-08 00:05:59.000000000","message":"probably fine, again, I can\u0027t find the coverage on the legacy behavior.","commit_id":"5050693ec40e1eebaf1c0d00066b37474d290b0d"}]}
