)]}'
{"neutron/agent/l3/extensions/qos/fip.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"6eb84dcd13685d69d49ecfea23b8597737d5ca96","unresolved":false,"context_lines":[{"line_number":112,"context_line":"    def initialize(self, connection, driver_type):"},{"line_number":113,"context_line":"        \"\"\"Initialize agent extension.\"\"\""},{"line_number":114,"context_line":"        self.resource_rpc \u003d resources_rpc.ResourcesPullRpcApi()"},{"line_number":115,"context_line":"        self.fip_qos_map \u003d RouterFipRateLimitMaps(\"fip-qos-cache\")"},{"line_number":116,"context_line":"        self._register_rpc_consumers()"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    def _handle_notification(self, context, resource_type,"}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_7291374e","line":115,"range":{"start_line":115,"start_character":50,"end_line":115,"end_character":65},"updated":"2019-04-29 13:23:20.000000000","message":"IMO, the whole change you have made for FipQosAgentExtension and RateLimitMaps is not needed. You are instantiating this class with a constant. Instead of modifying all methods using this constant in a class variable, you can use directly this constant.","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"4d5f9d6e0a823df1ea638df302060eb56a4ca477","unresolved":false,"context_lines":[{"line_number":112,"context_line":"    def initialize(self, connection, driver_type):"},{"line_number":113,"context_line":"        \"\"\"Initialize agent extension.\"\"\""},{"line_number":114,"context_line":"        self.resource_rpc \u003d resources_rpc.ResourcesPullRpcApi()"},{"line_number":115,"context_line":"        self.fip_qos_map \u003d RouterFipRateLimitMaps(\"fip-qos-cache\")"},{"line_number":116,"context_line":"        self._register_rpc_consumers()"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    def _handle_notification(self, context, resource_type,"}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_607aaff1","line":115,"range":{"start_line":115,"start_character":50,"end_line":115,"end_character":65},"in_reply_to":"ffb9cba7_32d41fbd","updated":"2019-04-30 14:10:50.000000000","message":"Instead of using RouterFipRateLimitMaps with this initialization variable, you can use a constant defined in this class, avoiding to redefine all those functions.","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"9e125d8f6d67f2005f100b11aa8e94f0f832caa0","unresolved":false,"context_lines":[{"line_number":112,"context_line":"    def initialize(self, connection, driver_type):"},{"line_number":113,"context_line":"        \"\"\"Initialize agent extension.\"\"\""},{"line_number":114,"context_line":"        self.resource_rpc \u003d resources_rpc.ResourcesPullRpcApi()"},{"line_number":115,"context_line":"        self.fip_qos_map \u003d RouterFipRateLimitMaps(\"fip-qos-cache\")"},{"line_number":116,"context_line":"        self._register_rpc_consumers()"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    def _handle_notification(self, context, resource_type,"}],"source_content_type":"text/x-python","patch_set":4,"id":"dfbec78f_ceaf9392","line":115,"range":{"start_line":115,"start_character":50,"end_line":115,"end_character":65},"in_reply_to":"ffb9cba7_607aaff1","updated":"2019-05-05 02:19:27.000000000","message":"Done","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"5c27ac5b8d71d8290c471f8a4d85cbdb8e2cbe9c","unresolved":false,"context_lines":[{"line_number":112,"context_line":"    def initialize(self, connection, driver_type):"},{"line_number":113,"context_line":"        \"\"\"Initialize agent extension.\"\"\""},{"line_number":114,"context_line":"        self.resource_rpc \u003d resources_rpc.ResourcesPullRpcApi()"},{"line_number":115,"context_line":"        self.fip_qos_map \u003d RouterFipRateLimitMaps(\"fip-qos-cache\")"},{"line_number":116,"context_line":"        self._register_rpc_consumers()"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"    def _handle_notification(self, context, resource_type,"}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_32d41fbd","line":115,"range":{"start_line":115,"start_character":50,"end_line":115,"end_character":65},"in_reply_to":"ffb9cba7_7291374e","updated":"2019-04-29 14:05:36.000000000","message":"Sorry, I do not get your point.\nThe base RateLimitMaps will be used for gatway-ip-qos and fip-qos both. Each should have its own cache lock, so here I give each one a independent lock name.","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"06b364b1d9db77e2d076e0d556431a29ecd19476","unresolved":false,"context_lines":[{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    def find_fip_router_id(self, fip):"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"        @lockutils.synchronized(self.lock_name)"},{"line_number":62,"context_line":"        def _find_fip_router_id():"},{"line_number":63,"context_line":"            for router_id, ips in self.router_floating_ips.items():"},{"line_number":64,"context_line":"                if fip in ips:"}],"source_content_type":"text/x-python","patch_set":9,"id":"bfb3d3c7_ec30b1a1","line":61,"updated":"2019-05-30 07:49:48.000000000","message":"sorry for maybe dummy question but why here You are using lockutils.synchronized and in some places coordination.synchronized instead?","commit_id":"ddc25c25ddc0dafe9f0a8b7a86c20634b162edec"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"f2b9952f5ded630bf44e446789cba4e429a88808","unresolved":false,"context_lines":[{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    def find_fip_router_id(self, fip):"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":"        @lockutils.synchronized(self.lock_name)"},{"line_number":62,"context_line":"        def _find_fip_router_id():"},{"line_number":63,"context_line":"            for router_id, ips in self.router_floating_ips.items():"},{"line_number":64,"context_line":"                if fip in ips:"}],"source_content_type":"text/x-python","patch_set":9,"id":"bfb3d3c7_b9d8b6ee","line":61,"in_reply_to":"bfb3d3c7_ec30b1a1","updated":"2019-05-30 10:44:33.000000000","message":"It does not accept class attribute self.lock_name, the following is not available:\n    @wrapper(self.lock_name)\n    def func(self, args):","commit_id":"ddc25c25ddc0dafe9f0a8b7a86c20634b162edec"}],"neutron/agent/l3/extensions/qos/gateway_ip.py":[{"author":{"_account_id":27654,"name":"Hongbin Lu","email":"kira034@163.com","username":"hongbin.lu"},"change_message_id":"53b45355532ff46102031cfd6b0ef3366e787d2c","unresolved":false,"context_lines":[{"line_number":118,"context_line":""},{"line_number":119,"context_line":"        self._handle_router_gateway_rate_limit(context, router_info)"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    @coordination.synchronized(\u0027qos-gateway-ip-{router_info.router_id}\u0027)"},{"line_number":122,"context_line":"    def _empty_router_gateway_rate_limits(self, router_info, tc_wrapper):"},{"line_number":123,"context_line":"        self.gateway_ip_qos_map.clean_by_resource(router_info.router_id)"},{"line_number":124,"context_line":"        for ip in router_info.qos_gateway_ips:"}],"source_content_type":"text/x-python","patch_set":6,"id":"dfbec78f_2865d0e1","line":121,"range":{"start_line":121,"start_character":5,"end_line":121,"end_character":17},"updated":"2019-05-08 16:54:21.000000000","message":"I think you can achieve the same by:\n\n    \n    def _empty_router_gateway_rate_limits(self, router_info, tc_wrapper):\n        @utils.synchronized(\u0027qos-gateway-ip-\u0027 + router_info.router_id)\n\t    def empty_router_gateway_rate_limits():\n            self.gateway_ip_qos_map.clean_by_resource(router_info.router_id)\n            for ip in router_info.qos_gateway_ips:\n                for direction in constants.VALID_DIRECTIONS:\n                    tc_wrapper.clear_ip_rate_limit(direction, ip)\n            router_info.qos_gateway_ips.clear()\n\n        empty_router_gateway_rate_limits()\n\nIf yes, we don\u0027t need the module \u0027coordination\u0027 which looks quite complex and hard to maintain.\n\nThe same applies to the rest of this patch.","commit_id":"d74d14c10cf9e097bab19b40722b6da9b600aecb"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"40d006ed7654640a43ecda09224c63532b1d8ac5","unresolved":false,"context_lines":[{"line_number":118,"context_line":""},{"line_number":119,"context_line":"        self._handle_router_gateway_rate_limit(context, router_info)"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    @coordination.synchronized(\u0027qos-gateway-ip-{router_info.router_id}\u0027)"},{"line_number":122,"context_line":"    def _empty_router_gateway_rate_limits(self, router_info, tc_wrapper):"},{"line_number":123,"context_line":"        self.gateway_ip_qos_map.clean_by_resource(router_info.router_id)"},{"line_number":124,"context_line":"        for ip in router_info.qos_gateway_ips:"}],"source_content_type":"text/x-python","patch_set":6,"id":"dfbec78f_f7dc7575","line":121,"range":{"start_line":121,"start_character":5,"end_line":121,"end_character":17},"in_reply_to":"dfbec78f_2865d0e1","updated":"2019-05-08 22:54:11.000000000","message":"This generic coordination mechanism is necessary because there are many other places where need such refactor.\nI see why you think this approach is complex, because we now need to support py27, so there are two copied function. But for that \"coordination.synchronized\", I\u0027d like to say it is clear and easy to read and maintain. BTW, most of that function is inspired by cinder:\nhttps://github.com/openstack/cinder/blob/master/cinder/coordination.py#L94. So I wonder maybe one day such mechanism can be adeded to the oslo_concurrency.","commit_id":"d74d14c10cf9e097bab19b40722b6da9b600aecb"}],"neutron/common/coordination.py":[{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"06b364b1d9db77e2d076e0d556431a29ecd19476","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#"},{"line_number":2,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":3,"context_line":"#    not use this file except in compliance with the License. You may obtain"},{"line_number":4,"context_line":"#    a copy of the License at"}],"source_content_type":"text/x-python","patch_set":9,"id":"bfb3d3c7_2c01e9af","line":1,"updated":"2019-05-30 07:49:48.000000000","message":"I think that this patch can be split into 2 separate patches. One with this new coordination module and second with usage of it in neutron code.","commit_id":"ddc25c25ddc0dafe9f0a8b7a86c20634b162edec"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"f2b9952f5ded630bf44e446789cba4e429a88808","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#"},{"line_number":2,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":3,"context_line":"#    not use this file except in compliance with the License. You may obtain"},{"line_number":4,"context_line":"#    a copy of the License at"}],"source_content_type":"text/x-python","patch_set":9,"id":"bfb3d3c7_3952863c","line":1,"in_reply_to":"bfb3d3c7_2c01e9af","updated":"2019-05-30 10:44:33.000000000","message":"I know you may want one patch to do one thing, right?","commit_id":"ddc25c25ddc0dafe9f0a8b7a86c20634b162edec"}],"neutron/coordination.py":[{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"24bffa9996cc94987855538aa2bdbf8b0054501f","unresolved":false,"context_lines":[{"line_number":60,"context_line":""},{"line_number":61,"context_line":"    @decorator.decorator"},{"line_number":62,"context_line":"    def _synchronized(f, *a, **k):"},{"line_number":63,"context_line":"        sig \u003d inspect.signature(f).bind(*a, **k)"},{"line_number":64,"context_line":"        sig.apply_defaults()"},{"line_number":65,"context_line":"        call_args \u003d sig.arguments"},{"line_number":66,"context_line":"        call_args[\u0027f_name\u0027] \u003d f.__name__"}],"source_content_type":"text/x-python","patch_set":3,"id":"ffb9cba7_37f73462","line":63,"range":{"start_line":63,"start_character":8,"end_line":63,"end_character":48},"updated":"2019-04-29 08:25:26.000000000","message":"neutron/coordination.py:63:20: W1505: \u001b[35mUsing deprecated method getcallargs()\u001b[0m (\u001b[35mdeprecated-method\u001b[0m)\n\nFor \"inspect.getcallargs\", \u0027noqa\u0027 and \u0027tox.ini [flake8] ignore\u003dW1505\u0027 do not work.\n\nFor py27, no such inspect.signature.\n\nSo maybe we need to add a copy function \u0027getcallargs\u0027 for py2, and call inspect.signature for py3 only.","commit_id":"1bc4f1a32b172bf7ed3cb40fdc51f0b09bb80196"},{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"73fb0a4ee021eb81afed164493f99fe50707945d","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#"},{"line_number":2,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":3,"context_line":"#    not use this file except in compliance with the License. You may obtain"},{"line_number":4,"context_line":"#    a copy of the License at"}],"source_content_type":"text/x-python","patch_set":4,"id":"dfbec78f_cb71c5e2","line":1,"updated":"2019-05-05 00:36:42.000000000","message":"IMO better place for whole this module would be neutron/common/ if we really need it","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"9e125d8f6d67f2005f100b11aa8e94f0f832caa0","unresolved":false,"context_lines":[{"line_number":1,"context_line":"#"},{"line_number":2,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":3,"context_line":"#    not use this file except in compliance with the License. You may obtain"},{"line_number":4,"context_line":"#    a copy of the License at"}],"source_content_type":"text/x-python","patch_set":4,"id":"dfbec78f_6e40e736","line":1,"in_reply_to":"dfbec78f_cb71c5e2","updated":"2019-05-05 02:19:27.000000000","message":"Done","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"6eb84dcd13685d69d49ecfea23b8597737d5ca96","unresolved":false,"context_lines":[{"line_number":26,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"def getargspec(func):"},{"line_number":30,"context_line":"    \"\"\"Get the names and default values of a function\u0027s arguments."},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    A tuple of four things is returned: (args, varargs, varkw, defaults)."}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_bd8785b5","line":29,"updated":"2019-04-29 13:23:20.000000000","message":"I don\u0027t understand. Why are you implementing a deprecated function? Why can\u0027t you use inspect.signature()?","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"7aaca3827e178b434e09d9b0ce5847e2f28f5e2c","unresolved":false,"context_lines":[{"line_number":26,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"def getargspec(func):"},{"line_number":30,"context_line":"    \"\"\"Get the names and default values of a function\u0027s arguments."},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    A tuple of four things is returned: (args, varargs, varkw, defaults)."}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_d3db37ea","line":29,"in_reply_to":"ffb9cba7_20fd976d","updated":"2019-04-30 15:19:17.000000000","message":"\u0027getargspec\u0027 is marked deprecated too, then pep8 pylint check can not pass.","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"5c27ac5b8d71d8290c471f8a4d85cbdb8e2cbe9c","unresolved":false,"context_lines":[{"line_number":26,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"def getargspec(func):"},{"line_number":30,"context_line":"    \"\"\"Get the names and default values of a function\u0027s arguments."},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    A tuple of four things is returned: (args, varargs, varkw, defaults)."}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_f2d9a7f2","line":29,"in_reply_to":"ffb9cba7_bd8785b5","updated":"2019-04-29 14:05:36.000000000","message":"py27 does not have such function.","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"4d5f9d6e0a823df1ea638df302060eb56a4ca477","unresolved":false,"context_lines":[{"line_number":26,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"def getargspec(func):"},{"line_number":30,"context_line":"    \"\"\"Get the names and default values of a function\u0027s arguments."},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"    A tuple of four things is returned: (args, varargs, varkw, defaults)."}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_20fd976d","line":29,"in_reply_to":"ffb9cba7_f2d9a7f2","updated":"2019-04-30 14:10:50.000000000","message":"But you have inspect.getargspec in py27","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"6eb84dcd13685d69d49ecfea23b8597737d5ca96","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    return inspect.ArgSpec(args, varargs, varkw, func.func_defaults)"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"def getcallargs(func, *positional, **named):"},{"line_number":47,"context_line":"    \"\"\"This is a copy of the inspect.getcallargs."},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    Since \"# noqa\" and does not work on directly calling inspect.getcallargs."}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_3dc5d5f1","line":46,"updated":"2019-04-29 13:23:20.000000000","message":"This is a python core function. Why do you need it? I see you use this function only for Py2, but this function is still available in py2.7\n\nhttps://docs.python.org/2/library/inspect.html","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"7aaca3827e178b434e09d9b0ce5847e2f28f5e2c","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    return inspect.ArgSpec(args, varargs, varkw, func.func_defaults)"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"def getcallargs(func, *positional, **named):"},{"line_number":47,"context_line":"    \"\"\"This is a copy of the inspect.getcallargs."},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    Since \"# noqa\" and does not work on directly calling inspect.getcallargs."}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_f3d8bbef","line":46,"in_reply_to":"ffb9cba7_003df329","updated":"2019-04-30 15:19:17.000000000","message":"\u0027getargspec\u0027 is marked deprecated too, then pep8 pylint check can not pass.","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"5c27ac5b8d71d8290c471f8a4d85cbdb8e2cbe9c","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    return inspect.ArgSpec(args, varargs, varkw, func.func_defaults)"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"def getcallargs(func, *positional, **named):"},{"line_number":47,"context_line":"    \"\"\"This is a copy of the inspect.getcallargs."},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    Since \"# noqa\" and does not work on directly calling inspect.getcallargs."}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_f202073d","line":46,"in_reply_to":"ffb9cba7_3dc5d5f1","updated":"2019-04-29 14:05:36.000000000","message":"Pep8 is now running on py3.6, that\n\"\"\"\ncall_args \u003d inspect.getcallargs(f, *a, **k)  # noqa\n\"\"\" can never pass the pylint check.\n\nIf use the new style \"inspect.signature\", py27 functional test could not pass, since this function does not exist in py27.\n\nWe have a conflict now...\n\nAnd please see the doc next line 47-50.","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"4d5f9d6e0a823df1ea638df302060eb56a4ca477","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    return inspect.ArgSpec(args, varargs, varkw, func.func_defaults)"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"def getcallargs(func, *positional, **named):"},{"line_number":47,"context_line":"    \"\"\"This is a copy of the inspect.getcallargs."},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    Since \"# noqa\" and does not work on directly calling inspect.getcallargs."}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_003df329","line":46,"in_reply_to":"ffb9cba7_f202073d","updated":"2019-04-30 14:10:50.000000000","message":"We still support py27.\n\ninspect.getargspec() is present in py27","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"7470ab804282b65d8a64d440e2fdf77cd8f0ce36","unresolved":false,"context_lines":[{"line_number":147,"context_line":"    return arg2value"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"def synchronized(lock_name):"},{"line_number":151,"context_line":"    \"\"\"Synchronization decorator."},{"line_number":152,"context_line":""},{"line_number":153,"context_line":"    :param str lock_name: Lock name."}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_65540f00","line":150,"range":{"start_line":150,"start_character":4,"end_line":150,"end_character":16},"updated":"2019-04-29 14:10:51.000000000","message":"Most of this function is inspired by cinder:\nhttps://github.com/openstack/cinder/blob/master/cinder/coordination.py#L94","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"6eb84dcd13685d69d49ecfea23b8597737d5ca96","unresolved":false,"context_lines":[{"line_number":193,"context_line":"            sig \u003d inspect.signature(f).bind(*a, **k)"},{"line_number":194,"context_line":"            sig.apply_defaults()"},{"line_number":195,"context_line":"            call_args \u003d sig.arguments"},{"line_number":196,"context_line":"        call_args[\u0027f_name\u0027] \u003d f.__name__"},{"line_number":197,"context_line":"        lock_format_name \u003d lock_name.format(**call_args)"},{"line_number":198,"context_line":"        t1 \u003d timeutils.now()"},{"line_number":199,"context_line":"        t2 \u003d None"}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_12079b1a","line":196,"range":{"start_line":196,"start_character":30,"end_line":196,"end_character":40},"updated":"2019-04-29 13:23:20.000000000","message":"oslo_utils.reflection.get_callable_name(f)","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"f4a32ed590102f4e2784f7f7f0507bb41b5f293c","unresolved":false,"context_lines":[{"line_number":193,"context_line":"            sig \u003d inspect.signature(f).bind(*a, **k)"},{"line_number":194,"context_line":"            sig.apply_defaults()"},{"line_number":195,"context_line":"            call_args \u003d sig.arguments"},{"line_number":196,"context_line":"        call_args[\u0027f_name\u0027] \u003d f.__name__"},{"line_number":197,"context_line":"        lock_format_name \u003d lock_name.format(**call_args)"},{"line_number":198,"context_line":"        t1 \u003d timeutils.now()"},{"line_number":199,"context_line":"        t2 \u003d None"}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_1c72497c","line":196,"range":{"start_line":196,"start_character":30,"end_line":196,"end_character":40},"in_reply_to":"ffb9cba7_12079b1a","updated":"2019-04-30 01:29:25.000000000","message":"After some tests, this function will  get a really long name with package path, for instance:\nneutron.agent.l3.extensions.qos.gateway_ip.RouterGatewayIPQosAgentExtension._empty_router_gateway_rate_limits\n\nit is not necessary, we only need the function name here.\n\nTest prints:\n(reflection.get_callable_name(f): \u0027, \u0027neutron.agent.l3.extensions.qos.gateway_ip._empty_router_gateway_rate_limits\u0027)\n    (\u0027f.__name__: \u0027, \u0027_empty_router_gateway_rate_limits\u0027)","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"6eb84dcd13685d69d49ecfea23b8597737d5ca96","unresolved":false,"context_lines":[{"line_number":194,"context_line":"            sig.apply_defaults()"},{"line_number":195,"context_line":"            call_args \u003d sig.arguments"},{"line_number":196,"context_line":"        call_args[\u0027f_name\u0027] \u003d f.__name__"},{"line_number":197,"context_line":"        lock_format_name \u003d lock_name.format(**call_args)"},{"line_number":198,"context_line":"        t1 \u003d timeutils.now()"},{"line_number":199,"context_line":"        t2 \u003d None"},{"line_number":200,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_728b776d","line":197,"range":{"start_line":197,"start_character":27,"end_line":197,"end_character":56},"updated":"2019-04-29 13:23:20.000000000","message":"What is happening if the named placeholder doesn\u0027t exist in the call_args?","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"5c8324d64a465a3f2ab100ef8368088a63bc35b8","unresolved":false,"context_lines":[{"line_number":194,"context_line":"            sig.apply_defaults()"},{"line_number":195,"context_line":"            call_args \u003d sig.arguments"},{"line_number":196,"context_line":"        call_args[\u0027f_name\u0027] \u003d f.__name__"},{"line_number":197,"context_line":"        lock_format_name \u003d lock_name.format(**call_args)"},{"line_number":198,"context_line":"        t1 \u003d timeutils.now()"},{"line_number":199,"context_line":"        t2 \u003d None"},{"line_number":200,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_6369671f","line":197,"range":{"start_line":197,"start_character":27,"end_line":197,"end_character":56},"in_reply_to":"ffb9cba7_52c0b3e1","updated":"2019-04-29 17:07:56.000000000","message":"The thing I don\u0027t like about this is it\u0027s duplicated lockutils.synchronized, and when that code changes we lose the benefit of that.  If all you\u0027re trying to do is make a unique lock name can\u0027t you do that in a wrapper that also then uses the lockutils code directly?","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"acd603afeecabf3aa1745231a882356298c9b997","unresolved":false,"context_lines":[{"line_number":194,"context_line":"            sig.apply_defaults()"},{"line_number":195,"context_line":"            call_args \u003d sig.arguments"},{"line_number":196,"context_line":"        call_args[\u0027f_name\u0027] \u003d f.__name__"},{"line_number":197,"context_line":"        lock_format_name \u003d lock_name.format(**call_args)"},{"line_number":198,"context_line":"        t1 \u003d timeutils.now()"},{"line_number":199,"context_line":"        t2 \u003d None"},{"line_number":200,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_59ba136e","line":197,"range":{"start_line":197,"start_character":27,"end_line":197,"end_character":56},"in_reply_to":"ffb9cba7_6369671f","updated":"2019-04-30 00:10:05.000000000","message":"No, it can not achieve this:\n@synchronized(\u0027{f_name}-{resource.id}-{snap[name]}\u0027)\ndef foo(self, resource, snap):\n\nA general synchronization mechanism can construct dynamic lock names from functions and their parameter values.","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"5c27ac5b8d71d8290c471f8a4d85cbdb8e2cbe9c","unresolved":false,"context_lines":[{"line_number":194,"context_line":"            sig.apply_defaults()"},{"line_number":195,"context_line":"            call_args \u003d sig.arguments"},{"line_number":196,"context_line":"        call_args[\u0027f_name\u0027] \u003d f.__name__"},{"line_number":197,"context_line":"        lock_format_name \u003d lock_name.format(**call_args)"},{"line_number":198,"context_line":"        t1 \u003d timeutils.now()"},{"line_number":199,"context_line":"        t2 \u003d None"},{"line_number":200,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":4,"id":"ffb9cba7_52c0b3e1","line":197,"range":{"start_line":197,"start_character":27,"end_line":197,"end_character":56},"in_reply_to":"ffb9cba7_728b776d","updated":"2019-04-29 14:05:36.000000000","message":"It should not happen...","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"}],"releasenotes/notes/Minimizing-lock-granularity-8bc2f893d9389cf8.yaml":[{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"d47d1044e42828c6dda574a22b83740a1bf3eaa7","unresolved":false,"context_lines":[{"line_number":5,"context_line":"    which will result multiply increase processing time of"},{"line_number":6,"context_line":"    resources, please see bug"},{"line_number":7,"context_line":"    `1824911 \u003chttps://bugs.launchpad.net/neutron/+bug/1824911\u003e`_."},{"line_number":8,"context_line":"    Leverage the coordination lock to the resource prcessing"},{"line_number":9,"context_line":"    and notification thread functions to minimize the lock"},{"line_number":10,"context_line":"    granularity."}],"source_content_type":"text/x-yaml","patch_set":13,"id":"9fb8cfa7_fa1ddfbd","line":8,"range":{"start_line":8,"start_character":51,"end_line":8,"end_character":60},"updated":"2019-06-27 08:47:30.000000000","message":"processing","commit_id":"62d8d55fc785b0f3a25e479b9c63e962370c3e0b"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"eba2fabf56eef50fbe1c66377de8f0861f6358f8","unresolved":false,"context_lines":[{"line_number":5,"context_line":"    which will result multiply increase processing time of"},{"line_number":6,"context_line":"    resources, please see bug"},{"line_number":7,"context_line":"    `1824911 \u003chttps://bugs.launchpad.net/neutron/+bug/1824911\u003e`_."},{"line_number":8,"context_line":"    Leverage the coordination lock to the resource prcessing"},{"line_number":9,"context_line":"    and notification thread functions to minimize the lock"},{"line_number":10,"context_line":"    granularity."}],"source_content_type":"text/x-yaml","patch_set":13,"id":"9fb8cfa7_2a6f5ffd","line":8,"range":{"start_line":8,"start_character":51,"end_line":8,"end_character":60},"in_reply_to":"9fb8cfa7_fa1ddfbd","updated":"2019-07-02 15:16:08.000000000","message":"Done","commit_id":"62d8d55fc785b0f3a25e479b9c63e962370c3e0b"},{"author":{"_account_id":11975,"name":"Slawek Kaplonski","email":"skaplons@redhat.com","username":"slaweq"},"change_message_id":"d47d1044e42828c6dda574a22b83740a1bf3eaa7","unresolved":false,"context_lines":[{"line_number":5,"context_line":"    which will result multiply increase processing time of"},{"line_number":6,"context_line":"    resources, please see bug"},{"line_number":7,"context_line":"    `1824911 \u003chttps://bugs.launchpad.net/neutron/+bug/1824911\u003e`_."},{"line_number":8,"context_line":"    Leverage the coordination lock to the resource prcessing"},{"line_number":9,"context_line":"    and notification thread functions to minimize the lock"},{"line_number":10,"context_line":"    granularity."}],"source_content_type":"text/x-yaml","patch_set":13,"id":"9fb8cfa7_9a84e3d4","line":10,"range":{"start_line":8,"start_character":4,"end_line":10,"end_character":16},"updated":"2019-06-27 08:47:30.000000000","message":"IMO this part of note should be enough. The previous paragraph isn\u0027t IMO necessary in release note.","commit_id":"62d8d55fc785b0f3a25e479b9c63e962370c3e0b"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"eba2fabf56eef50fbe1c66377de8f0861f6358f8","unresolved":false,"context_lines":[{"line_number":5,"context_line":"    which will result multiply increase processing time of"},{"line_number":6,"context_line":"    resources, please see bug"},{"line_number":7,"context_line":"    `1824911 \u003chttps://bugs.launchpad.net/neutron/+bug/1824911\u003e`_."},{"line_number":8,"context_line":"    Leverage the coordination lock to the resource prcessing"},{"line_number":9,"context_line":"    and notification thread functions to minimize the lock"},{"line_number":10,"context_line":"    granularity."}],"source_content_type":"text/x-yaml","patch_set":13,"id":"9fb8cfa7_8a7d2bb4","line":10,"range":{"start_line":8,"start_character":4,"end_line":10,"end_character":16},"in_reply_to":"9fb8cfa7_9a84e3d4","updated":"2019-07-02 15:16:08.000000000","message":"removed","commit_id":"62d8d55fc785b0f3a25e479b9c63e962370c3e0b"}],"requirements.txt":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"6eb84dcd13685d69d49ecfea23b8597737d5ca96","unresolved":false,"context_lines":[{"line_number":7,"context_line":"PasteDeploy\u003e\u003d1.5.0 # MIT"},{"line_number":8,"context_line":"Routes\u003e\u003d2.3.1 # MIT"},{"line_number":9,"context_line":"debtcollector\u003e\u003d1.2.0 # Apache-2.0"},{"line_number":10,"context_line":"decorator\u003e\u003d3.4.0 # BSD"},{"line_number":11,"context_line":"eventlet!\u003d0.18.3,!\u003d0.20.1,\u003e\u003d0.18.2 # MIT"},{"line_number":12,"context_line":"pecan\u003e\u003d1.3.2 # BSD"},{"line_number":13,"context_line":"httplib2\u003e\u003d0.9.1 # MIT"}],"source_content_type":"text/plain","patch_set":3,"id":"ffb9cba7_0fcf7429","line":10,"range":{"start_line":10,"start_character":0,"end_line":10,"end_character":9},"updated":"2019-04-29 13:23:20.000000000","message":"nit: instead of adding a new dependency, why don\u0027t you use functools.wraps()?","commit_id":"1bc4f1a32b172bf7ed3cb40fdc51f0b09bb80196"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"6eb84dcd13685d69d49ecfea23b8597737d5ca96","unresolved":false,"context_lines":[{"line_number":7,"context_line":"PasteDeploy\u003e\u003d1.5.0 # MIT"},{"line_number":8,"context_line":"Routes\u003e\u003d2.3.1 # MIT"},{"line_number":9,"context_line":"debtcollector\u003e\u003d1.2.0 # Apache-2.0"},{"line_number":10,"context_line":"decorator\u003e\u003d3.4.0 # BSD"},{"line_number":11,"context_line":"eventlet!\u003d0.18.3,!\u003d0.20.1,\u003e\u003d0.18.2 # MIT"},{"line_number":12,"context_line":"pecan\u003e\u003d1.3.2 # BSD"},{"line_number":13,"context_line":"httplib2\u003e\u003d0.9.1 # MIT"}],"source_content_type":"text/plain","patch_set":4,"id":"ffb9cba7_8f57e426","line":10,"range":{"start_line":10,"start_character":0,"end_line":10,"end_character":9},"updated":"2019-04-29 13:23:20.000000000","message":"Do we need to add a new dependency? IMO, you can use @functools.wraps(f)","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"f4a32ed590102f4e2784f7f7f0507bb41b5f293c","unresolved":false,"context_lines":[{"line_number":7,"context_line":"PasteDeploy\u003e\u003d1.5.0 # MIT"},{"line_number":8,"context_line":"Routes\u003e\u003d2.3.1 # MIT"},{"line_number":9,"context_line":"debtcollector\u003e\u003d1.2.0 # Apache-2.0"},{"line_number":10,"context_line":"decorator\u003e\u003d3.4.0 # BSD"},{"line_number":11,"context_line":"eventlet!\u003d0.18.3,!\u003d0.20.1,\u003e\u003d0.18.2 # MIT"},{"line_number":12,"context_line":"pecan\u003e\u003d1.3.2 # BSD"},{"line_number":13,"context_line":"httplib2\u003e\u003d0.9.1 # MIT"}],"source_content_type":"text/plain","patch_set":4,"id":"ffb9cba7_fc4bb527","line":10,"range":{"start_line":10,"start_character":0,"end_line":10,"end_character":9},"in_reply_to":"ffb9cba7_8f57e426","updated":"2019-04-30 01:29:25.000000000","message":"After some tests, @functools.wraps does not work.","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":9531,"name":"liuyulong","display_name":"LIU Yulong","email":"i@liuyulong.me","username":"LIU-Yulong"},"change_message_id":"7aaca3827e178b434e09d9b0ce5847e2f28f5e2c","unresolved":false,"context_lines":[{"line_number":7,"context_line":"PasteDeploy\u003e\u003d1.5.0 # MIT"},{"line_number":8,"context_line":"Routes\u003e\u003d2.3.1 # MIT"},{"line_number":9,"context_line":"debtcollector\u003e\u003d1.2.0 # Apache-2.0"},{"line_number":10,"context_line":"decorator\u003e\u003d3.4.0 # BSD"},{"line_number":11,"context_line":"eventlet!\u003d0.18.3,!\u003d0.20.1,\u003e\u003d0.18.2 # MIT"},{"line_number":12,"context_line":"pecan\u003e\u003d1.3.2 # BSD"},{"line_number":13,"context_line":"httplib2\u003e\u003d0.9.1 # MIT"}],"source_content_type":"text/plain","patch_set":4,"id":"ffb9cba7_73f60b66","line":10,"range":{"start_line":10,"start_character":0,"end_line":10,"end_character":9},"in_reply_to":"ffb9cba7_c08cbbd8","updated":"2019-04-30 15:19:17.000000000","message":"The lock name failed to initialize. It will be empty when use functools.wraps.","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"4d5f9d6e0a823df1ea638df302060eb56a4ca477","unresolved":false,"context_lines":[{"line_number":7,"context_line":"PasteDeploy\u003e\u003d1.5.0 # MIT"},{"line_number":8,"context_line":"Routes\u003e\u003d2.3.1 # MIT"},{"line_number":9,"context_line":"debtcollector\u003e\u003d1.2.0 # Apache-2.0"},{"line_number":10,"context_line":"decorator\u003e\u003d3.4.0 # BSD"},{"line_number":11,"context_line":"eventlet!\u003d0.18.3,!\u003d0.20.1,\u003e\u003d0.18.2 # MIT"},{"line_number":12,"context_line":"pecan\u003e\u003d1.3.2 # BSD"},{"line_number":13,"context_line":"httplib2\u003e\u003d0.9.1 # MIT"}],"source_content_type":"text/plain","patch_set":4,"id":"ffb9cba7_c08cbbd8","line":10,"range":{"start_line":10,"start_character":0,"end_line":10,"end_character":9},"in_reply_to":"ffb9cba7_fc4bb527","updated":"2019-04-30 14:10:50.000000000","message":"But what\u0027s the problem? \"decorator\" is doing the same. Where is this failing? What else do you need? Just to know and to provide help if needed.","commit_id":"20d9fe597e36291dad956e8a7cec2e63d52ec703"}]}
