)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":105,"name":"Kyle Mestery","email":"mestery@mestery.com","username":"mestery"},"change_message_id":"4069df4800127aed2d0f0b8ad11c37d536e7c1de","unresolved":false,"context_lines":[{"line_number":7,"context_line":"[WIP] Alternate for Move DHCP updates onto worker thread, coalesce port updates"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Original is here : https://review.openstack.org/#/c/220758/"},{"line_number":10,"context_line":""},{"line_number":11,"context_line":"Change-Id: I304efdccbaed3f4e9dbc3cb7268cc28b2b0baed9"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"fa69d971_0204debd","line":10,"updated":"2016-01-08 14:20:18.000000000","message":"Per the original:\n\nRelated-Bug: #1453350","commit_id":"a625e9b5feeffe14baf137d9114357b811638730"}],"neutron/agent/dhcp/agent.py":[{"author":{"_account_id":19461,"name":"Shaun Crampton","email":"shaun@tigera.io","username":"fasaxc"},"change_message_id":"3a212b09f86d3ddadb477543fe6014e84ed9b960","unresolved":false,"context_lines":[{"line_number":200,"context_line":"    def _periodic_resync_helper(self):"},{"line_number":201,"context_line":"        \"\"\"Resync the dhcp state at the configured interval.\"\"\""},{"line_number":202,"context_line":"        while True:"},{"line_number":203,"context_line":"            eventlet.sleep(self.conf.resync_interval)"},{"line_number":204,"context_line":"            if self.needs_resync_reasons:"},{"line_number":205,"context_line":"                # be careful to avoid a race with additions to list"},{"line_number":206,"context_line":"                # from other threads"}],"source_content_type":"text/x-python","patch_set":11,"id":"ba63e191_7a681af6","line":203,"updated":"2016-01-19 11:30:22.000000000","message":"If we did go down this route, I think this sleep should be converted to a queue or an event to allow the RPC threads to wake up the background thread when they\u0027ve marked a network as dirty.","commit_id":"cce08cbde5edefd7c7a5280bff8f6a8487699766"},{"author":{"_account_id":19461,"name":"Shaun Crampton","email":"shaun@tigera.io","username":"fasaxc"},"change_message_id":"3a212b09f86d3ddadb477543fe6014e84ed9b960","unresolved":false,"context_lines":[{"line_number":213,"context_line":"                              {\"reason\": r, \"network\": net})"},{"line_number":214,"context_line":"                self.sync_state(reasons.keys())"},{"line_number":215,"context_line":"            if self.dirty_networks:"},{"line_number":216,"context_line":"                self._reload_dirty_networks()"},{"line_number":217,"context_line":""},{"line_number":218,"context_line":"    def _mark_dirty_network(self, network_id):"},{"line_number":219,"context_line":"        \"\"\"Looks up the network and marks it as dirty.\"\"\""}],"source_content_type":"text/x-python","patch_set":11,"id":"ba63e191_3aedc28b","line":216,"updated":"2016-01-19 11:30:22.000000000","message":"See my comment on the original review: https://review.openstack.org/#/c/220758/6\n\nI think this may result in an incorrect concurrent access to the cache object in certain circumstances.","commit_id":"cce08cbde5edefd7c7a5280bff8f6a8487699766"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"94138644e9fdbd384e2e9cebf27df7f999da0e15","unresolved":false,"context_lines":[{"line_number":224,"context_line":"            self.dirty_networks.add(network)"},{"line_number":225,"context_line":"        else:"},{"line_number":226,"context_line":"            LOG.debug(\"_mark_dirty_network : network_id is not in cache %s \","},{"line_number":227,"context_line":"                      network_id)"},{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    @utils.synchronized(\u0027dhcp-agent\u0027)"},{"line_number":230,"context_line":"    def _reload_dirty_networks(self):"}],"source_content_type":"text/x-python","patch_set":12,"id":"da0c15f0_5bd55c41","line":227,"range":{"start_line":227,"start_character":32,"end_line":227,"end_character":33},"updated":"2016-03-25 21:28:29.000000000","message":"I think right at the end of this we can use eventlet to spawn a call to _reload_dirty_networks. This will prevent the need to call it during the periodic sync loop and will ensure that the dirty networks are cleaned out as soon as possible.","commit_id":"d86eac90c8b324d996f87326d4617a124c255e29"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"abae0080520ad36e2684373b61a25adee5e6b5ca","unresolved":false,"context_lines":[{"line_number":224,"context_line":"            self.dirty_networks.add(network)"},{"line_number":225,"context_line":"        else:"},{"line_number":226,"context_line":"            LOG.debug(\"_mark_dirty_network : network_id is not in cache %s \","},{"line_number":227,"context_line":"                      network_id)"},{"line_number":228,"context_line":""},{"line_number":229,"context_line":"    @utils.synchronized(\u0027dhcp-agent\u0027)"},{"line_number":230,"context_line":"    def _reload_dirty_networks(self):"}],"source_content_type":"text/x-python","patch_set":12,"id":"ba0121b8_aa7451fd","line":227,"range":{"start_line":227,"start_character":32,"end_line":227,"end_character":33},"in_reply_to":"da0c15f0_5bd55c41","updated":"2016-03-28 21:18:34.000000000","message":"Yes, that should work, I\u0027ll re-spin with that if noone else minds.\n\nI also think we should remove this else as none of the other code in this file ever logs the fact that a network was not in the cache, it just ignores it.","commit_id":"d86eac90c8b324d996f87326d4617a124c255e29"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"858ff4806f9127d7742a5fda858cdfe63925de94","unresolved":false,"context_lines":[{"line_number":213,"context_line":"                              {\"reason\": r, \"network\": net})"},{"line_number":214,"context_line":"                self.sync_state(reasons.keys())"},{"line_number":215,"context_line":""},{"line_number":216,"context_line":"    def _mark_dirty_network(self, network_id):"},{"line_number":217,"context_line":"        \"\"\"Looks up the network and marks it as dirty.\"\"\""},{"line_number":218,"context_line":"        network \u003d self.cache.get_network_by_id(network_id)"},{"line_number":219,"context_line":"        if network:"}],"source_content_type":"text/x-python","patch_set":14,"id":"ba0121b8_9dae7596","line":216,"updated":"2016-03-30 20:42:53.000000000","message":"One of the callers has already done a cache lookup of the network, so it should pass it long.  The other could just as easily do it as well.","commit_id":"71434fcf2fc192a0107d16097bfa7175b992b03a"},{"author":{"_account_id":13734,"name":"Nell Jerram","email":"nell@tigera.io","username":"neiljerram"},"change_message_id":"e185b26db22e0bd4d5ae08c339be41f26e9a4e7e","unresolved":false,"context_lines":[{"line_number":220,"context_line":"            LOG.debug(\"_mark_dirty_network: network_id is dirty %s\","},{"line_number":221,"context_line":"                      network_id)"},{"line_number":222,"context_line":"            self.dirty_networks.add(network)"},{"line_number":223,"context_line":"            eventlet.spawn(self._reload_dirty_networks)"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"    @utils.synchronized(\u0027dhcp-agent\u0027)"},{"line_number":226,"context_line":"    def _reload_dirty_networks(self):"}],"source_content_type":"text/x-python","patch_set":14,"id":"ba0121b8_32f367a0","line":223,"updated":"2016-03-29 16:32:19.000000000","message":"I just have one remaining worry: what can cause the current thread (that runs _mark_dirty_network) to yield to the thread that runs _reload_dirty_networks?  If the answer is \u003csomething that happens very frequently, such as logging\u003e, then I\u0027m not sure that this change will actually make any difference at all - because we could still end up doing call_driver(\u0027reload_allocations\u0027) for every RPC port update.  (Whereas the idea of the original code change was to batch a group of RPC port updates and then do \u0027reload_allocations\u0027 once for all of those.)\n\nSo, to be precise, one question and one concern:\n\n- What causes an eventlet thread to yield?  In particular, does any I/O cause that (such as logging)?\n\n- Even if the current answer to that question is OK, isn\u0027t it wrong that we\u0027re making the DHCP agent code dependent on aspects of future eventlet implementation that might not be documented?","commit_id":"71434fcf2fc192a0107d16097bfa7175b992b03a"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"5e78aec3cd471311c1f19dbd9d997b9dfdf5a5b8","unresolved":false,"context_lines":[{"line_number":220,"context_line":"            LOG.debug(\"_mark_dirty_network: network_id is dirty %s\","},{"line_number":221,"context_line":"                      network_id)"},{"line_number":222,"context_line":"            self.dirty_networks.add(network)"},{"line_number":223,"context_line":"            eventlet.spawn(self._reload_dirty_networks)"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"    @utils.synchronized(\u0027dhcp-agent\u0027)"},{"line_number":226,"context_line":"    def _reload_dirty_networks(self):"}],"source_content_type":"text/x-python","patch_set":14,"id":"ba0121b8_8f23d7a6","line":223,"updated":"2016-03-30 23:10:17.000000000","message":"Oh, duh. Forgot that there was still a lock on adding to the dirty networks. Yes, this would just result in effectively random batching depending on the ordering of which threads are allowed to grab the lock.","commit_id":"71434fcf2fc192a0107d16097bfa7175b992b03a"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"ea5e199f83ccb1afdd483c4601e91228315d6cd7","unresolved":false,"context_lines":[{"line_number":220,"context_line":"            LOG.debug(\"_mark_dirty_network: network_id is dirty %s\","},{"line_number":221,"context_line":"                      network_id)"},{"line_number":222,"context_line":"            self.dirty_networks.add(network)"},{"line_number":223,"context_line":"            eventlet.spawn(self._reload_dirty_networks)"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"    @utils.synchronized(\u0027dhcp-agent\u0027)"},{"line_number":226,"context_line":"    def _reload_dirty_networks(self):"}],"source_content_type":"text/x-python","patch_set":14,"id":"ba0121b8_61685a88","line":223,"in_reply_to":"ba0121b8_32f367a0","updated":"2016-03-30 02:00:54.000000000","message":"Also, Neil, because a lock is held during the reload allocations, it means that the batching happens whenever an ongoing reload is taking place. So this is a much better approach than waiting an arbitrary amount of time for a queue to fill up and then draining it because it means the agent reacts to changes as fast as possible, only batching when necessary.\n\nAssume it takes 5 seconds to process a reload and we receive 4 port creates on the same network 1 second apart.\n\n1st update: net added to dirty networks and eventlet thread is spawned which acquires the lock, pops off the dirty network and starts a reload\n\n2nd update: net added to dirty networks. eventlet coro spawned which then blocks waiting for the lock\n\n3rd update: net added to dirty networks. eventlet coro spawned which blocks waiting for lock\n\n4th update: net added to dirty networks. eventlet coro spawned which blocks waiting for lock\n\n1st reload finishes: lock is released and one of the 3 coros waiting for the lock acquires it. this coro pops the network off and calls reload\n\n2nd reload finishes: lock is released and remaining two coros take turns getting the lock, finding an empty dirty_networks set, and returning.","commit_id":"71434fcf2fc192a0107d16097bfa7175b992b03a"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"65ad7b34d915ecdefa293289cd10882469a59531","unresolved":false,"context_lines":[{"line_number":220,"context_line":"            LOG.debug(\"_mark_dirty_network: network_id is dirty %s\","},{"line_number":221,"context_line":"                      network_id)"},{"line_number":222,"context_line":"            self.dirty_networks.add(network)"},{"line_number":223,"context_line":"            eventlet.spawn(self._reload_dirty_networks)"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"    @utils.synchronized(\u0027dhcp-agent\u0027)"},{"line_number":226,"context_line":"    def _reload_dirty_networks(self):"}],"source_content_type":"text/x-python","patch_set":14,"id":"ba0121b8_e0562fd1","line":223,"in_reply_to":"ba0121b8_32f367a0","updated":"2016-03-29 20:30:49.000000000","message":"Neil - yes, I guess I\u0027m making the assumption that the release of the lock will trigger a yield and the reload thread will run.  So this code might need some re-work.\n\nWe were going to test it locally to see if it actually helped.","commit_id":"71434fcf2fc192a0107d16097bfa7175b992b03a"},{"author":{"_account_id":13734,"name":"Nell Jerram","email":"nell@tigera.io","username":"neiljerram"},"change_message_id":"d9e64ec60cdb360aeaa53a65d1afb509649b56a7","unresolved":false,"context_lines":[{"line_number":220,"context_line":"            LOG.debug(\"_mark_dirty_network: network_id is dirty %s\","},{"line_number":221,"context_line":"                      network_id)"},{"line_number":222,"context_line":"            self.dirty_networks.add(network)"},{"line_number":223,"context_line":"            eventlet.spawn(self._reload_dirty_networks)"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"    @utils.synchronized(\u0027dhcp-agent\u0027)"},{"line_number":226,"context_line":"    def _reload_dirty_networks(self):"}],"source_content_type":"text/x-python","patch_set":14,"id":"ba0121b8_d172c2ac","line":223,"in_reply_to":"ba0121b8_61685a88","updated":"2016-03-30 10:36:17.000000000","message":"However, I am still not clear if the coroutines will be scheduled in a way that allows useful batching to occur.\n\nTaking your example above, I think that these are all wrong:\n\n\u003e 2nd update: net added to dirty networks...\n\u003e\n\u003e 3rd update: net added to dirty networks...\n\u003e\n\u003e 4th update: net added to dirty networks...\n\nThe code that _would_ add net to dirty_networks - and more importantly add/update the port in the NetModel - also needs the \u0027dhcp-agent\u0027 lock, and therefore will not run at all until the \u0027reload-allocations\u0027 for the 1st update has completed.\n\nSo, when that \u0027reload-allocations\u0027 completes, there is a coroutine waiting to process the 2nd update, and I think the RPC messages for the 3rd and 4th updates are still in the RPC queue.  So then:\n\n2nd update: net added to dirty networks. eventlet coro spawned which then blocks waiting for the lock\n\nNow port_create_end releases \u0027dhcp-agent\u0027 lock, and one of 2 things can happen:\n\na) The RPC thread reads the next RPC message and calls port_create_end again, and is successful grabbing \u0027dhcp-agent\u0027 lock again.\n\nb) The reload_dirty_networks coro manages to grab the \u0027dhcp-agent\u0027 lock first, and so the RPC thread will have to block until \u0027reload-allocations\u0027 is done for the 2nd update.\n\nIf there is a sustained pattern of choosing case (b), then there is no batching at all.","commit_id":"71434fcf2fc192a0107d16097bfa7175b992b03a"},{"author":{"_account_id":13734,"name":"Nell Jerram","email":"nell@tigera.io","username":"neiljerram"},"change_message_id":"d9e64ec60cdb360aeaa53a65d1afb509649b56a7","unresolved":false,"context_lines":[{"line_number":220,"context_line":"            LOG.debug(\"_mark_dirty_network: network_id is dirty %s\","},{"line_number":221,"context_line":"                      network_id)"},{"line_number":222,"context_line":"            self.dirty_networks.add(network)"},{"line_number":223,"context_line":"            eventlet.spawn(self._reload_dirty_networks)"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"    @utils.synchronized(\u0027dhcp-agent\u0027)"},{"line_number":226,"context_line":"    def _reload_dirty_networks(self):"}],"source_content_type":"text/x-python","patch_set":14,"id":"ba0121b8_76cacc6e","line":223,"in_reply_to":"ba0121b8_c12686b9","updated":"2016-03-30 10:36:17.000000000","message":"Thanks, Kevin.  I agree now that the lock (\u0027dhcp-agent\u0027) is the dominant factor here, and so we are not at risk of something like coroutine switching when the running code does a LOG.","commit_id":"71434fcf2fc192a0107d16097bfa7175b992b03a"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"858ff4806f9127d7742a5fda858cdfe63925de94","unresolved":false,"context_lines":[{"line_number":220,"context_line":"            LOG.debug(\"_mark_dirty_network: network_id is dirty %s\","},{"line_number":221,"context_line":"                      network_id)"},{"line_number":222,"context_line":"            self.dirty_networks.add(network)"},{"line_number":223,"context_line":"            eventlet.spawn(self._reload_dirty_networks)"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"    @utils.synchronized(\u0027dhcp-agent\u0027)"},{"line_number":226,"context_line":"    def _reload_dirty_networks(self):"}],"source_content_type":"text/x-python","patch_set":14,"id":"ba0121b8_7dbc41dc","line":223,"in_reply_to":"ba0121b8_d172c2ac","updated":"2016-03-30 20:42:53.000000000","message":"\u003e 1st update: net added to dirty networks and eventlet thread is spawned which acquires the lock, pops off the dirty network and starts a reload\n\nLooks right\n\n\u003e 2nd update: net added to dirty networks. eventlet coro spawned which then blocks waiting for the lock\n\nHere\u0027s where I\u0027m not so sure.  If the eventlet thread is running a reload, the port update RPC will be blocked until it can acquire the lock.  So there will never be more than one network in the dirty list, right?\n\nIt seems as though we want the path leading to _mark_dirty_network() to be lockless, but if the lock is protecting the cache we can\u0027t do that.","commit_id":"71434fcf2fc192a0107d16097bfa7175b992b03a"},{"author":{"_account_id":13734,"name":"Nell Jerram","email":"nell@tigera.io","username":"neiljerram"},"change_message_id":"d9e64ec60cdb360aeaa53a65d1afb509649b56a7","unresolved":false,"context_lines":[{"line_number":220,"context_line":"            LOG.debug(\"_mark_dirty_network: network_id is dirty %s\","},{"line_number":221,"context_line":"                      network_id)"},{"line_number":222,"context_line":"            self.dirty_networks.add(network)"},{"line_number":223,"context_line":"            eventlet.spawn(self._reload_dirty_networks)"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"    @utils.synchronized(\u0027dhcp-agent\u0027)"},{"line_number":226,"context_line":"    def _reload_dirty_networks(self):"}],"source_content_type":"text/x-python","patch_set":14,"id":"ba0121b8_16927057","line":223,"in_reply_to":"ba0121b8_e0562fd1","updated":"2016-03-30 10:36:17.000000000","message":"Thanks, Brian, I think that\u0027s sensible.","commit_id":"71434fcf2fc192a0107d16097bfa7175b992b03a"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"30a10176b62602ea26a49f49780a41545186e6b7","unresolved":false,"context_lines":[{"line_number":220,"context_line":"            LOG.debug(\"_mark_dirty_network: network_id is dirty %s\","},{"line_number":221,"context_line":"                      network_id)"},{"line_number":222,"context_line":"            self.dirty_networks.add(network)"},{"line_number":223,"context_line":"            eventlet.spawn(self._reload_dirty_networks)"},{"line_number":224,"context_line":""},{"line_number":225,"context_line":"    @utils.synchronized(\u0027dhcp-agent\u0027)"},{"line_number":226,"context_line":"    def _reload_dirty_networks(self):"}],"source_content_type":"text/x-python","patch_set":14,"id":"ba0121b8_c12686b9","line":223,"in_reply_to":"ba0121b8_e0562fd1","updated":"2016-03-30 01:47:39.000000000","message":"This doesn\u0027t depend on any hidden implementation details of eventlet. All spawned coroutines will block waiting to get the lock and yield. Any blocking operation (interface polling, sleeps, logging, lock acquisition) will cause the main loop to yield to any waiting coroutines which will get another chance to grab the lock.\n\nNone of this has anything to do with eventlet implementation details, it\u0027s just how cooperative yielding works. Same thing would happen with any other coroutine library.\n\nAdditionally, this logic isn\u0027t even dependent on coroutines, we could spawn an entire thread if we wanted and all reloads would still be serialized by waiting on the lock until they proceed.","commit_id":"71434fcf2fc192a0107d16097bfa7175b992b03a"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"6d7fdc0c32aaf51065dc5374631f00a3d77cb011","unresolved":false,"context_lines":[{"line_number":64,"context_line":"        for i in range(1, 21):"},{"line_number":65,"context_line":"            if i !\u003d 1:"},{"line_number":66,"context_line":"                eventlet.sleep(0.1)"},{"line_number":67,"context_line":"            with DHCP_LOCK.write_lock():"},{"line_number":68,"context_line":"                if DHCP_LOCK.has_pending_writers and i \u003c 20:"},{"line_number":69,"context_line":"                    continue"},{"line_number":70,"context_line":"                return f(*args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":18,"id":"5a18252c_a891a89b","line":67,"updated":"2016-04-13 13:15:37.000000000","message":"what are the chances of locking and finding that there are other writers waiting (considering green threads)? is this complexity really worth it or needed?\n\nDon\u0027t we need to call into something blocking between L67 and L68 to other greenthread to try to acquire the lock?\n\n(sorry, this is probably ignorance on my side, just trying to understand it)","commit_id":"af3d003eef3789a4c0411f5c9432ecd243b6e29d"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"6d7fdc0c32aaf51065dc5374631f00a3d77cb011","unresolved":false,"context_lines":[{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    def __init__(self, host\u003dNone, conf\u003dNone):"},{"line_number":99,"context_line":"        super(DhcpAgent, self).__init__(host\u003dhost)"},{"line_number":100,"context_line":"        # the following is effectively unlimted. only used in lieu of"},{"line_number":101,"context_line":"        # eventlet.spawn so unit tests can call waitall() to esnure coroutines"},{"line_number":102,"context_line":"        # have completed."},{"line_number":103,"context_line":"        self.reload_pool \u003d eventlet.GreenPool(2 ** 32)"}],"source_content_type":"text/x-python","patch_set":18,"id":"5a18252c_8de15e9d","line":100,"updated":"2016-04-13 13:15:37.000000000","message":"unlimted -\u003e unlimited","commit_id":"af3d003eef3789a4c0411f5c9432ecd243b6e29d"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"6d7fdc0c32aaf51065dc5374631f00a3d77cb011","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    def __init__(self, host\u003dNone, conf\u003dNone):"},{"line_number":99,"context_line":"        super(DhcpAgent, self).__init__(host\u003dhost)"},{"line_number":100,"context_line":"        # the following is effectively unlimted. only used in lieu of"},{"line_number":101,"context_line":"        # eventlet.spawn so unit tests can call waitall() to esnure coroutines"},{"line_number":102,"context_line":"        # have completed."},{"line_number":103,"context_line":"        self.reload_pool \u003d eventlet.GreenPool(2 ** 32)"},{"line_number":104,"context_line":"        self.needs_resync_reasons \u003d collections.defaultdict(list)"}],"source_content_type":"text/x-python","patch_set":18,"id":"5a18252c_cd98761e","line":101,"updated":"2016-04-13 13:15:37.000000000","message":"esnure-\u003eensure","commit_id":"af3d003eef3789a4c0411f5c9432ecd243b6e29d"},{"author":{"_account_id":8788,"name":"Miguel Angel Ajo","email":"mangelajo@redhat.com","username":"mangelajo"},"change_message_id":"6d7fdc0c32aaf51065dc5374631f00a3d77cb011","unresolved":false,"context_lines":[{"line_number":100,"context_line":"        # the following is effectively unlimted. only used in lieu of"},{"line_number":101,"context_line":"        # eventlet.spawn so unit tests can call waitall() to esnure coroutines"},{"line_number":102,"context_line":"        # have completed."},{"line_number":103,"context_line":"        self.reload_pool \u003d eventlet.GreenPool(2 ** 32)"},{"line_number":104,"context_line":"        self.needs_resync_reasons \u003d collections.defaultdict(list)"},{"line_number":105,"context_line":"        self.conf \u003d conf or cfg.CONF"},{"line_number":106,"context_line":"        self.cache \u003d NetworkCache()"}],"source_content_type":"text/x-python","patch_set":18,"id":"5a18252c_e388e324","line":103,"updated":"2016-04-13 13:15:37.000000000","message":"don\u0027t we have any self.reload_pool.waitall()  ? \n\nthat\u0027d keep decreasing the count of available threads, and I\u0027m not sure if the threads are actually executed otherwise?","commit_id":"af3d003eef3789a4c0411f5c9432ecd243b6e29d"}]}
