)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"69eda53ddc4b93276c285f953d3eabcf781a400c","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This change:"},{"line_number":10,"context_line":"* removes a q.emtpy() vs. q.get() race"},{"line_number":11,"context_line":"* avoids creating lost of short-lived threads"},{"line_number":12,"context_line":"  (because: why would we ?)"},{"line_number":13,"context_line":"* avoids calling spawn_n in a while True"},{"line_number":14,"context_line":"  (what is inside spawn_n might fail, and if"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"ff6b8bd7_f0e05d99","line":11,"range":{"start_line":11,"start_character":18,"end_line":11,"end_character":22},"updated":"2018-03-05 19:50:19.000000000","message":"s/lots","commit_id":"e4fbc617999438f66768dc61578187fb133e58a7"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"69eda53ddc4b93276c285f953d3eabcf781a400c","unresolved":false,"context_lines":[{"line_number":23,"context_line":"How come we don\u0027t have a Hopefully-Solves-Bug: tag ?"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"Change-Id: Ic348c08af375099a919116188ae17d2017695ecb"},{"line_number":26,"context_line":"Related-Bug: 1750777"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"ff6b8bd7_6b5bfe2d","line":26,"range":{"start_line":26,"start_character":0,"end_line":26,"end_character":7},"updated":"2018-03-05 19:50:19.000000000","message":"If this fixes it we don\u0027t need the other change and this should be \"Closes\"","commit_id":"e4fbc617999438f66768dc61578187fb133e58a7"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"2524bf3fc9826fc4765c35cdf0f4b8180acc2a87","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Remove race and simplify conntrack state management"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This change:"},{"line_number":10,"context_line":"* removes a q.emtpy() vs. q.get() race"},{"line_number":11,"context_line":"* avoids creating lots of short-lived threads"},{"line_number":12,"context_line":"  (because: why would we ?)"},{"line_number":13,"context_line":"* adds a try/except block to be sure we can log"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"df7087c5_a079ca2f","line":10,"range":{"start_line":10,"start_character":0,"end_line":10,"end_character":38},"updated":"2018-03-12 17:02:55.000000000","message":"this line would need to go, since my analysis was wrong: get() is blocking so trying .empty() before doing .get() is not a race","commit_id":"7d96544e854b490fa135b6a564ca38377932901b"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"52197cf4c94914bdaed4675b8dbd5742f74befa0","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Remove race and simplify conntrack state management"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This change:"},{"line_number":10,"context_line":"* removes a q.emtpy() vs. q.get() race"},{"line_number":11,"context_line":"* avoids creating lots of short-lived threads"},{"line_number":12,"context_line":"  (because: why would we ?)"},{"line_number":13,"context_line":"* adds a try/except block to be sure we can log"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"df7087c5_d4d4c3bf","line":10,"range":{"start_line":10,"start_character":0,"end_line":10,"end_character":38},"in_reply_to":"df7087c5_a079ca2f","updated":"2018-03-12 17:34:21.000000000","message":"I can remove it, but I think there is still a small window for a race, see my comment in the code.","commit_id":"7d96544e854b490fa135b6a564ca38377932901b"}],"neutron/agent/linux/ip_conntrack.py":[{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"69eda53ddc4b93276c285f953d3eabcf781a400c","unresolved":false,"context_lines":[{"line_number":52,"context_line":"    def updates(self):"},{"line_number":53,"context_line":"        \"\"\"Grabs the next conntrack update from the queue and processes.\"\"\""},{"line_number":54,"context_line":"        while not self._queue.empty():"},{"line_number":55,"context_line":"            update \u003d self._queue.get()"},{"line_number":56,"context_line":"            yield update"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"ff6b8bd7_2b70a672","side":"PARENT","line":55,"updated":"2018-03-05 19:50:19.000000000","message":"This should have blocked, but perhaps with multiple workers \u003e1 get woken and only one returns something, causing an exception?  But then that would be just as broken in the changed code except it would be logged?","commit_id":"20760bcdf58e2f3655bfa36000b3611e09f8ce89"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"1963519997ccbe23e8708bb93b73571e4a315687","unresolved":false,"context_lines":[{"line_number":52,"context_line":"    def updates(self):"},{"line_number":53,"context_line":"        \"\"\"Grabs the next conntrack update from the queue and processes.\"\"\""},{"line_number":54,"context_line":"        while not self._queue.empty():"},{"line_number":55,"context_line":"            update \u003d self._queue.get()"},{"line_number":56,"context_line":"            yield update"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"df7087c5_a090ea4f","side":"PARENT","line":55,"in_reply_to":"ff6b8bd7_2b70a672","updated":"2018-03-12 16:52:00.000000000","message":"I think .get() would not return nor raise an exception in the case where there are multiple workers (this is the whole point and the doc says \"If optional args block is true and timeout is None (the default), block if necessary until an item is available\").  I think you are right to hint that what I thought was a race likely to be the cause for our problem, probably does not exist and then is not the cause of the problem.\n\n\nAt this point the only thing that I\u0027m quite sure about is that we need to properly catch exception of whatever is done by what we give spawn_n to spaw_n -- or we take high risk of silently ignoring failures.\n\nThen there is the question of short-lived threads vs. long lived threads, but I don\u0027t have a strong rationale to favor long lived threads, except that it seems slightly better in terms of resources, but perhaps not by a relevant margin.","commit_id":"20760bcdf58e2f3655bfa36000b3611e09f8ce89"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"69eda53ddc4b93276c285f953d3eabcf781a400c","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        self.start_process_queue()"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def start_process_queue(self):"},{"line_number":74,"context_line":"        LOG.debug(\"Starting ipconntrack _process_queue_loop()\")"},{"line_number":75,"context_line":"        pool \u003d eventlet.GreenPool(size\u003d8)"},{"line_number":76,"context_line":"        pool.spawn_n(self._process_queue)"},{"line_number":77,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"ff6b8bd7_f08e1dcf","line":74,"range":{"start_line":74,"start_character":40,"end_line":74,"end_character":61},"updated":"2018-03-05 19:50:19.000000000","message":"We should fix the message while we\u0027re at it, \"_process_queue() workers\" ?","commit_id":"e4fbc617999438f66768dc61578187fb133e58a7"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"69eda53ddc4b93276c285f953d3eabcf781a400c","unresolved":false,"context_lines":[{"line_number":73,"context_line":"    def start_process_queue(self):"},{"line_number":74,"context_line":"        LOG.debug(\"Starting ipconntrack _process_queue_loop()\")"},{"line_number":75,"context_line":"        pool \u003d eventlet.GreenPool(size\u003d8)"},{"line_number":76,"context_line":"        pool.spawn_n(self._process_queue)"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    def _process_queue(self):"},{"line_number":79,"context_line":"        while True:"}],"source_content_type":"text/x-python","patch_set":1,"id":"ff6b8bd7_1024f1c5","line":76,"updated":"2018-03-05 19:50:19.000000000","message":"When I wrote this I based it on the router processing queue code which had the \"while True:\".  I\u0027m not sure of any small details of why one method would be preferred over the other.","commit_id":"e4fbc617999438f66768dc61578187fb133e58a7"},{"author":{"_account_id":4694,"name":"Miguel Lavalle","email":"miguel@mlavalle.com","username":"minsel"},"change_message_id":"6027e4f53c6b0e2990b9768a1620a3fc857a5956","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def _start_process_queue(self):"},{"line_number":73,"context_line":"        LOG.debug(\"Starting ipconntrack _process_queue_loop() workers\")"},{"line_number":74,"context_line":"        pool \u003d eventlet.GreenPool(size\u003d8)"},{"line_number":75,"context_line":"        pool.spawn_n(self._process_queue_loop)"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def _process_queue_loop(self):"},{"line_number":78,"context_line":"        # While it\u0027s technically not necessary to have this method, the"}],"source_content_type":"text/x-python","patch_set":3,"id":"df7087c5_4f1123ac","line":75,"range":{"start_line":74,"start_character":0,"end_line":75,"end_character":46},"updated":"2018-03-09 20:29:58.000000000","message":"If I am reading this correctly, with this approach we will have only one worker, right? Don\u0027t we want more?","commit_id":"9403e76fded14d75b1d392bc557cd79bc214c08e"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"45333114a5b51034d541b71fd308fd41f36706fd","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        self._queue \u003d eventlet.queue.LightQueue()"},{"line_number":70,"context_line":"        self._start_process_queue()"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def _start_process_queue(self):"},{"line_number":73,"context_line":"        eventlet.spawn_n(self._process_queue_loop)"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def _process_queue_loop(self):"},{"line_number":76,"context_line":"        LOG.debug(\"Starting ip_conntrack _process_queue_worker() threads\")"},{"line_number":77,"context_line":"        pool \u003d eventlet.GreenPool(size\u003d8)"},{"line_number":78,"context_line":"        while True:"},{"line_number":79,"context_line":"            pool.spawn_n(self._process_queue_worker)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def _process_queue_worker(self):"},{"line_number":82,"context_line":"        # While it\u0027s technically not necessary to have this method, the"}],"source_content_type":"text/x-python","patch_set":4,"id":"df7087c5_7ca4a8a6","line":79,"range":{"start_line":72,"start_character":0,"end_line":79,"end_character":52},"updated":"2018-03-13 09:43:47.000000000","message":"The purpose of having these two methods was that the first one is starting a thread that will keep spawning threads forever with a max of 8 concurrent threads. 8 threads will be started, and each time a thread dies, a new one is restarted.\n\nWith this change, the threads are no longer short-lived (while True L86) and they won\u0027t die if any exception is catched.\n\nSo, I believe we can perhaps simplify even more:\n\n    def _start_process_queue(self):\n        LOG.debug(\"Starting ip_conntrack _process_queue_worker() threads\")\n        pool \u003d eventlet.GreenPool(size\u003d8)\n        for _ in range(0, 8):\n            pool.spawn_n(self._process_queue_worker)\n\n(perhaps replacing 8 with a constant)","commit_id":"7d96544e854b490fa135b6a564ca38377932901b"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"b1fdbefe0ca7d662e1d9f31091dc78ca81bbaeef","unresolved":false,"context_lines":[{"line_number":98,"context_line":"                self._delete_conntrack_state("},{"line_number":99,"context_line":"                    update.device_info_list, update.rule)"},{"line_number":100,"context_line":"        except IndexError:"},{"line_number":101,"context_line":"            # queue was empty, another worker stole our entry, not fatal"},{"line_number":102,"context_line":"            return"},{"line_number":103,"context_line":"        except Exception as e:"},{"line_number":104,"context_line":"            LOG.error(\"Failed to process ip_conntrack queue entry: %s\", e)"}],"source_content_type":"text/x-python","patch_set":4,"id":"df7087c5_00643621","line":101,"range":{"start_line":101,"start_character":14,"end_line":101,"end_character":62},"updated":"2018-03-12 17:06:34.000000000","message":"Are we sure that this comment is valid: is IndexError raised in such cases ? (eventlet.queue.Empty seems to be the exception that would be raised if the queue was empty, but I\u0027m not sure we can have this case since we use a blocking get()...)\n\nAnd this except IndexError might hide real issues in self.*_*conntrack* methods...","commit_id":"7d96544e854b490fa135b6a564ca38377932901b"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"52197cf4c94914bdaed4675b8dbd5742f74befa0","unresolved":false,"context_lines":[{"line_number":98,"context_line":"                self._delete_conntrack_state("},{"line_number":99,"context_line":"                    update.device_info_list, update.rule)"},{"line_number":100,"context_line":"        except IndexError:"},{"line_number":101,"context_line":"            # queue was empty, another worker stole our entry, not fatal"},{"line_number":102,"context_line":"            return"},{"line_number":103,"context_line":"        except Exception as e:"},{"line_number":104,"context_line":"            LOG.error(\"Failed to process ip_conntrack queue entry: %s\", e)"}],"source_content_type":"text/x-python","patch_set":4,"id":"df7087c5_d45fe36f","line":101,"range":{"start_line":101,"start_character":14,"end_line":101,"end_character":62},"in_reply_to":"df7087c5_00643621","updated":"2018-03-12 17:34:21.000000000","message":"I definitely saw an IndexError when working on my (bad) change that we are reverting, maybe it had to do with the empty/get logic, and when this thread finally got to the get() there wasn\u0027t an entry.\n\nBypassing get() and going right to _get() does show that was the case (entry probably got popped before we arrived):\n\n\u003e\u003e\u003e q \u003d eventlet.queue.LightQueue()\n\u003e\u003e\u003e q._get()\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  File \"/usr/local/lib/python2.7/dist-packages/eventlet/queue.py\", line 171, in _get\n    return self.queue.popleft()\nIndexError: pop from an empty deque\n\nI wonder if get() can still trigger this though, as this is what it is doing:\n\n    def get():\n        [...]\n        if self.qsize():\n            if self.putters:\n                self._schedule_unlock()\n            return self._get()\n\nIt\u0027s basically doing \"if not empty, _get()\", which might fail with multiple threads, and it won\u0027t return Empty.","commit_id":"7d96544e854b490fa135b6a564ca38377932901b"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"2735c0128ebda8b7403feee44651bcb15bd978b3","unresolved":false,"context_lines":[{"line_number":98,"context_line":"                self._delete_conntrack_state("},{"line_number":99,"context_line":"                    update.device_info_list, update.rule)"},{"line_number":100,"context_line":"        except IndexError:"},{"line_number":101,"context_line":"            # queue was empty, another worker stole our entry, not fatal"},{"line_number":102,"context_line":"            return"},{"line_number":103,"context_line":"        except Exception as e:"},{"line_number":104,"context_line":"            LOG.error(\"Failed to process ip_conntrack queue entry: %s\", e)"}],"source_content_type":"text/x-python","patch_set":4,"id":"df7087c5_81fa75ba","line":101,"range":{"start_line":101,"start_character":14,"end_line":101,"end_character":62},"in_reply_to":"df7087c5_d45fe36f","updated":"2018-03-13 09:30:33.000000000","message":"--- About the possibility of empty()/get() race:\n\nThe doc [1] seems to imply that these classes are (green)thread safe: \"Synchronized queues. The eventlet.queue module implements multi-producer, multi-consumer queues that work across greenlets, with the API similar to the classes found in the standard Queue and multiprocessing modules.\"\n\nAdditionally, I read this: \"An interesting difference, made possible because of greenthreads, is that Queue.qsize(), Queue.empty(), and Queue.full() can be used as indicators of whether the subsequent Queue.get() or Queue.put() will not block. The new methods Queue.getting() and Queue.putting() report on the number of greenthreads blocking in put or get respectively.\"\n\nWhich would lead me to believe that there is no .emtpy()/.get() race issue.\n\n[1] http://eventlet.net/doc/modules/queue.html\n\n-- About IndexError...\n\nI can\u0027t explain why you\u0027ve seen an IndexError, this seems inconsistent with the doc above and the fact that eventlet greenthread do not race between one another unless they explicitly yield.\n\nBut, if you really think you need to catch an IndexError in the case where get might still raise it, then the \u0027try\u0027 statement should include the get(), not start after it (L91-92).","commit_id":"7d96544e854b490fa135b6a564ca38377932901b"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"d31d3c41e2f226da2a538e30e3d82d90f46e3262","unresolved":false,"context_lines":[{"line_number":74,"context_line":"    def _start_process_queue(self):"},{"line_number":75,"context_line":"        LOG.debug(\"Starting ip_conntrack _process_queue_worker() threads\")"},{"line_number":76,"context_line":"        pool \u003d eventlet.GreenPool(size\u003dWORKERS)"},{"line_number":77,"context_line":"        for _ in range(0, WORKERS):"},{"line_number":78,"context_line":"            pool.spawn_n(self._process_queue_worker)"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def _process_queue_worker(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"df7087c5_02d5dee4","line":77,"range":{"start_line":77,"start_character":23,"end_line":77,"end_character":25},"updated":"2018-03-14 14:26:59.000000000","message":"nit: don\u0027t need the 0, here, but it\u0027s the _ causing the pep8 issue","commit_id":"33ea7837c8b0d9c3df7ff5bc6d501a8e5f01afdc"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"f4f2db8262ac65d2473d5f1ade77491d6d1e7636","unresolved":false,"context_lines":[{"line_number":74,"context_line":"    def _start_process_queue(self):"},{"line_number":75,"context_line":"        LOG.debug(\"Starting ip_conntrack _process_queue_worker() threads\")"},{"line_number":76,"context_line":"        pool \u003d eventlet.GreenPool(size\u003dWORKERS)"},{"line_number":77,"context_line":"        for _ in range(0, WORKERS):"},{"line_number":78,"context_line":"            pool.spawn_n(self._process_queue_worker)"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def _process_queue_worker(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"df7087c5_88726dac","line":77,"range":{"start_line":77,"start_character":23,"end_line":77,"end_character":25},"in_reply_to":"df7087c5_02d5dee4","updated":"2018-03-14 15:15:58.000000000","message":"ok!","commit_id":"33ea7837c8b0d9c3df7ff5bc6d501a8e5f01afdc"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"d31d3c41e2f226da2a538e30e3d82d90f46e3262","unresolved":false,"context_lines":[{"line_number":100,"context_line":"#             # NOTE: it remains unclear why this Exception would pop up, but"},{"line_number":101,"context_line":"#             # if it does, it means that the queue was empty, another worker"},{"line_number":102,"context_line":"#             # stole our entry, not fatal"},{"line_number":103,"context_line":"#             return"},{"line_number":104,"context_line":"        except Exception as e:"},{"line_number":105,"context_line":"            LOG.error(\"Failed to process ip_conntrack queue entry: %s\", e)"},{"line_number":106,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"df7087c5_02ee3eb3","line":103,"updated":"2018-03-14 14:26:59.000000000","message":"Yeah, I guess we don\u0027t need this, at worst we print an error saying it was an IndexError, and if we see a lot of those we can put this back.","commit_id":"33ea7837c8b0d9c3df7ff5bc6d501a8e5f01afdc"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"f4f2db8262ac65d2473d5f1ade77491d6d1e7636","unresolved":false,"context_lines":[{"line_number":100,"context_line":"#             # NOTE: it remains unclear why this Exception would pop up, but"},{"line_number":101,"context_line":"#             # if it does, it means that the queue was empty, another worker"},{"line_number":102,"context_line":"#             # stole our entry, not fatal"},{"line_number":103,"context_line":"#             return"},{"line_number":104,"context_line":"        except Exception as e:"},{"line_number":105,"context_line":"            LOG.error(\"Failed to process ip_conntrack queue entry: %s\", e)"},{"line_number":106,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"df7087c5_286b21b7","line":103,"in_reply_to":"df7087c5_02ee3eb3","updated":"2018-03-14 15:15:58.000000000","message":"okay!","commit_id":"33ea7837c8b0d9c3df7ff5bc6d501a8e5f01afdc"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"f4f2db8262ac65d2473d5f1ade77491d6d1e7636","unresolved":false,"context_lines":[{"line_number":97,"context_line":"                self._delete_conntrack_state("},{"line_number":98,"context_line":"                    update.device_info_list, update.rule)"},{"line_number":99,"context_line":"        except Exception as e:"},{"line_number":100,"context_line":"            LOG.error(\"Failed to process ip_conntrack queue entry: %s\", e)"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"    def _process(self, device_info_list, rule, remote_ips\u003dNone):"},{"line_number":103,"context_line":"        # queue the update to allow the caller to resume its work"}],"source_content_type":"text/x-python","patch_set":6,"id":"df7087c5_48969595","line":100,"range":{"start_line":100,"start_character":12,"end_line":100,"end_character":74},"updated":"2018-03-14 15:15:58.000000000","message":"I\u0027m pushing a new PS, to use LOG.exception and also log the \u0027update\u0027 object.","commit_id":"246c47af30f69dec691875c9ffe1835ebe8690cc"},{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"f344061ce74ded021c22b237dd883602a0888965","unresolved":false,"context_lines":[{"line_number":99,"context_line":"                    update.device_info_list, update.rule)"},{"line_number":100,"context_line":"        except:  # noqa"},{"line_number":101,"context_line":"            LOG.exception(\"Failed to process ip_conntrack queue entry: %s\","},{"line_number":102,"context_line":"                          update)"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"    def _process(self, device_info_list, rule, remote_ips\u003dNone):"},{"line_number":105,"context_line":"        # queue the update to allow the caller to resume its work"}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_bc053613","line":102,"updated":"2018-03-14 15:52:15.000000000","message":"I think this will print something like \u003cIpConntrackUpdate object at 0x7fcf515ec1d0\u003e without adding a __repr__() to the IPConntrackUpdate class.  Something like:\n\n    def __repr__(self):                                                         \n        return (\u0027\u003cIpConntrackUpdate(device_info_list\u003d%s, rule\u003d%s, \u0027                             \u0027remote_ips\u003d%s\u003e\u0027 % (self.device_info_list, self.rule,                                               self.remote_ips))\n\njust ignore the bad line wrapping","commit_id":"c296fdc6dad3f486ae218a0220755dafc4a5613d"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"b3a3558f827530fb299a26495551bcba58aaa72c","unresolved":false,"context_lines":[{"line_number":99,"context_line":"                    update.device_info_list, update.rule)"},{"line_number":100,"context_line":"        except:  # noqa"},{"line_number":101,"context_line":"            LOG.exception(\"Failed to process ip_conntrack queue entry: %s\","},{"line_number":102,"context_line":"                          update)"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"    def _process(self, device_info_list, rule, remote_ips\u003dNone):"},{"line_number":105,"context_line":"        # queue the update to allow the caller to resume its work"}],"source_content_type":"text/x-python","patch_set":8,"id":"df7087c5_f28bd764","line":102,"in_reply_to":"df7087c5_bc053613","updated":"2018-03-14 16:37:38.000000000","message":"Good point!","commit_id":"c296fdc6dad3f486ae218a0220755dafc4a5613d"}]}
