)]}'
{"rally/common/utils.py":[{"author":{"_account_id":6172,"name":"Boris Pavlovic","email":"boris@pavlovic.me","username":"boris-42"},"change_message_id":"eefa4b2e8ca40b0c318ded1a2b4595b1f27cc589","unresolved":false,"context_lines":[{"line_number":490,"context_line":"        raise ValueError(\"nonexistent thread id\")"},{"line_number":491,"context_line":"    elif res \u003e 1:"},{"line_number":492,"context_line":"        # NOTE(rvasilets) if it returns a number greater than one, you\u0027re"},{"line_number":493,"context_line":"        # in trouble, and you should call it again with exc\u003dNULL to revert"},{"line_number":494,"context_line":"        # the effect"},{"line_number":495,"context_line":"        ctypes.pythonapi.PyThreadState_SetAsyncExc(thread.ident, None)"},{"line_number":496,"context_line":"        raise SystemError(\"PyThreadState_SetAsyncExc failed\")"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a29b11f_5452e1de","line":493,"updated":"2015-10-18 08:01:47.000000000","message":"what means you are in trouble? who is in trouble and why it is in trouble?","commit_id":"d2b59d0506e75b7b877ffbbfa04ada8ce521011e"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"c87713e2874bef3c90653ac9b5e25042ca3b0d45","unresolved":false,"context_lines":[{"line_number":517,"context_line":""},{"line_number":518,"context_line":""},{"line_number":519,"context_line":"def timeout_thr_closing(queue, timeout, is_stop):"},{"line_number":520,"context_line":"    \"\"\"Terminate threads by timeout."},{"line_number":521,"context_line":""},{"line_number":522,"context_line":"    Function need to be run in separate thread. Its designed to terminate"},{"line_number":523,"context_line":"    threads in the same process which are run longer then timeout."}],"source_content_type":"text/x-python","patch_set":9,"id":"1a26ad4f_60481288","line":520,"updated":"2015-10-30 13:11:30.000000000","message":"This method looks complicated.\n\nThings may be much simpler:\n\n :param timeout: timeout in seconds when thread should be killed\n :param threading.Event event: object which will be set if thread exited before timeout\n \n if not event.wait(timeout\u003dtimeout):\n   terminate_thread()\n\nThats all","commit_id":"aa05c788cd8652914e419287669c06e4bd7cd980"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"e3208e288c9df134ddf46b529b8e896131f9804e","unresolved":false,"context_lines":[{"line_number":517,"context_line":""},{"line_number":518,"context_line":""},{"line_number":519,"context_line":"def timeout_thr_closing(queue, timeout, is_stop):"},{"line_number":520,"context_line":"    \"\"\"Terminate threads by timeout."},{"line_number":521,"context_line":""},{"line_number":522,"context_line":"    Function need to be run in separate thread. Its designed to terminate"},{"line_number":523,"context_line":"    threads in the same process which are run longer then timeout."}],"source_content_type":"text/x-python","patch_set":9,"id":"1a26ad4f_8696a6ee","line":520,"in_reply_to":"1a26ad4f_60481288","updated":"2015-10-30 14:17:04.000000000","message":"No. Because we have a lot of threads that possibly need to be terminated. Also we need to know which thread to terminate and when.","commit_id":"aa05c788cd8652914e419287669c06e4bd7cd980"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"e92ee94db9d6670b818fa0acee46267b0e22206a","unresolved":false,"context_lines":[{"line_number":522,"context_line":"    Function need to be run in separate thread. Its designed to terminate"},{"line_number":523,"context_line":"    threads in the same process which are run longer then timeout."},{"line_number":524,"context_line":""},{"line_number":525,"context_line":"    :param queue: multiprocessing.Queue instance contained tuples of"},{"line_number":526,"context_line":"                  thread id, start time of the thread"},{"line_number":527,"context_line":"    :param timeout: timeout for threads in the queue after which"},{"line_number":528,"context_line":"                    threads must to be terminated"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a26ad4f_48a3949d","line":525,"updated":"2015-11-02 13:57:27.000000000","message":"Why multiprocessing.Queue? We are not using this queue between processes, and this queue does a lot of synchronization stuff to be process-safe (it can even start new threads)\n\nIt better use Queue.Queue here.","commit_id":"aa05c788cd8652914e419287669c06e4bd7cd980"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"11bd656342d7275380bad4ff6ded284fbd8d2057","unresolved":false,"context_lines":[{"line_number":522,"context_line":"    Function need to be run in separate thread. Its designed to terminate"},{"line_number":523,"context_line":"    threads in the same process which are run longer then timeout."},{"line_number":524,"context_line":""},{"line_number":525,"context_line":"    :param queue: multiprocessing.Queue instance contained tuples of"},{"line_number":526,"context_line":"                  thread id, start time of the thread"},{"line_number":527,"context_line":"    :param timeout: timeout for threads in the queue after which"},{"line_number":528,"context_line":"                    threads must to be terminated"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a26ad4f_873e7a26","line":525,"in_reply_to":"1a26ad4f_48a3949d","updated":"2015-11-02 14:55:38.000000000","message":"Agree. This was left from previous version.","commit_id":"aa05c788cd8652914e419287669c06e4bd7cd980"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"e92ee94db9d6670b818fa0acee46267b0e22206a","unresolved":false,"context_lines":[{"line_number":523,"context_line":"    threads in the same process which are run longer then timeout."},{"line_number":524,"context_line":""},{"line_number":525,"context_line":"    :param queue: multiprocessing.Queue instance contained tuples of"},{"line_number":526,"context_line":"                  thread id, start time of the thread"},{"line_number":527,"context_line":"    :param timeout: timeout for threads in the queue after which"},{"line_number":528,"context_line":"                    threads must to be terminated"},{"line_number":529,"context_line":"    :param is_stop: threading,Event instance if its set then"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a26ad4f_28d418ea","line":526,"updated":"2015-11-02 13:57:27.000000000","message":"It will be simpler if we just pass \"deadline\" instead of start_time. Then we can remove \"timeout\" argument from this function.","commit_id":"aa05c788cd8652914e419287669c06e4bd7cd980"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"11bd656342d7275380bad4ff6ded284fbd8d2057","unresolved":false,"context_lines":[{"line_number":523,"context_line":"    threads in the same process which are run longer then timeout."},{"line_number":524,"context_line":""},{"line_number":525,"context_line":"    :param queue: multiprocessing.Queue instance contained tuples of"},{"line_number":526,"context_line":"                  thread id, start time of the thread"},{"line_number":527,"context_line":"    :param timeout: timeout for threads in the queue after which"},{"line_number":528,"context_line":"                    threads must to be terminated"},{"line_number":529,"context_line":"    :param is_stop: threading,Event instance if its set then"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a26ad4f_ad091586","line":526,"in_reply_to":"1a26ad4f_28d418ea","updated":"2015-11-02 14:55:38.000000000","message":"ok","commit_id":"aa05c788cd8652914e419287669c06e4bd7cd980"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"c87713e2874bef3c90653ac9b5e25042ca3b0d45","unresolved":false,"context_lines":[{"line_number":526,"context_line":"                  thread id, start time of the thread"},{"line_number":527,"context_line":"    :param timeout: timeout for threads in the queue after which"},{"line_number":528,"context_line":"                    threads must to be terminated"},{"line_number":529,"context_line":"    :param is_stop: threading,Event instance if its set then"},{"line_number":530,"context_line":"                    we exit from the function"},{"line_number":531,"context_line":"    \"\"\""},{"line_number":532,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"1a26ad4f_008b5ec4","line":529,"updated":"2015-10-30 13:11:30.000000000","message":"typo: threading.Event","commit_id":"aa05c788cd8652914e419287669c06e4bd7cd980"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"e3208e288c9df134ddf46b529b8e896131f9804e","unresolved":false,"context_lines":[{"line_number":526,"context_line":"                  thread id, start time of the thread"},{"line_number":527,"context_line":"    :param timeout: timeout for threads in the queue after which"},{"line_number":528,"context_line":"                    threads must to be terminated"},{"line_number":529,"context_line":"    :param is_stop: threading,Event instance if its set then"},{"line_number":530,"context_line":"                    we exit from the function"},{"line_number":531,"context_line":"    \"\"\""},{"line_number":532,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"1a26ad4f_263792e4","line":529,"in_reply_to":"1a26ad4f_008b5ec4","updated":"2015-10-30 14:17:04.000000000","message":"Done","commit_id":"aa05c788cd8652914e419287669c06e4bd7cd980"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"c87713e2874bef3c90653ac9b5e25042ca3b0d45","unresolved":false,"context_lines":[{"line_number":530,"context_line":"                    we exit from the function"},{"line_number":531,"context_line":"    \"\"\""},{"line_number":532,"context_line":""},{"line_number":533,"context_line":"    if not timeout:"},{"line_number":534,"context_line":"        return"},{"line_number":535,"context_line":"    thr_obj_id, thr_start \u003d (None, None)"},{"line_number":536,"context_line":"    while not is_stop.is_set():"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a26ad4f_e0542222","line":533,"updated":"2015-10-30 13:11:30.000000000","message":"How this can even be possible?","commit_id":"aa05c788cd8652914e419287669c06e4bd7cd980"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"e3208e288c9df134ddf46b529b8e896131f9804e","unresolved":false,"context_lines":[{"line_number":530,"context_line":"                    we exit from the function"},{"line_number":531,"context_line":"    \"\"\""},{"line_number":532,"context_line":""},{"line_number":533,"context_line":"    if not timeout:"},{"line_number":534,"context_line":"        return"},{"line_number":535,"context_line":"    thr_obj_id, thr_start \u003d (None, None)"},{"line_number":536,"context_line":"    while not is_stop.is_set():"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a26ad4f_063cd6c6","line":533,"in_reply_to":"1a26ad4f_e0542222","updated":"2015-10-30 14:17:04.000000000","message":"Agree. Need to add default value.","commit_id":"aa05c788cd8652914e419287669c06e4bd7cd980"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"e92ee94db9d6670b818fa0acee46267b0e22206a","unresolved":false,"context_lines":[{"line_number":533,"context_line":"    if not timeout:"},{"line_number":534,"context_line":"        return"},{"line_number":535,"context_line":"    thr_obj_id, thr_start \u003d (None, None)"},{"line_number":536,"context_line":"    while not is_stop.is_set():"},{"line_number":537,"context_line":"        if not thr_obj_id and not queue.empty():"},{"line_number":538,"context_line":"            thr_obj_id, thr_start \u003d queue.get()"},{"line_number":539,"context_line":"        if thr_obj_id and time.time() - thr_start \u003e\u003d timeout:"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a26ad4f_a3be0b63","line":536,"updated":"2015-11-02 13:57:27.000000000","message":"This loop will take 100% of cpu.\n\nThis may be avoided by using following algorithm:\n\n all_threads \u003d {}\n thread_id, deadline \u003d queue.get() #  we need at least one thread\n all_threads[thread_id] \u003d deadline\n while not is_stop.is_set():\n   earliest_thread \u003d min(all_threads.items(), key\u003dlambda x: x[1])\n   deadline, thread_id \u003d all_threads[earliest_thread]\n   new_thread \u003d queue.get(timeout\u003ddeadline-time.time())\n   if not new_thread:\n     # timeout occured. killing thread\n     kill_thread(thread_id)\n     all_threads.pop(thread_id)","commit_id":"aa05c788cd8652914e419287669c06e4bd7cd980"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"58eb12a113e65471782aecf7d167f6f5b6015e24","unresolved":false,"context_lines":[{"line_number":533,"context_line":"    if not timeout:"},{"line_number":534,"context_line":"        return"},{"line_number":535,"context_line":"    thr_obj_id, thr_start \u003d (None, None)"},{"line_number":536,"context_line":"    while not is_stop.is_set():"},{"line_number":537,"context_line":"        if not thr_obj_id and not queue.empty():"},{"line_number":538,"context_line":"            thr_obj_id, thr_start \u003d queue.get()"},{"line_number":539,"context_line":"        if thr_obj_id and time.time() - thr_start \u003e\u003d timeout:"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a26ad4f_edef0d85","line":536,"in_reply_to":"1a26ad4f_a3be0b63","updated":"2015-11-02 14:59:12.000000000","message":"Hmm. Scenario may be finished before blocking queue.get, so seems we a doomed to use time.sleep","commit_id":"aa05c788cd8652914e419287669c06e4bd7cd980"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"56da61b7dd871bf9f9d8eebe6989023de63f2f0b","unresolved":false,"context_lines":[{"line_number":473,"context_line":"    Terminates a python thread from another thread of the same process"},{"line_number":474,"context_line":"    raising async exception in the terminating thread."},{"line_number":475,"context_line":""},{"line_number":476,"context_line":"    :param thread_ref: the id of the threading.Thread instance"},{"line_number":477,"context_line":"    :param exc_type: an Exception object to be raised"},{"line_number":478,"context_line":"    \"\"\""},{"line_number":479,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_5e309d01","line":476,"updated":"2015-11-04 17:37:17.000000000","message":"s/thread_ref/thread_id/","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"80b4e75f05fee8d049a63bba59860b92b6c90f3e","unresolved":false,"context_lines":[{"line_number":473,"context_line":"    Terminates a python thread from another thread of the same process"},{"line_number":474,"context_line":"    raising async exception in the terminating thread."},{"line_number":475,"context_line":""},{"line_number":476,"context_line":"    :param thread_ref: the id of the threading.Thread instance"},{"line_number":477,"context_line":"    :param exc_type: an Exception object to be raised"},{"line_number":478,"context_line":"    \"\"\""},{"line_number":479,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_b14c5743","line":476,"in_reply_to":"fa80f949_5e309d01","updated":"2015-11-04 18:59:24.000000000","message":"Done","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"56da61b7dd871bf9f9d8eebe6989023de63f2f0b","unresolved":false,"context_lines":[{"line_number":474,"context_line":"    raising async exception in the terminating thread."},{"line_number":475,"context_line":""},{"line_number":476,"context_line":"    :param thread_ref: the id of the threading.Thread instance"},{"line_number":477,"context_line":"    :param exc_type: an Exception object to be raised"},{"line_number":478,"context_line":"    \"\"\""},{"line_number":479,"context_line":""},{"line_number":480,"context_line":"    thread \u003d ctypes.cast(thread_id, ctypes.py_object).value"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_d909072e","line":477,"updated":"2015-11-04 17:37:17.000000000","message":"The default value is an exception class, not an exception object. Should this read s/object/class/ ?","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"80b4e75f05fee8d049a63bba59860b92b6c90f3e","unresolved":false,"context_lines":[{"line_number":474,"context_line":"    raising async exception in the terminating thread."},{"line_number":475,"context_line":""},{"line_number":476,"context_line":"    :param thread_ref: the id of the threading.Thread instance"},{"line_number":477,"context_line":"    :param exc_type: an Exception object to be raised"},{"line_number":478,"context_line":"    \"\"\""},{"line_number":479,"context_line":""},{"line_number":480,"context_line":"    thread \u003d ctypes.cast(thread_id, ctypes.py_object).value"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_11452316","line":477,"in_reply_to":"fa80f949_d909072e","updated":"2015-11-04 18:59:24.000000000","message":"Done","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"56da61b7dd871bf9f9d8eebe6989023de63f2f0b","unresolved":false,"context_lines":[{"line_number":496,"context_line":"        raise SystemError(\"PyThreadState_SetAsyncExc failed\")"},{"line_number":497,"context_line":""},{"line_number":498,"context_line":""},{"line_number":499,"context_line":"def timeout_thr_closing(queue, is_stop, timeout\u003dNone):"},{"line_number":500,"context_line":"    \"\"\"Terminate threads by timeout."},{"line_number":501,"context_line":""},{"line_number":502,"context_line":"    Function need to be run in separate thread. Its designed to terminate"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_b93d23bd","line":499,"updated":"2015-11-04 17:37:17.000000000","message":"This function name is odd. Why not just \"timeout_thread()\"?","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"80b4e75f05fee8d049a63bba59860b92b6c90f3e","unresolved":false,"context_lines":[{"line_number":496,"context_line":"        raise SystemError(\"PyThreadState_SetAsyncExc failed\")"},{"line_number":497,"context_line":""},{"line_number":498,"context_line":""},{"line_number":499,"context_line":"def timeout_thr_closing(queue, is_stop, timeout\u003dNone):"},{"line_number":500,"context_line":"    \"\"\"Terminate threads by timeout."},{"line_number":501,"context_line":""},{"line_number":502,"context_line":"    Function need to be run in separate thread. Its designed to terminate"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_f1417f0c","line":499,"in_reply_to":"fa80f949_b93d23bd","updated":"2015-11-04 18:59:24.000000000","message":"Done","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"56da61b7dd871bf9f9d8eebe6989023de63f2f0b","unresolved":false,"context_lines":[{"line_number":507,"context_line":"    :param is_stop: threading.Event instance if its set then"},{"line_number":508,"context_line":"                    we exit from the function"},{"line_number":509,"context_line":"    :param timeout: timeout for threads in the queue after which"},{"line_number":510,"context_line":"                    threads must to be terminated"},{"line_number":511,"context_line":"    \"\"\""},{"line_number":512,"context_line":""},{"line_number":513,"context_line":"    if not timeout:"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_7947bb4b","line":510,"updated":"2015-11-04 17:37:17.000000000","message":"Would there be a use case for supplying the timeout as part of the tuple pushed onto the queue? That way a single timeout_thr_closing() thread could monitor multiple threads with different timeouts.\n\nOr, as Sergey suggested in a previous patchset, pass in (thread id, deadline) to the queue, and then you don\u0027t need the start time or timeout at all.","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"67c860cb1019ba722706513c535dd7ec5eb8ac6a","unresolved":false,"context_lines":[{"line_number":507,"context_line":"    :param is_stop: threading.Event instance if its set then"},{"line_number":508,"context_line":"                    we exit from the function"},{"line_number":509,"context_line":"    :param timeout: timeout for threads in the queue after which"},{"line_number":510,"context_line":"                    threads must to be terminated"},{"line_number":511,"context_line":"    \"\"\""},{"line_number":512,"context_line":""},{"line_number":513,"context_line":"    if not timeout:"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_e7fe9d6a","line":510,"in_reply_to":"fa80f949_51d72b23","updated":"2015-11-04 20:01:36.000000000","message":"Supplying a deadline shouldn\u0027t create any ugly if\u0027s -- it should actually simplify the code.","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"80b4e75f05fee8d049a63bba59860b92b6c90f3e","unresolved":false,"context_lines":[{"line_number":507,"context_line":"    :param is_stop: threading.Event instance if its set then"},{"line_number":508,"context_line":"                    we exit from the function"},{"line_number":509,"context_line":"    :param timeout: timeout for threads in the queue after which"},{"line_number":510,"context_line":"                    threads must to be terminated"},{"line_number":511,"context_line":"    \"\"\""},{"line_number":512,"context_line":""},{"line_number":513,"context_line":"    if not timeout:"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_51d72b23","line":510,"in_reply_to":"fa80f949_7947bb4b","updated":"2015-11-04 18:59:24.000000000","message":"But then would be ugly if\u0027s in runners. Therefore I should check there if timeout was specified or not. So I don\u0027t want to disfigure in runners just for not to pass int into function. That is why I don\u0027t what to do this change.","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"caeaa7b2a61c36366624c75ab58ec2a0fe0c3ad1","unresolved":false,"context_lines":[{"line_number":507,"context_line":"    :param is_stop: threading.Event instance if its set then"},{"line_number":508,"context_line":"                    we exit from the function"},{"line_number":509,"context_line":"    :param timeout: timeout for threads in the queue after which"},{"line_number":510,"context_line":"                    threads must to be terminated"},{"line_number":511,"context_line":"    \"\"\""},{"line_number":512,"context_line":""},{"line_number":513,"context_line":"    if not timeout:"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_d3eb0d77","line":510,"in_reply_to":"fa80f949_e7fe9d6a","updated":"2015-11-05 08:37:02.000000000","message":"http://ideone.com/pAjFVc here is an example how I think we will change constant runner after exclude timeout from parameter of the function.","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"1349bc1bec3f6347bddc4e3e6b8f5f13035c362d","unresolved":false,"context_lines":[{"line_number":496,"context_line":"        raise SystemError(\"PyThreadState_SetAsyncExc failed\")"},{"line_number":497,"context_line":""},{"line_number":498,"context_line":""},{"line_number":499,"context_line":"def timeout_thread(queue, is_stop, timeout\u003dNone):"},{"line_number":500,"context_line":"    \"\"\"Terminate threads by timeout."},{"line_number":501,"context_line":""},{"line_number":502,"context_line":"    Function need to be run in separate thread. Its designed to terminate"}],"source_content_type":"text/x-python","patch_set":13,"id":"fa80f949_17c16c80","line":499,"updated":"2015-11-05 16:05:08.000000000","message":"is_stop and timeout may be removed\n\nMain thread can put (thread_id, deadline) pairs in the queue.\n\nWhen scenario finished, main thread can put (None, None) in the queue, and join timeout_thread\n\ntimeout_thread may look like this:\n\n all_threads \u003d {}\n thread_id, deadline \u003d queue.get() #  we need at least one thread\n all_threads[thread_id] \u003d deadline\n while True:\n   earliest_thread \u003d min(all_threads.items(), key\u003dlambda x: x[1])\n   deadline, thread_id \u003d all_threads[earliest_thread]\n   new_pair \u003d queue.get(timeout\u003ddeadline-time.time())\n   if new_pair is None:\n     # timeout occured. killing thread\n     kill_thread(thread_id)\n     all_threads.pop(thread_id)\n   elif new_pair[0] is None:\n     return\n\nthoughts?","commit_id":"9de412644f253946e52d5d483abfa8561587d433"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"02495021f024bfd3ac9c5098ff10e5432d27d207","unresolved":false,"context_lines":[{"line_number":507,"context_line":"    :param is_stop: threading.Event instance if its set then"},{"line_number":508,"context_line":"                    we exit from the function"},{"line_number":509,"context_line":"    :param timeout: timeout for threads in the queue after which"},{"line_number":510,"context_line":"                    threads must to be terminated"},{"line_number":511,"context_line":"    \"\"\""},{"line_number":512,"context_line":""},{"line_number":513,"context_line":"    if not timeout:"}],"source_content_type":"text/x-python","patch_set":13,"id":"fa80f949_bc096adf","line":510,"updated":"2015-11-05 14:56:39.000000000","message":"Please use one of the two options that has been suggested to remove timeout as a keyword argument. There don\u0027t need to be any significant changes to the constant runner; you just change the data you put on the queue. Either put the timeout on the queue along with the thread id and start time, or put (thread_id, deadline) on the queue. E.g.: http://www.fpaste.org/287275/14467352/\n\nThere\u0027s no need to do anything special with timeout\u003d0 in either of the suggested approaches.","commit_id":"9de412644f253946e52d5d483abfa8561587d433"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"6ff7d8520d7d4481ba8621e00a2c474eda3ac32b","unresolved":false,"context_lines":[{"line_number":507,"context_line":"    :param is_stop: threading.Event instance if its set then"},{"line_number":508,"context_line":"                    we exit from the function"},{"line_number":509,"context_line":"    :param timeout: timeout for threads in the queue after which"},{"line_number":510,"context_line":"                    threads must to be terminated"},{"line_number":511,"context_line":"    \"\"\""},{"line_number":512,"context_line":""},{"line_number":513,"context_line":"    if not timeout:"}],"source_content_type":"text/x-python","patch_set":13,"id":"fa80f949_7e7e651a","line":510,"in_reply_to":"fa80f949_3774b3cd","updated":"2015-11-06 14:53:07.000000000","message":"The more I think about this, the more I think it\u0027s probably premature optimization. Since we don\u0027t have an immediate need to pass a timeout per thread, I\u0027m fine to leave this as-is.","commit_id":"9de412644f253946e52d5d483abfa8561587d433"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"73c4fac9a648866f58c36d79eef196c05e7ce2aa","unresolved":false,"context_lines":[{"line_number":507,"context_line":"    :param is_stop: threading.Event instance if its set then"},{"line_number":508,"context_line":"                    we exit from the function"},{"line_number":509,"context_line":"    :param timeout: timeout for threads in the queue after which"},{"line_number":510,"context_line":"                    threads must to be terminated"},{"line_number":511,"context_line":"    \"\"\""},{"line_number":512,"context_line":""},{"line_number":513,"context_line":"    if not timeout:"}],"source_content_type":"text/x-python","patch_set":13,"id":"fa80f949_3774b3cd","line":510,"in_reply_to":"fa80f949_bc096adf","updated":"2015-11-05 15:26:34.000000000","message":"In code that you post would be one thread that we don\u0027t need and queue that is also not used. In case of timeout 0.","commit_id":"9de412644f253946e52d5d483abfa8561587d433"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"4ec59f17a7eff6f6b4ebf6da8ff7c8bdd728fd83","unresolved":false,"context_lines":[{"line_number":523,"context_line":"        if next_thread:"},{"line_number":524,"context_line":"            thread_id, deadline \u003d next_thread"},{"line_number":525,"context_line":"        try:"},{"line_number":526,"context_line":"            next_thread \u003d queue.get(timeout\u003ddeadline - time.time())"},{"line_number":527,"context_line":"        except moves.queue.Empty as e:"},{"line_number":528,"context_line":"            # NOTE(rvasilets) its normal situation when queue is empty"},{"line_number":529,"context_line":"            next_thread \u003d queue.get(block\u003dTrue, timeout\u003dNone)"}],"source_content_type":"text/x-python","patch_set":15,"id":"da85f559_dcd787eb","line":526,"updated":"2015-11-10 14:37:52.000000000","message":"So if we got next_thread normally, then we should add it to all_threads by next line.","commit_id":"66d7e9830655f4f7813667cee50a1233e46fd5c7"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"4ec59f17a7eff6f6b4ebf6da8ff7c8bdd728fd83","unresolved":false,"context_lines":[{"line_number":525,"context_line":"        try:"},{"line_number":526,"context_line":"            next_thread \u003d queue.get(timeout\u003ddeadline - time.time())"},{"line_number":527,"context_line":"        except moves.queue.Empty as e:"},{"line_number":528,"context_line":"            # NOTE(rvasilets) its normal situation when queue is empty"},{"line_number":529,"context_line":"            next_thread \u003d queue.get(block\u003dTrue, timeout\u003dNone)"},{"line_number":530,"context_line":"            pass"},{"line_number":531,"context_line":"        if next_thread[0] is not None:"}],"source_content_type":"text/x-python","patch_set":15,"id":"da85f559_1c93cfa4","line":528,"updated":"2015-11-10 14:37:52.000000000","message":"It is not normal. If queue is empty then timeout was reached, and we should kill the thread and go next round of the loop","commit_id":"66d7e9830655f4f7813667cee50a1233e46fd5c7"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"4ec59f17a7eff6f6b4ebf6da8ff7c8bdd728fd83","unresolved":false,"context_lines":[{"line_number":526,"context_line":"            next_thread \u003d queue.get(timeout\u003ddeadline - time.time())"},{"line_number":527,"context_line":"        except moves.queue.Empty as e:"},{"line_number":528,"context_line":"            # NOTE(rvasilets) its normal situation when queue is empty"},{"line_number":529,"context_line":"            next_thread \u003d queue.get(block\u003dTrue, timeout\u003dNone)"},{"line_number":530,"context_line":"            pass"},{"line_number":531,"context_line":"        if next_thread[0] is not None:"},{"line_number":532,"context_line":"            # NOTE(rvasilets) timeout occurred. killing thread"}],"source_content_type":"text/x-python","patch_set":15,"id":"da85f559_1ce42f0b","line":529,"updated":"2015-11-10 14:37:52.000000000","message":"so here should be terminate_thread(thread_id)","commit_id":"66d7e9830655f4f7813667cee50a1233e46fd5c7"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"4ec59f17a7eff6f6b4ebf6da8ff7c8bdd728fd83","unresolved":false,"context_lines":[{"line_number":527,"context_line":"        except moves.queue.Empty as e:"},{"line_number":528,"context_line":"            # NOTE(rvasilets) its normal situation when queue is empty"},{"line_number":529,"context_line":"            next_thread \u003d queue.get(block\u003dTrue, timeout\u003dNone)"},{"line_number":530,"context_line":"            pass"},{"line_number":531,"context_line":"        if next_thread[0] is not None:"},{"line_number":532,"context_line":"            # NOTE(rvasilets) timeout occurred. killing thread"},{"line_number":533,"context_line":"            terminate_thread(thread_id)"}],"source_content_type":"text/x-python","patch_set":15,"id":"da85f559_9cbedfd2","line":530,"updated":"2015-11-10 14:37:52.000000000","message":"and please remove this","commit_id":"66d7e9830655f4f7813667cee50a1233e46fd5c7"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"4ec59f17a7eff6f6b4ebf6da8ff7c8bdd728fd83","unresolved":false,"context_lines":[{"line_number":529,"context_line":"            next_thread \u003d queue.get(block\u003dTrue, timeout\u003dNone)"},{"line_number":530,"context_line":"            pass"},{"line_number":531,"context_line":"        if next_thread[0] is not None:"},{"line_number":532,"context_line":"            # NOTE(rvasilets) timeout occurred. killing thread"},{"line_number":533,"context_line":"            terminate_thread(thread_id)"},{"line_number":534,"context_line":"            thread_id \u003d None"},{"line_number":535,"context_line":"        elif next_thread is (None, None,):"}],"source_content_type":"text/x-python","patch_set":15,"id":"da85f559_bca083a0","line":532,"updated":"2015-11-10 14:37:52.000000000","message":"This is not timeout. Timeout is handled in line 529, so 531-534 should be removed","commit_id":"66d7e9830655f4f7813667cee50a1233e46fd5c7"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"40c3ae011a705945c6b2a649536c05dc11b66807","unresolved":false,"context_lines":[{"line_number":497,"context_line":"    # NOTE(rvasilets) \u0027res\u0027 means the number of python thread states modified."},{"line_number":498,"context_line":"    # Here is called C API function (the black magic)."},{"line_number":499,"context_line":"    if res \u003d\u003d 0:"},{"line_number":500,"context_line":"        raise ValueError(\"nonexistent thread id\")"},{"line_number":501,"context_line":"    elif res \u003e 1:"},{"line_number":502,"context_line":"        # NOTE(rvasilets) if it returns a number greater than one, you\u0027re"},{"line_number":503,"context_line":"        # in trouble(changed bigger then one python thread state. Those can"}],"source_content_type":"text/x-python","patch_set":16,"id":"da85f559_c03c36ca","line":500,"updated":"2015-11-11 17:42:40.000000000","message":"There is no need to raise an exception here. It is not error, thread may be finished before we get to this line.","commit_id":"e82bc9c89d3c1249b95d77b5f02513fcceb0ad1c"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"2d69ffa844e788380472bc3f7a101ab8349f6389","unresolved":false,"context_lines":[{"line_number":520,"context_line":""},{"line_number":521,"context_line":"    all_threads \u003d collections.deque()"},{"line_number":522,"context_line":"    while True:"},{"line_number":523,"context_line":"        thread_id, deadline \u003d all_threads[0]"},{"line_number":524,"context_line":"        try:"},{"line_number":525,"context_line":"            next_thread \u003d queue.get(timeout\u003ddeadline - time.time())"},{"line_number":526,"context_line":"            all_threads.append(next_thread)"}],"source_content_type":"text/x-python","patch_set":16,"id":"da85f559_a5f7c457","line":523,"updated":"2015-11-11 17:39:33.000000000","message":"This will fail with IndexError, because this container may be empty (it is empty initially)\n\nWe should check for its length:\n\n if len(all_threads) \u003d\u003d 0:\n    timeout \u003d None\n else:\n    thread_id, deadline \u003d all_threads.popleft() # get less recent item\n    timeout \u003d deadline - time.time()\n ...\n queue.get(timeout\u003dtimeout)\n ...","commit_id":"e82bc9c89d3c1249b95d77b5f02513fcceb0ad1c"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"40c3ae011a705945c6b2a649536c05dc11b66807","unresolved":false,"context_lines":[{"line_number":531,"context_line":""},{"line_number":532,"context_line":"            terminate_thread(thread_id)"},{"line_number":533,"context_line":"            all_threads.popleft()"},{"line_number":534,"context_line":"            next_thread \u003d queue.get(block\u003dTrue, timeout\u003dNone)"},{"line_number":535,"context_line":"            all_threads.append(next_thread)"},{"line_number":536,"context_line":""},{"line_number":537,"context_line":"        if next_thread is (None, None,):"}],"source_content_type":"text/x-python","patch_set":16,"id":"da85f559_85040018","line":534,"updated":"2015-11-11 17:42:40.000000000","message":"There should be one queue.get in this method. In this block of code we should only try to kill timed out thread.","commit_id":"e82bc9c89d3c1249b95d77b5f02513fcceb0ad1c"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"bcc155d28ecdb561e90bb73a4d855359c93a72ee","unresolved":false,"context_lines":[{"line_number":519,"context_line":"                  thread id, timeout timestamp of the thread"},{"line_number":520,"context_line":"    \"\"\""},{"line_number":521,"context_line":""},{"line_number":522,"context_line":"    all_threads \u003d collections.deque()"},{"line_number":523,"context_line":"    while True:"},{"line_number":524,"context_line":"        if len(all_threads) \u003d\u003d 0:"},{"line_number":525,"context_line":"            timeout \u003d None"}],"source_content_type":"text/x-python","patch_set":17,"id":"da85f559_6a2d24a7","line":522,"updated":"2015-11-11 19:02:03.000000000","message":"we also need to add here thread_id \u003d None","commit_id":"843c1646848befead8d838d48a53f7a91a010f14"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"bcc155d28ecdb561e90bb73a4d855359c93a72ee","unresolved":false,"context_lines":[{"line_number":524,"context_line":"        if len(all_threads) \u003d\u003d 0:"},{"line_number":525,"context_line":"            timeout \u003d None"},{"line_number":526,"context_line":"        else:"},{"line_number":527,"context_line":"            thread_id, deadline \u003d all_threads[0]"},{"line_number":528,"context_line":"            timeout \u003d deadline - time.time()"},{"line_number":529,"context_line":"        try:"},{"line_number":530,"context_line":"            next_thread \u003d queue.get(timeout\u003dtimeout)"}],"source_content_type":"text/x-python","patch_set":17,"id":"da85f559_8afe48ac","line":527,"updated":"2015-11-11 19:02:03.000000000","message":"thread_id, deadline \u003d all_threads.popleft()","commit_id":"843c1646848befead8d838d48a53f7a91a010f14"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"bcc155d28ecdb561e90bb73a4d855359c93a72ee","unresolved":false,"context_lines":[{"line_number":525,"context_line":"            timeout \u003d None"},{"line_number":526,"context_line":"        else:"},{"line_number":527,"context_line":"            thread_id, deadline \u003d all_threads[0]"},{"line_number":528,"context_line":"            timeout \u003d deadline - time.time()"},{"line_number":529,"context_line":"        try:"},{"line_number":530,"context_line":"            next_thread \u003d queue.get(timeout\u003dtimeout)"},{"line_number":531,"context_line":"            all_threads.append(next_thread)"}],"source_content_type":"text/x-python","patch_set":17,"id":"da85f559_ca3e9027","line":528,"updated":"2015-11-11 19:02:03.000000000","message":"We also need to check if we are still waiting for some thread. So code will look like this:\n\n if thread_id:\n  timeout \u003d deadline - time.time()\n elif len(all_threads) \u003d\u003d 0:\n  timeout \u003d None\n else:\n   thread_id, deadline \u003d all_threads.popleft()\n   timeout \u003d deadline - time.time()","commit_id":"843c1646848befead8d838d48a53f7a91a010f14"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"bcc155d28ecdb561e90bb73a4d855359c93a72ee","unresolved":false,"context_lines":[{"line_number":534,"context_line":"            # ValueError means that timeout lower then 0 and the"},{"line_number":535,"context_line":"            # thread was already terminated."},{"line_number":536,"context_line":""},{"line_number":537,"context_line":"            terminate_thread(thread_id)"},{"line_number":538,"context_line":"            all_threads.popleft()"},{"line_number":539,"context_line":"            next_thread \u003d queue.get(block\u003dTrue, timeout\u003dNone)"},{"line_number":540,"context_line":"            all_threads.append(next_thread)"}],"source_content_type":"text/x-python","patch_set":17,"id":"da85f559_0d2352a8","line":537,"updated":"2015-11-11 19:02:03.000000000","message":"we are not waiting for this thread annymore, so we should also set thread_id to None","commit_id":"843c1646848befead8d838d48a53f7a91a010f14"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"bcc155d28ecdb561e90bb73a4d855359c93a72ee","unresolved":false,"context_lines":[{"line_number":535,"context_line":"            # thread was already terminated."},{"line_number":536,"context_line":""},{"line_number":537,"context_line":"            terminate_thread(thread_id)"},{"line_number":538,"context_line":"            all_threads.popleft()"},{"line_number":539,"context_line":"            next_thread \u003d queue.get(block\u003dTrue, timeout\u003dNone)"},{"line_number":540,"context_line":"            all_threads.append(next_thread)"},{"line_number":541,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"da85f559_6aef64e9","line":538,"updated":"2015-11-11 19:02:03.000000000","message":"there should be one place with popleft() (line 527)","commit_id":"843c1646848befead8d838d48a53f7a91a010f14"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"bcc155d28ecdb561e90bb73a4d855359c93a72ee","unresolved":false,"context_lines":[{"line_number":536,"context_line":""},{"line_number":537,"context_line":"            terminate_thread(thread_id)"},{"line_number":538,"context_line":"            all_threads.popleft()"},{"line_number":539,"context_line":"            next_thread \u003d queue.get(block\u003dTrue, timeout\u003dNone)"},{"line_number":540,"context_line":"            all_threads.append(next_thread)"},{"line_number":541,"context_line":""},{"line_number":542,"context_line":"        if next_thread is (None, None,):"}],"source_content_type":"text/x-python","patch_set":17,"id":"da85f559_0ab7b8f5","line":539,"updated":"2015-11-11 19:02:03.000000000","message":"there should be one place with queue.get (line 530)","commit_id":"843c1646848befead8d838d48a53f7a91a010f14"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"b23ba368692aba6987f1b1c1db008c61a05d7ad6","unresolved":false,"context_lines":[{"line_number":520,"context_line":"    \"\"\""},{"line_number":521,"context_line":""},{"line_number":522,"context_line":"    all_threads \u003d collections.deque()"},{"line_number":523,"context_line":"    thread_id \u003d None"},{"line_number":524,"context_line":"    while True:"},{"line_number":525,"context_line":"        if len(all_threads) \u003d\u003d 0:"},{"line_number":526,"context_line":"            timeout \u003d None"}],"source_content_type":"text/x-python","patch_set":18,"id":"da85f559_92ade8ea","line":523,"updated":"2015-11-12 16:08:27.000000000","message":"Hm. Seems this line is not needed","commit_id":"aae6a87d5ecf05e0b86441b4a826fcca12b83387"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"b23ba368692aba6987f1b1c1db008c61a05d7ad6","unresolved":false,"context_lines":[{"line_number":533,"context_line":"        except (moves.queue.Empty, ValueError):"},{"line_number":534,"context_line":"            # NOTE(rvasilets) Empty means that timeout was occurred."},{"line_number":535,"context_line":"            # ValueError means that timeout lower then 0 and the"},{"line_number":536,"context_line":"            # thread was already terminated."},{"line_number":537,"context_line":""},{"line_number":538,"context_line":"            terminate_thread(thread_id)"},{"line_number":539,"context_line":"            all_threads.popleft()"}],"source_content_type":"text/x-python","patch_set":18,"id":"da85f559_b297cc38","line":536,"updated":"2015-11-12 16:08:27.000000000","message":"ValueError means that timeout lower then 0. Thats all. Thread may be still alive.","commit_id":"aae6a87d5ecf05e0b86441b4a826fcca12b83387"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"b23ba368692aba6987f1b1c1db008c61a05d7ad6","unresolved":false,"context_lines":[{"line_number":537,"context_line":""},{"line_number":538,"context_line":"            terminate_thread(thread_id)"},{"line_number":539,"context_line":"            all_threads.popleft()"},{"line_number":540,"context_line":"            all_threads.append(next_thread)"},{"line_number":541,"context_line":""},{"line_number":542,"context_line":"        if next_thread is (None, None,):"},{"line_number":543,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":18,"id":"da85f559_975cfa4b","line":540,"updated":"2015-11-12 16:08:27.000000000","message":"And this too","commit_id":"aae6a87d5ecf05e0b86441b4a826fcca12b83387"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"f79089953366dcfc402443a8a3ec7c3335dcfbd3","unresolved":false,"context_lines":[{"line_number":487,"context_line":"    :param exc_type: an Exception class to be raised"},{"line_number":488,"context_line":"    \"\"\""},{"line_number":489,"context_line":""},{"line_number":490,"context_line":"    thread \u003d ctypes.cast(thread_id, ctypes.py_object).value"},{"line_number":491,"context_line":"    if not thread.isAlive():"},{"line_number":492,"context_line":"        return"},{"line_number":493,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba8a016a_faeb8f10","line":490,"updated":"2015-11-23 12:51:21.000000000","message":"we can pass in this method thread.ident instead of id(thread)","commit_id":"89bd36b25687b628cac07547c49ea86c321e0e31"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"76650b1651044224c7b260d17560c05ba3f4921d","unresolved":false,"context_lines":[{"line_number":487,"context_line":"    :param exc_type: an Exception class to be raised"},{"line_number":488,"context_line":"    \"\"\""},{"line_number":489,"context_line":""},{"line_number":490,"context_line":"    thread \u003d ctypes.cast(thread_id, ctypes.py_object).value"},{"line_number":491,"context_line":"    if not thread.isAlive():"},{"line_number":492,"context_line":"        return"},{"line_number":493,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba8a016a_4970a9a4","line":490,"in_reply_to":"ba8a016a_faeb8f10","updated":"2015-11-24 08:54:30.000000000","message":"Yes we can. Do you want to use you method instead of mine? Why its better?","commit_id":"89bd36b25687b628cac07547c49ea86c321e0e31"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"f79089953366dcfc402443a8a3ec7c3335dcfbd3","unresolved":false,"context_lines":[{"line_number":488,"context_line":"    \"\"\""},{"line_number":489,"context_line":""},{"line_number":490,"context_line":"    thread \u003d ctypes.cast(thread_id, ctypes.py_object).value"},{"line_number":491,"context_line":"    if not thread.isAlive():"},{"line_number":492,"context_line":"        return"},{"line_number":493,"context_line":""},{"line_number":494,"context_line":"    res \u003d ctypes.pythonapi.PyThreadState_SetAsyncExc("}],"source_content_type":"text/x-python","patch_set":21,"id":"ba8a016a_fad2af5a","line":491,"updated":"2015-11-23 12:51:21.000000000","message":"This is not necessary. Thread may exit just after this line","commit_id":"89bd36b25687b628cac07547c49ea86c321e0e31"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"f79089953366dcfc402443a8a3ec7c3335dcfbd3","unresolved":false,"context_lines":[{"line_number":498,"context_line":"    if res \u003d\u003d 0:"},{"line_number":499,"context_line":"        LOG.warning(\"Nonexistent thread id. Possibly thread was\""},{"line_number":500,"context_line":"                    \"terminated by his own.\")"},{"line_number":501,"context_line":"    elif res \u003e 1:"},{"line_number":502,"context_line":"        # NOTE(rvasilets) if it returns a number greater than one, you\u0027re"},{"line_number":503,"context_line":"        # in trouble(changed bigger then one python thread state. Those can"},{"line_number":504,"context_line":"        # mutate the list of thread states we\u0027re traversing), and you"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba8a016a_fabcefdc","line":501,"updated":"2015-11-23 12:51:21.000000000","message":"res may be either 0 or 1\n\nhttps://github.com/python/cpython/blob/1fe0fd9feb6a4472a9a1b186502eb9c0b2366326/Python/pystate.c#L561-L594","commit_id":"89bd36b25687b628cac07547c49ea86c321e0e31"},{"author":{"_account_id":8491,"name":"Illia Khudoshyn","email":"ikhudoshyn@mirantis.com","username":"ikhudoshyn"},"change_message_id":"6753291ea3ee95516534a6b30b18ae2d29428d1f","unresolved":false,"context_lines":[{"line_number":512,"context_line":"    \"\"\"Terminate threads by timeout."},{"line_number":513,"context_line":""},{"line_number":514,"context_line":"    Function need to be run in separate thread. Its designed to terminate"},{"line_number":515,"context_line":"    threads in the same process which are run longer then timeout."},{"line_number":516,"context_line":""},{"line_number":517,"context_line":"    :param queue: Queue contained tuples of"},{"line_number":518,"context_line":"                  thread id, timeout timestamp of the thread"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba8a016a_79e7b040","line":515,"updated":"2015-11-23 12:26:29.000000000","message":"which are run -\u003e which are running","commit_id":"89bd36b25687b628cac07547c49ea86c321e0e31"},{"author":{"_account_id":8491,"name":"Illia Khudoshyn","email":"ikhudoshyn@mirantis.com","username":"ikhudoshyn"},"change_message_id":"6753291ea3ee95516534a6b30b18ae2d29428d1f","unresolved":false,"context_lines":[{"line_number":514,"context_line":"    Function need to be run in separate thread. Its designed to terminate"},{"line_number":515,"context_line":"    threads in the same process which are run longer then timeout."},{"line_number":516,"context_line":""},{"line_number":517,"context_line":"    :param queue: Queue contained tuples of"},{"line_number":518,"context_line":"                  thread id, timeout timestamp of the thread"},{"line_number":519,"context_line":"    \"\"\""},{"line_number":520,"context_line":""}],"source_content_type":"text/x-python","patch_set":21,"id":"ba8a016a_59d3cc5f","line":517,"updated":"2015-11-23 12:26:29.000000000","message":"contained -\u003e containing","commit_id":"89bd36b25687b628cac07547c49ea86c321e0e31"},{"author":{"_account_id":8491,"name":"Illia Khudoshyn","email":"ikhudoshyn@mirantis.com","username":"ikhudoshyn"},"change_message_id":"6753291ea3ee95516534a6b30b18ae2d29428d1f","unresolved":false,"context_lines":[{"line_number":536,"context_line":"            all_threads.popleft()"},{"line_number":537,"context_line":""},{"line_number":538,"context_line":"        if next_thread \u003d\u003d (None, None,):"},{"line_number":539,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba8a016a_3405adc1","line":539,"updated":"2015-11-23 12:26:29.000000000","message":"Consider the following scenario:\nThis thread reads several (5..10..20) tread_ids\u0026timeouts from \u0027queue\u0027 w/o any error, appends it to \u0027all_threads\u0027, gets (None, None,) and returns.\nNo thread gets killed.\nThis does not look like a behavior we expect here.","commit_id":"89bd36b25687b628cac07547c49ea86c321e0e31"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"f79089953366dcfc402443a8a3ec7c3335dcfbd3","unresolved":false,"context_lines":[{"line_number":536,"context_line":"            all_threads.popleft()"},{"line_number":537,"context_line":""},{"line_number":538,"context_line":"        if next_thread \u003d\u003d (None, None,):"},{"line_number":539,"context_line":"            return"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba8a016a_b4f8bd7d","line":539,"in_reply_to":"ba8a016a_3405adc1","updated":"2015-11-23 12:51:21.000000000","message":"This thread get (None, None) when scenario is finished and all threads are exited and joined. There is nothing to kill.","commit_id":"89bd36b25687b628cac07547c49ea86c321e0e31"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"b60debc85e24132a5bd4a36779379026ac47d2f8","unresolved":false,"context_lines":[{"line_number":518,"context_line":"    :param exc_type: an Exception class to be raised"},{"line_number":519,"context_line":"    \"\"\""},{"line_number":520,"context_line":""},{"line_number":521,"context_line":"    thread \u003d ctypes.cast(thread_id, ctypes.py_object).value"},{"line_number":522,"context_line":""},{"line_number":523,"context_line":"    res \u003d ctypes.pythonapi.PyThreadState_SetAsyncExc("},{"line_number":524,"context_line":"        ctypes.c_long(thread.ident), ctypes.py_object(exc_type))"}],"source_content_type":"text/x-python","patch_set":23,"id":"9a8ffd7b_89adad33","line":521,"updated":"2015-11-24 12:55:54.000000000","message":"Passing thread.ident is better because then we can remove this line and just use thread.ident in line 524\n\nYour methods is literally doing this:\n\n thread \u003d Thread() # got Thread instance\n thread_id \u003d id(thread)\n thread \u003d ctypes.cast(thread_id, ctypes.py_object).value # got Thread instance\n ident \u003d thread.ident\n\nI just want to skip all this unnecessary steps, and just do\n\n thread \u003d Thread()\n ident \u003d thread.ident","commit_id":"b2c0417719e38c902b97598a5ad697fa8e1d705c"},{"author":{"_account_id":6835,"name":"Kun Huang","email":"gareth@openstacker.org","username":"academicgareth"},"change_message_id":"b4fbd0771aaa109dab3d3b999dd58d00554eeff7","unresolved":false,"context_lines":[{"line_number":484,"context_line":"        raise ValueError(\"sleep_time should be \u003e\u003d 0\")"},{"line_number":485,"context_line":""},{"line_number":486,"context_line":""},{"line_number":487,"context_line":"def terminate_thread(thread_ident, exc_type\u003dexceptions.ThreadTimeoutException):"},{"line_number":488,"context_line":"    \"\"\"Terminate a python thread."},{"line_number":489,"context_line":""},{"line_number":490,"context_line":"    Use PyThreadState_SetAsyncExc to terminate thread."}],"source_content_type":"text/x-python","patch_set":35,"id":"9a8ffd7b_2fe637b0","line":487,"updated":"2015-12-03 14:17:52.000000000","message":"is it possible to use thread.exit?\n\nhttps://docs.python.org/2/library/thread.html#thread.exit\n\nusing cpython api is hard to review in the future...","commit_id":"02c4d40ad992523650e9ad1e184d6984b2c87c38"}],"rally/exceptions.py":[{"author":{"_account_id":10475,"name":"Alexander Maretskiy","email":"amaretskiy@mirantis.com","username":"maretskiy"},"change_message_id":"3f934ac4666584133ce6e3fafb7a3423d7e14353","unresolved":false,"context_lines":[{"line_number":79,"context_line":"    msg_fmt \u003d _(\"The resource can not be found: %(message)s\")"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"class ThreadTimeoutException(RallyException):"},{"line_number":83,"context_line":"    msg_fmt \u003d _(\"Iteration interrupted due to timeout.\")"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"9a8ffd7b_5dfb6cc1","line":82,"updated":"2015-12-02 17:29:05.000000000","message":"Can we reuse TimeoutException? (we are actually on our way to reduce number of exceptions)","commit_id":"02c4d40ad992523650e9ad1e184d6984b2c87c38"},{"author":{"_account_id":9545,"name":"Andriy Kurilin","email":"andr.kurilin@gmail.com","username":"akurilin"},"change_message_id":"e6601ffc1937f5c83ef01417224d1d99ddf85f78","unresolved":false,"context_lines":[{"line_number":79,"context_line":"    msg_fmt \u003d _(\"The resource can not be found: %(message)s\")"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"class ThreadTimeoutException(RallyException):"},{"line_number":83,"context_line":"    msg_fmt \u003d _(\"Iteration interrupted due to timeout.\")"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"9a8ffd7b_946c1dd1","line":82,"in_reply_to":"9a8ffd7b_1e8e352e","updated":"2015-12-03 12:32:11.000000000","message":"The main idea is not to reduce number of exceptions or not to increase number of exceptions:) We should remove/replace all custom exceptions and not add new ones if it used only in one place.\nImo, most of exception classes can be replaced by RallyException + proper message.","commit_id":"02c4d40ad992523650e9ad1e184d6984b2c87c38"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"63e04d3b4e08dc475410517ccc9b66928277acef","unresolved":false,"context_lines":[{"line_number":79,"context_line":"    msg_fmt \u003d _(\"The resource can not be found: %(message)s\")"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"class ThreadTimeoutException(RallyException):"},{"line_number":83,"context_line":"    msg_fmt \u003d _(\"Iteration interrupted due to timeout.\")"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":""}],"source_content_type":"text/x-python","patch_set":35,"id":"9a8ffd7b_1e8e352e","line":82,"in_reply_to":"9a8ffd7b_5dfb6cc1","updated":"2015-12-02 19:39:35.000000000","message":"We are on the way not to reduce but not to increase number of exceptions if its possible. In cause of usage this exception we don\u0027t have any information about exception(exception message) except its name. So just TimeoutException vs ThreadTimeoutException name inside thread. 1st name could relate to any timeout during scenario execution. 2st name is more specific. To summarize when this exception would raised we will see only its name! Anyway I don\u0027t think that this a reason to block such a huge change. We could fix this later in another patch.","commit_id":"02c4d40ad992523650e9ad1e184d6984b2c87c38"}],"tests/unit/common/test_utils.py":[{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"56da61b7dd871bf9f9d8eebe6989023de63f2f0b","unresolved":false,"context_lines":[{"line_number":477,"context_line":"            mock_pythonapi.PyThreadState_SetAsyncExc.assert_called_once_with("},{"line_number":478,"context_line":"                42, fake_py_object)"},{"line_number":479,"context_line":"            self.assertEqual("},{"line_number":480,"context_line":"                1, mock_pythonapi.PyThreadState_SetAsyncExc.called)"},{"line_number":481,"context_line":"        elif pthread_state \u003d\u003d 0:"},{"line_number":482,"context_line":"            self.assertRaises("},{"line_number":483,"context_line":"                ValueError, utils.terminate_thread, \"fake_thread_id\")"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_1938ef9f","line":480,"updated":"2015-11-04 17:37:17.000000000","message":"Check the mock_py_object call as well.\n\nAlso, add a test that passes in an exc_type kwarg to terminate_thread to ensure that it\u0027s honored.","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"fdec82c211cf4e438194e93329db229b1b248b20","unresolved":false,"context_lines":[{"line_number":477,"context_line":"            mock_pythonapi.PyThreadState_SetAsyncExc.assert_called_once_with("},{"line_number":478,"context_line":"                42, fake_py_object)"},{"line_number":479,"context_line":"            self.assertEqual("},{"line_number":480,"context_line":"                1, mock_pythonapi.PyThreadState_SetAsyncExc.called)"},{"line_number":481,"context_line":"        elif pthread_state \u003d\u003d 0:"},{"line_number":482,"context_line":"            self.assertRaises("},{"line_number":483,"context_line":"                ValueError, utils.terminate_thread, \"fake_thread_id\")"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_8e6eba94","line":480,"in_reply_to":"fa80f949_1938ef9f","updated":"2015-11-05 08:51:05.000000000","message":"Done","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"}],"tests/unit/plugins/common/runners/test_constant.py":[{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"56da61b7dd871bf9f9d8eebe6989023de63f2f0b","unresolved":false,"context_lines":[{"line_number":72,"context_line":"                                 context, \"Dummy\", \"dummy\", (), mock_event,"},{"line_number":73,"context_line":"                                 info)"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        self.assertEqual(times + 1, mock_thread.call_count)"},{"line_number":76,"context_line":"        self.assertEqual(times + 1, mock_thread_instance.start.call_count)"},{"line_number":77,"context_line":"        self.assertEqual(times + 1, mock_thread_instance.join.call_count)"},{"line_number":78,"context_line":"        self.assertEqual(times, mock_runner._get_scenario_context.call_count)"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_f912cb08","line":75,"updated":"2015-11-04 17:37:17.000000000","message":"Add a comment here to explain why we expect times + 1.\n\nOr, much better yet, check the actual calls to these functions. There\u0027s a sort of half-hearted attempt do to that with mock_thread() below, but it should use assert_has_calls() instead, and there\u0027s no effort with the other functions.","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"caeaa7b2a61c36366624c75ab58ec2a0fe0c3ad1","unresolved":false,"context_lines":[{"line_number":72,"context_line":"                                 context, \"Dummy\", \"dummy\", (), mock_event,"},{"line_number":73,"context_line":"                                 info)"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        self.assertEqual(times + 1, mock_thread.call_count)"},{"line_number":76,"context_line":"        self.assertEqual(times + 1, mock_thread_instance.start.call_count)"},{"line_number":77,"context_line":"        self.assertEqual(times + 1, mock_thread_instance.join.call_count)"},{"line_number":78,"context_line":"        self.assertEqual(times, mock_runner._get_scenario_context.call_count)"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_b39f6902","line":75,"in_reply_to":"fa80f949_874551b4","updated":"2015-11-05 08:37:02.000000000","message":"Okey, I will left here comment.","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"67c860cb1019ba722706513c535dd7ec5eb8ac6a","unresolved":false,"context_lines":[{"line_number":72,"context_line":"                                 context, \"Dummy\", \"dummy\", (), mock_event,"},{"line_number":73,"context_line":"                                 info)"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        self.assertEqual(times + 1, mock_thread.call_count)"},{"line_number":76,"context_line":"        self.assertEqual(times + 1, mock_thread_instance.start.call_count)"},{"line_number":77,"context_line":"        self.assertEqual(times + 1, mock_thread_instance.join.call_count)"},{"line_number":78,"context_line":"        self.assertEqual(times, mock_runner._get_scenario_context.call_count)"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_874551b4","line":75,"in_reply_to":"fa80f949_91c0332c","updated":"2015-11-04 20:01:36.000000000","message":"If you don\u0027t want to comment this, then please make the tests more complete. It will not be obvious to anyone reading this code at a later date what the +1 is for.\n\nAnd honestly, more comments in all of Rally would certainly not hurt it. That sounds like an excellent suggestion.","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"},{"author":{"_account_id":12395,"name":"Roman Vasylets","email":"pomeo92@gmail.com","username":"rvasilets"},"change_message_id":"80b4e75f05fee8d049a63bba59860b92b6c90f3e","unresolved":false,"context_lines":[{"line_number":72,"context_line":"                                 context, \"Dummy\", \"dummy\", (), mock_event,"},{"line_number":73,"context_line":"                                 info)"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        self.assertEqual(times + 1, mock_thread.call_count)"},{"line_number":76,"context_line":"        self.assertEqual(times + 1, mock_thread_instance.start.call_count)"},{"line_number":77,"context_line":"        self.assertEqual(times + 1, mock_thread_instance.join.call_count)"},{"line_number":78,"context_line":"        self.assertEqual(times, mock_runner._get_scenario_context.call_count)"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_91c0332c","line":75,"in_reply_to":"fa80f949_f912cb08","updated":"2015-11-04 18:59:24.000000000","message":"I don\u0027t think that I must left comment or Notes to expected values in unit tests. If its unclear why \u0027times + 1\u0027 then please read the code(its preferable) or let us make such work by the whole Rally for consistence.","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"02495021f024bfd3ac9c5098ff10e5432d27d207","unresolved":false,"context_lines":[{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        self.assertEqual(5, mock_thread.call_count)"},{"line_number":76,"context_line":"        self.assertEqual(5, mock_thread_instance.start.call_count)"},{"line_number":77,"context_line":"        self.assertEqual(5, mock_thread_instance.join.call_count)"},{"line_number":78,"context_line":"        self.assertEqual(times, mock_runner._get_scenario_context.call_count)"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"        for i in range(times):"}],"source_content_type":"text/x-python","patch_set":13,"id":"fa80f949_fcedb2ef","line":77,"updated":"2015-11-05 14:56:39.000000000","message":"Let\u0027s just fix these assertions to check the actual calls instead of trying to find the least-unreadable way to check something proximate to what we actually care about.","commit_id":"9de412644f253946e52d5d483abfa8561587d433"},{"author":{"_account_id":8491,"name":"Illia Khudoshyn","email":"ikhudoshyn@mirantis.com","username":"ikhudoshyn"},"change_message_id":"6753291ea3ee95516534a6b30b18ae2d29428d1f","unresolved":false,"context_lines":[{"line_number":72,"context_line":"                                 context, \"Dummy\", \"dummy\", (), mock_event,"},{"line_number":73,"context_line":"                                 info)"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        self.assertEqual(5, mock_thread.call_count)"},{"line_number":76,"context_line":"        self.assertEqual(5, mock_thread_instance.start.call_count)"},{"line_number":77,"context_line":"        self.assertEqual(5, mock_thread_instance.join.call_count)"},{"line_number":78,"context_line":"        self.assertEqual(times, mock_runner._get_scenario_context.call_count)"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba8a016a_be25fec2","line":75,"updated":"2015-11-23 12:26:29.000000000","message":"is it \u0027times +1\u0027 or some other magic?","commit_id":"89bd36b25687b628cac07547c49ea86c321e0e31"}],"tests/unit/plugins/common/runners/test_rps.py":[{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"56da61b7dd871bf9f9d8eebe6989023de63f2f0b","unresolved":false,"context_lines":[{"line_number":105,"context_line":"        self.assertEqual(times + 1, mock_thread_instance.start.call_count)"},{"line_number":106,"context_line":"        self.assertEqual(times + 1, mock_thread_instance.join.call_count)"},{"line_number":107,"context_line":"        self.assertEqual(1, mock_time.sleep.call_count)"},{"line_number":108,"context_line":"        self.assertEqual(2, mock_thread_instance.isAlive.call_count)"},{"line_number":109,"context_line":"        self.assertEqual(times * 4 - 1, mock_time.time.count)"},{"line_number":110,"context_line":"        self.assertEqual(times, mock_runner._get_scenario_context.call_count)"},{"line_number":111,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"fa80f949_590437bf","line":108,"updated":"2015-11-04 17:37:17.000000000","message":"Same here.","commit_id":"3357caea11d47e129d8217854f9a1071de1d8320"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"738a0aef84019a767ca815134eb2acd4a8d9f738","unresolved":false,"context_lines":[{"line_number":104,"context_line":"        self.assertEqual(times + 1, mock_thread.call_count)"},{"line_number":105,"context_line":"        self.assertEqual(times + 1, mock_thread_instance.start.call_count)"},{"line_number":106,"context_line":"        self.assertEqual(times + 1, mock_thread_instance.join.call_count)"},{"line_number":107,"context_line":"        # NOTE(rvasilets) If its not clear why here is times + 1."},{"line_number":108,"context_line":"        # Then please see the code and try to find there one more call"},{"line_number":109,"context_line":"        self.assertEqual(1, mock_time.sleep.call_count)"},{"line_number":110,"context_line":"        self.assertEqual(2, mock_thread_instance.isAlive.call_count)"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa80f949_49da097a","line":107,"updated":"2015-11-05 10:35:38.000000000","message":"this comment is useless","commit_id":"3c5f04850e0fc19b255904cac6b82f35c0239d8d"},{"author":{"_account_id":7369,"name":"Sergey Skripnick","email":"sskripnick@mirantis.com","username":"redixin"},"change_message_id":"738a0aef84019a767ca815134eb2acd4a8d9f738","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        self.assertEqual(2, mock_thread_instance.isAlive.call_count)"},{"line_number":111,"context_line":"        self.assertEqual(times * 4 - 1, mock_time.time.count)"},{"line_number":112,"context_line":"        self.assertEqual(times, mock_runner._get_scenario_context.call_count)"},{"line_number":113,"context_line":"        # NOTE(rvasilets) If you not understand why here is such constants"},{"line_number":114,"context_line":"        # then try to count proper mock calls"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"        for i in range(times):"}],"source_content_type":"text/x-python","patch_set":12,"id":"fa80f949_69acada0","line":113,"updated":"2015-11-05 10:35:38.000000000","message":"ditto","commit_id":"3c5f04850e0fc19b255904cac6b82f35c0239d8d"},{"author":{"_account_id":11748,"name":"Chris St. Pierre","email":"cstpierr@cisco.com","username":"stpierre"},"change_message_id":"02495021f024bfd3ac9c5098ff10e5432d27d207","unresolved":false,"context_lines":[{"line_number":106,"context_line":"        self.assertEqual(5, mock_thread_instance.join.call_count)"},{"line_number":107,"context_line":"        self.assertEqual(1, mock_time.sleep.call_count)"},{"line_number":108,"context_line":"        self.assertEqual(2, mock_thread_instance.isAlive.call_count)"},{"line_number":109,"context_line":"        self.assertEqual(15, mock_time.time.count)"},{"line_number":110,"context_line":"        self.assertEqual(times, mock_runner._get_scenario_context.call_count)"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"        for i in range(times):"}],"source_content_type":"text/x-python","patch_set":13,"id":"fa80f949_dcc9ce79","line":109,"updated":"2015-11-05 14:56:39.000000000","message":"Same here. It\u0027s still unobvious where these numbers come from. (Perhaps even less obvious than it was before with math around \u0027times\u0027.)","commit_id":"9de412644f253946e52d5d483abfa8561587d433"},{"author":{"_account_id":8491,"name":"Illia Khudoshyn","email":"ikhudoshyn@mirantis.com","username":"ikhudoshyn"},"change_message_id":"6753291ea3ee95516534a6b30b18ae2d29428d1f","unresolved":false,"context_lines":[{"line_number":106,"context_line":"        self.assertEqual(5, mock_thread_instance.join.call_count)"},{"line_number":107,"context_line":"        self.assertEqual(1, mock_time.sleep.call_count)"},{"line_number":108,"context_line":"        self.assertEqual(2, mock_thread_instance.isAlive.call_count)"},{"line_number":109,"context_line":"        self.assertEqual(15, mock_time.time.count)"},{"line_number":110,"context_line":"        self.assertEqual(times, mock_runner._get_scenario_context.call_count)"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"        for i in range(times):"}],"source_content_type":"text/x-python","patch_set":21,"id":"ba8a016a_5e1bb280","line":109,"updated":"2015-11-23 12:26:29.000000000","message":"Why all these numbers are here?","commit_id":"89bd36b25687b628cac07547c49ea86c321e0e31"}]}
