)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":4694,"name":"Miguel Lavalle","email":"miguel@mlavalle.com","username":"minsel"},"change_message_id":"2fc8ab9f16ced870536c76934aeb01c3c8b18149","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Reimplement wait_until_true in neutron-lib"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"In an effort to move away from neutron.common, reimplement"},{"line_number":10,"context_line":"neutorn.common.utils.wait_until_true in neutron_lib.utils.helpers."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This is a reimplementation, and not a move, since eventlet is not"},{"line_number":13,"context_line":"allowed in neutorn-lib."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"7a77a97e_7e97d747","line":10,"range":{"start_line":10,"start_character":0,"end_line":10,"end_character":7},"updated":"2016-11-17 21:10:57.000000000","message":"neutron","commit_id":"2e7ab09e9980f09594aec369aca2c3527381d8a2"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"20f9fa98f93333d1cfe68b6a7bf30aad2e723ca8","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Reimplement wait_until_true in neutron-lib"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"In an effort to move away from neutron.common, reimplement"},{"line_number":10,"context_line":"neutorn.common.utils.wait_until_true in neutron_lib.utils.helpers."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This is a reimplementation, and not a move, since eventlet is not"},{"line_number":13,"context_line":"allowed in neutorn-lib."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"7a77a97e_d4d19c24","line":10,"range":{"start_line":10,"start_character":0,"end_line":10,"end_character":7},"in_reply_to":"7a77a97e_7e97d747","updated":"2016-11-18 07:37:25.000000000","message":"Will fix.","commit_id":"2e7ab09e9980f09594aec369aca2c3527381d8a2"},{"author":{"_account_id":4694,"name":"Miguel Lavalle","email":"miguel@mlavalle.com","username":"minsel"},"change_message_id":"2fc8ab9f16ced870536c76934aeb01c3c8b18149","unresolved":false,"context_lines":[{"line_number":10,"context_line":"neutorn.common.utils.wait_until_true in neutron_lib.utils.helpers."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This is a reimplementation, and not a move, since eventlet is not"},{"line_number":13,"context_line":"allowed in neutorn-lib."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: Id5a40019c301e117a67c39ceb1e86b1ad8b5edc4"},{"line_number":16,"context_line":"Partial-Bug: 1642167"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"7a77a97e_5e85bb04","line":13,"range":{"start_line":13,"start_character":11,"end_line":13,"end_character":18},"updated":"2016-11-17 21:10:57.000000000","message":"neutron","commit_id":"2e7ab09e9980f09594aec369aca2c3527381d8a2"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"20f9fa98f93333d1cfe68b6a7bf30aad2e723ca8","unresolved":false,"context_lines":[{"line_number":10,"context_line":"neutorn.common.utils.wait_until_true in neutron_lib.utils.helpers."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This is a reimplementation, and not a move, since eventlet is not"},{"line_number":13,"context_line":"allowed in neutorn-lib."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: Id5a40019c301e117a67c39ceb1e86b1ad8b5edc4"},{"line_number":16,"context_line":"Partial-Bug: 1642167"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"7a77a97e_f4ccd88a","line":13,"range":{"start_line":13,"start_character":11,"end_line":13,"end_character":18},"in_reply_to":"7a77a97e_5e85bb04","updated":"2016-11-18 07:37:25.000000000","message":"Will fix.","commit_id":"2e7ab09e9980f09594aec369aca2c3527381d8a2"}],"neutron_lib/eventlet_utils.py":[{"author":{"_account_id":5367,"name":"boden","email":"bodenvmw@gmail.com","username":"boden"},"change_message_id":"140a95e1cb3c6831214b5ae2d42fbd69d74dd304","unresolved":false,"context_lines":[{"line_number":15,"context_line":"from oslo_utils import importutils"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"def eventlet_config():"},{"line_number":19,"context_line":"    eventlet_timeout \u003d importutils.try_import(\u0027eventlet.timeout\u0027)"},{"line_number":20,"context_line":"    if eventlet_timeout:"},{"line_number":21,"context_line":"        helpers.Timeout \u003d eventlet_timeout.Timeout"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a77a97e_de5d4b16","line":21,"range":{"start_line":18,"start_character":0,"end_line":21,"end_character":50},"updated":"2016-11-17 21:03:51.000000000","message":"Why do we want this in its own module?\nCouldn\u0027t we just do this in the helpers.py?\n\n    Timeout \u003d importutils.try_import(\u0027eventlet.timeout\u0027) or Exception","commit_id":"2e7ab09e9980f09594aec369aca2c3527381d8a2"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"20f9fa98f93333d1cfe68b6a7bf30aad2e723ca8","unresolved":false,"context_lines":[{"line_number":15,"context_line":"from oslo_utils import importutils"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"def eventlet_config():"},{"line_number":19,"context_line":"    eventlet_timeout \u003d importutils.try_import(\u0027eventlet.timeout\u0027)"},{"line_number":20,"context_line":"    if eventlet_timeout:"},{"line_number":21,"context_line":"        helpers.Timeout \u003d eventlet_timeout.Timeout"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a77a97e_1476b43d","line":21,"range":{"start_line":18,"start_character":0,"end_line":21,"end_character":50},"in_reply_to":"7a77a97e_de5d4b16","updated":"2016-11-18 07:37:25.000000000","message":"I\u0027ll do something similar:\n eventlet_timeout \u003d importutils.try_import(\u0027eventlet.timeout\u0027)\n if eventlet_timeout:\n     Timeout \u003d eventlet_timeout.Timeout\n else\n     class Timeout(Exception):\n         pass\n\nI still want helpers.Timeout to be a subclass of Exception and not Exception itself, so that it can be specifically mentioned in an \u0027except\u0027 clause.","commit_id":"2e7ab09e9980f09594aec369aca2c3527381d8a2"}],"neutron_lib/utils/helpers.py":[{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"5d9237d45bbcff5062c92cc13e4d9417f89c700f","unresolved":false,"context_lines":[{"line_number":193,"context_line":"    :param exception: Exception class for eventlet.Timeout."},{"line_number":194,"context_line":"    (see doc for eventlet.Timeout for more information)"},{"line_number":195,"context_line":"    \"\"\""},{"line_number":196,"context_line":"    exception \u003d exception or Timeout"},{"line_number":197,"context_line":"    event \u003d threading.Event()"},{"line_number":198,"context_line":"    timer \u003d threading.Timer(timeout, lambda: event.set())"},{"line_number":199,"context_line":"    timer.start()"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a77a97e_7caacd71","line":196,"range":{"start_line":196,"start_character":4,"end_line":196,"end_character":36},"updated":"2016-11-16 15:15:19.000000000","message":"exception \u003d exception or Timeout()","commit_id":"8c0fa102e323b1bd08962fd82701dd9a51608ea3"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"7beedf305d3344cfdd649a1a358e04a846f4b0e5","unresolved":false,"context_lines":[{"line_number":193,"context_line":"    :param exception: Exception class for eventlet.Timeout."},{"line_number":194,"context_line":"    (see doc for eventlet.Timeout for more information)"},{"line_number":195,"context_line":"    \"\"\""},{"line_number":196,"context_line":"    exception \u003d exception or Timeout"},{"line_number":197,"context_line":"    event \u003d threading.Event()"},{"line_number":198,"context_line":"    timer \u003d threading.Timer(timeout, lambda: event.set())"},{"line_number":199,"context_line":"    timer.start()"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a77a97e_f710b6aa","line":196,"range":{"start_line":196,"start_character":4,"end_line":196,"end_character":36},"in_reply_to":"7a77a97e_7caacd71","updated":"2016-11-16 15:34:06.000000000","message":"The eventlet API allows exception to be both a class extending Exception, or an instance of such a class. If it\u0027s a class, it should be instantiated only if it is thrown.\n\nI\u0027ll add the proper conditions to maintain API compatibility as much as possible.","commit_id":"8c0fa102e323b1bd08962fd82701dd9a51608ea3"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"7793d4923fde20796f3e5494f4e49fc1e3fc9d8d","unresolved":false,"context_lines":[{"line_number":195,"context_line":"    \"\"\""},{"line_number":196,"context_line":"    exception \u003d exception or Timeout"},{"line_number":197,"context_line":"    event \u003d threading.Event()"},{"line_number":198,"context_line":"    timer \u003d threading.Timer(timeout, lambda: event.set())"},{"line_number":199,"context_line":"    timer.start()"},{"line_number":200,"context_line":"    try:"},{"line_number":201,"context_line":"        while not predicate():"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a77a97e_1cd0f91e","line":198,"range":{"start_line":198,"start_character":37,"end_line":198,"end_character":56},"updated":"2016-11-16 15:12:11.000000000","message":"I think just \u0027event.set\u0027 is sufficient.","commit_id":"8c0fa102e323b1bd08962fd82701dd9a51608ea3"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"7beedf305d3344cfdd649a1a358e04a846f4b0e5","unresolved":false,"context_lines":[{"line_number":195,"context_line":"    \"\"\""},{"line_number":196,"context_line":"    exception \u003d exception or Timeout"},{"line_number":197,"context_line":"    event \u003d threading.Event()"},{"line_number":198,"context_line":"    timer \u003d threading.Timer(timeout, lambda: event.set())"},{"line_number":199,"context_line":"    timer.start()"},{"line_number":200,"context_line":"    try:"},{"line_number":201,"context_line":"        while not predicate():"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a77a97e_176a92b3","line":198,"range":{"start_line":198,"start_character":37,"end_line":198,"end_character":56},"in_reply_to":"7a77a97e_1cd0f91e","updated":"2016-11-16 15:34:06.000000000","message":"Will fix.","commit_id":"8c0fa102e323b1bd08962fd82701dd9a51608ea3"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"5d9237d45bbcff5062c92cc13e4d9417f89c700f","unresolved":false,"context_lines":[{"line_number":200,"context_line":"    try:"},{"line_number":201,"context_line":"        while not predicate():"},{"line_number":202,"context_line":"            if event.wait(sleep):"},{"line_number":203,"context_line":"                raise exception()"},{"line_number":204,"context_line":"    finally:"},{"line_number":205,"context_line":"        timer.cancel()"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a77a97e_3ca05590","line":203,"range":{"start_line":203,"start_character":16,"end_line":203,"end_character":33},"updated":"2016-11-16 15:15:19.000000000","message":"raise exception","commit_id":"8c0fa102e323b1bd08962fd82701dd9a51608ea3"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"7beedf305d3344cfdd649a1a358e04a846f4b0e5","unresolved":false,"context_lines":[{"line_number":200,"context_line":"    try:"},{"line_number":201,"context_line":"        while not predicate():"},{"line_number":202,"context_line":"            if event.wait(sleep):"},{"line_number":203,"context_line":"                raise exception()"},{"line_number":204,"context_line":"    finally:"},{"line_number":205,"context_line":"        timer.cancel()"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a77a97e_f787d6d4","line":203,"range":{"start_line":203,"start_character":16,"end_line":203,"end_character":33},"in_reply_to":"7a77a97e_3ca05590","updated":"2016-11-16 15:34:06.000000000","message":"Will do as per the discussion on line #196","commit_id":"8c0fa102e323b1bd08962fd82701dd9a51608ea3"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"5d9237d45bbcff5062c92cc13e4d9417f89c700f","unresolved":false,"context_lines":[{"line_number":201,"context_line":"        while not predicate():"},{"line_number":202,"context_line":"            if event.wait(sleep):"},{"line_number":203,"context_line":"                raise exception()"},{"line_number":204,"context_line":"    finally:"},{"line_number":205,"context_line":"        timer.cancel()"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a77a97e_7c464dc0","line":204,"range":{"start_line":204,"start_character":4,"end_line":204,"end_character":11},"updated":"2016-11-16 15:15:19.000000000","message":"So as per docs for cancel(): \"This will only work if the timer is still in its waiting stage.\" If the exception is raised, is timer still in waiting stage?","commit_id":"8c0fa102e323b1bd08962fd82701dd9a51608ea3"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"7beedf305d3344cfdd649a1a358e04a846f4b0e5","unresolved":false,"context_lines":[{"line_number":201,"context_line":"        while not predicate():"},{"line_number":202,"context_line":"            if event.wait(sleep):"},{"line_number":203,"context_line":"                raise exception()"},{"line_number":204,"context_line":"    finally:"},{"line_number":205,"context_line":"        timer.cancel()"}],"source_content_type":"text/x-python","patch_set":1,"id":"7a77a97e_57bb2a27","line":204,"range":{"start_line":204,"start_character":4,"end_line":204,"end_character":11},"in_reply_to":"7a77a97e_7c464dc0","updated":"2016-11-16 15:34:06.000000000","message":"No, but predicate may raise an exception too.","commit_id":"8c0fa102e323b1bd08962fd82701dd9a51608ea3"},{"author":{"_account_id":5367,"name":"boden","email":"bodenvmw@gmail.com","username":"boden"},"change_message_id":"140a95e1cb3c6831214b5ae2d42fbd69d74dd304","unresolved":false,"context_lines":[{"line_number":184,"context_line":"    pass"},{"line_number":185,"context_line":""},{"line_number":186,"context_line":""},{"line_number":187,"context_line":"def wait_until_true(predicate, timeout\u003d60, sleep\u003d1, exception\u003dNone):"},{"line_number":188,"context_line":"    \"\"\"Wait until callable predicate is evaluated as True"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":"    :param predicate: Callable deciding whether waiting should continue."}],"source_content_type":"text/x-python","patch_set":4,"id":"7a77a97e_9e12f355","line":187,"updated":"2016-11-17 21:03:51.000000000","message":"While this is really cool, I\u0027m beginning to question if its the right approach for us as it really seems to add complexity not only in the implementation below, but also W/R/T to how do we properly test, etc.. I\u0027d be tempted to just say for something this small [1] we might just push back on consumers to impl themselves, or just say lets have eventlet in neutron... Not sure we should get into the business of implementing bridge points into eventlet.\n\n\n\n[1] https://github.com/openstack/neutron/blob/master/neutron/common/utils.py#L721","commit_id":"2e7ab09e9980f09594aec369aca2c3527381d8a2"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"6be3b2e9460f9e3e422a347a9565cf32e6765096","unresolved":false,"context_lines":[{"line_number":184,"context_line":"    pass"},{"line_number":185,"context_line":""},{"line_number":186,"context_line":""},{"line_number":187,"context_line":"def wait_until_true(predicate, timeout\u003d60, sleep\u003d1, exception\u003dNone):"},{"line_number":188,"context_line":"    \"\"\"Wait until callable predicate is evaluated as True"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":"    :param predicate: Callable deciding whether waiting should continue."}],"source_content_type":"text/x-python","patch_set":4,"id":"5a74a57a_8403300f","line":187,"in_reply_to":"7a77a97e_7431a859","updated":"2016-11-23 01:23:54.000000000","message":"if you want this into a library and available to all OpenStack projects, a much more suitable library is something like oslo.utils.\n\nBesides the eventlet issue, it seems to me that the footprint caused by this method is so limited outside the neutron\u0027s repo that it\u0027s hard to justify why we\u0027d take on this technical complexity in neutron-lib, when such a method could be beneficial in other repos like Tempest or any repos\u0027 test subtree, for example.\n\n[1] http://codesearch.openstack.org/?q\u003dwait_until_true\u0026i\u003dnope\u0026files\u003d\u0026repos\u003d","commit_id":"2e7ab09e9980f09594aec369aca2c3527381d8a2"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"20f9fa98f93333d1cfe68b6a7bf30aad2e723ca8","unresolved":false,"context_lines":[{"line_number":184,"context_line":"    pass"},{"line_number":185,"context_line":""},{"line_number":186,"context_line":""},{"line_number":187,"context_line":"def wait_until_true(predicate, timeout\u003d60, sleep\u003d1, exception\u003dNone):"},{"line_number":188,"context_line":"    \"\"\"Wait until callable predicate is evaluated as True"},{"line_number":189,"context_line":""},{"line_number":190,"context_line":"    :param predicate: Callable deciding whether waiting should continue."}],"source_content_type":"text/x-python","patch_set":4,"id":"7a77a97e_7431a859","line":187,"in_reply_to":"7a77a97e_9e12f355","updated":"2016-11-18 07:37:25.000000000","message":"If there is a move away from eventlet, this re-implementation will have to be done.\n\nMostly, I re-implemented this method since it is used in Dragonflow (I think only in tests though), and I would rather limit dependency on neutron core only for things that require it (e.g. mechanism drivers, and service).\n\nI would also prefer not to re-write a method that exists in other OpenStack projects, if this method could be placed in a library.","commit_id":"2e7ab09e9980f09594aec369aca2c3527381d8a2"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"a7df5884eef4b487c2e38877efca50a99202dd19","unresolved":false,"context_lines":[{"line_number":206,"context_line":"    try:"},{"line_number":207,"context_line":"        while not predicate():"},{"line_number":208,"context_line":"            if event.wait(sleep):"},{"line_number":209,"context_line":"                if (inspect.isclass(exception) and"},{"line_number":210,"context_line":"                        issubclass(exception, BaseException)):"},{"line_number":211,"context_line":"                    raise exception()"},{"line_number":212,"context_line":"                elif isinstance(exception, BaseException):"},{"line_number":213,"context_line":"                    raise exception"},{"line_number":214,"context_line":"                else:"},{"line_number":215,"context_line":"                    raise TypeError(_LE(\u0027exception must subclass or \u0027"},{"line_number":216,"context_line":"                                        \u0027instantiate BaseException\u0027))"},{"line_number":217,"context_line":"    finally:"},{"line_number":218,"context_line":"        timer.cancel()"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a77a97e_16630643","line":216,"range":{"start_line":209,"start_character":0,"end_line":216,"end_character":69},"updated":"2016-11-18 15:24:08.000000000","message":"This is all Python\u0027s implicit behavior. You don\u0027t need to bother what the \u0027exception\u0027 is. You can raise class or class instance and if it doesn\u0027t inherit from BaseException, you get TypeError.","commit_id":"6d4192715b1d1ca69c1b133fba0f06df0143e3dc"},{"author":{"_account_id":20229,"name":"Omer Anson","email":"omer.anson@toganetworks.com","username":"oanson"},"change_message_id":"0bfca87771c4df4c485f423229aa83124b638d14","unresolved":false,"context_lines":[{"line_number":206,"context_line":"    try:"},{"line_number":207,"context_line":"        while not predicate():"},{"line_number":208,"context_line":"            if event.wait(sleep):"},{"line_number":209,"context_line":"                if (inspect.isclass(exception) and"},{"line_number":210,"context_line":"                        issubclass(exception, BaseException)):"},{"line_number":211,"context_line":"                    raise exception()"},{"line_number":212,"context_line":"                elif isinstance(exception, BaseException):"},{"line_number":213,"context_line":"                    raise exception"},{"line_number":214,"context_line":"                else:"},{"line_number":215,"context_line":"                    raise TypeError(_LE(\u0027exception must subclass or \u0027"},{"line_number":216,"context_line":"                                        \u0027instantiate BaseException\u0027))"},{"line_number":217,"context_line":"    finally:"},{"line_number":218,"context_line":"        timer.cancel()"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a77a97e_c8a1e295","line":216,"range":{"start_line":209,"start_character":0,"end_line":216,"end_character":69},"in_reply_to":"7a77a97e_16630643","updated":"2016-11-18 18:38:38.000000000","message":"Didn\u0027t know that. Everything makes more sense now (including you comment from PS1 which I misunderstood (: ).\n\nWill fix.","commit_id":"6d4192715b1d1ca69c1b133fba0f06df0143e3dc"}]}
