)]}'
{"swift/common/daemon.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b5a4fc815b89ea9b44fd6faee9e42b88c407c160","unresolved":false,"context_lines":[{"line_number":56,"context_line":"        else:"},{"line_number":57,"context_line":"            run_func \u003d self.run_forever"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"        tpool.execute(run_func, **kwargs)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"def run_daemon(klass, conf_file, section_name\u003d\u0027\u0027, once\u003dFalse, **kwargs):"}],"source_content_type":"text/x-python","patch_set":4,"id":"fa69d971_6258de8a","line":59,"updated":"2016-01-11 20:12:11.000000000","message":"So using a system thread will mean that any signal will be handled here and terminate the thread actually doing the daemon work?\n\nWhat\u0027s the overhead?\n\nMaybe InternalClient\u0027s shouldn\u0027t be trapping SystemExit - remove catch_errors?","commit_id":"01677babea1e46e54932631c9d0344f090b82c9a"},{"author":{"_account_id":12193,"name":"Hisashi Osanai","email":"osanai.hisashi@jp.fujitsu.com","username":"ho"},"change_message_id":"0c01c8171ad8309c837e8352abb37a962a7ebc0e","unresolved":false,"context_lines":[{"line_number":56,"context_line":"        else:"},{"line_number":57,"context_line":"            run_func \u003d self.run_forever"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"        tpool.execute(run_func, **kwargs)"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"def run_daemon(klass, conf_file, section_name\u003d\u0027\u0027, once\u003dFalse, **kwargs):"}],"source_content_type":"text/x-python","patch_set":4,"id":"da6ed579_18aa711a","line":59,"in_reply_to":"fa69d971_6258de8a","updated":"2016-01-12 02:27:36.000000000","message":"Yeah, a native thread for run_func is doing the daemon work and this main thread is waiting for finishing the daemon work.\nCompare to current master, this patch introduces tpool here so I think this (using a native thread in addition to main thread) is an overhead for the system. But I don\u0027t think there is big overhead.\nI thought a similar fix, remove SystemExit handling from catch_errors, I prefer to modify the Daemon class because if we enhance some functions using this Daemon class, we might have same problem in the future but Daemon class has signal handling that doesn\u0027t get influence from other logic.","commit_id":"01677babea1e46e54932631c9d0344f090b82c9a"}],"test/probe/test_signals.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"7276eed2dee52c0678337c8bf1e7158068eda62d","unresolved":false,"context_lines":[{"line_number":151,"context_line":"            q.get()"},{"line_number":152,"context_line":"            # once it\u0027s hung in our connection - send it sig term"},{"line_number":153,"context_line":"            print(\u0027Attempting to stop reconciler!\u0027)"},{"line_number":154,"context_line":"            reconciler.stop()"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"if __name__ \u003d\u003d \u0027__main__\u0027:"}],"source_content_type":"text/x-python","patch_set":7,"id":"fa6399be_550509c0","line":154,"updated":"2016-10-12 01:22:57.000000000","message":"if you revert the change to catch_errors and run this probe test you too can experience first hand the \"Error: An error occurred:\" traceback to your logs and the indestructible container-reconciler process!\n\nThere\u0027s a handy work-around on the lp bug #1489209 when you inevitably need to SIGKILL the beast.","commit_id":"36babc0c34d6899aa836dae695f8479d6b06e092"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ce3a3c28a4f448892183b1cea322711a61e70bb7","unresolved":false,"context_lines":[{"line_number":139,"context_line":"            if dev"},{"line_number":140,"context_line":"        ]"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"    def test_main(self):"},{"line_number":143,"context_line":"        reconciler \u003d Manager([\u0027container-reconciler\u0027])"},{"line_number":144,"context_line":"        with spawn_services(self.ip_ports) as q:"},{"line_number":145,"context_line":"            reconciler.start()"}],"source_content_type":"text/x-python","patch_set":8,"id":"ba5da102_1dc5935a","line":142,"updated":"2016-11-05 00:54:49.000000000","message":"This still passes without the change to swift/common/daemon.py -- is that intentional?\n\nOr is there some way for us to differentiate (as part of the probe test) between the\n\n Attempting to stop reconciler!\n Signal container-reconciler  pid: 26110  signal: 15\n Waited 15 seconds for container-reconciler to die; giving up\n ok\n\nand\n\n Attempting to stop reconciler!\n Signal container-reconciler  pid: 26949  signal: 15\n container-reconciler (26949) appears to have stopped\n ok\n\nstates?","commit_id":"bdf83beccf6857effdb1a2721a3eb42bf7fe4ab7"}],"test/unit/common/test_daemon.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b5a4fc815b89ea9b44fd6faee9e42b88c407c160","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        sample_conf \u003d \"[my-daemon-ex]\\nuser \u003d %s\\n\" % getuser()"},{"line_number":110,"context_line":"        with tmpfile(sample_conf) as conf_file:"},{"line_number":111,"context_line":"            # test user quit"},{"line_number":112,"context_line":"            MyDaemonEx.run_forever \u003d MyDaemonEx.run_quit"},{"line_number":113,"context_line":"            sio \u003d StringIO()"},{"line_number":114,"context_line":"            logger \u003d logging.getLogger(\u0027server\u0027)"},{"line_number":115,"context_line":"            logger.addHandler(logging.StreamHandler(sio))"}],"source_content_type":"text/x-python","patch_set":4,"id":"fa69d971_e2d92e23","line":112,"updated":"2016-01-11 20:12:11.000000000","message":"Maybe part of the problem is just that this patch on the class isn\u0027t being restored after the test finishes?\n\nYou may not need to make a second class if you use mock to reset the MyDaemon class?","commit_id":"01677babea1e46e54932631c9d0344f090b82c9a"},{"author":{"_account_id":12193,"name":"Hisashi Osanai","email":"osanai.hisashi@jp.fujitsu.com","username":"ho"},"change_message_id":"0c01c8171ad8309c837e8352abb37a962a7ebc0e","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        sample_conf \u003d \"[my-daemon-ex]\\nuser \u003d %s\\n\" % getuser()"},{"line_number":110,"context_line":"        with tmpfile(sample_conf) as conf_file:"},{"line_number":111,"context_line":"            # test user quit"},{"line_number":112,"context_line":"            MyDaemonEx.run_forever \u003d MyDaemonEx.run_quit"},{"line_number":113,"context_line":"            sio \u003d StringIO()"},{"line_number":114,"context_line":"            logger \u003d logging.getLogger(\u0027server\u0027)"},{"line_number":115,"context_line":"            logger.addHandler(logging.StreamHandler(sio))"}],"source_content_type":"text/x-python","patch_set":4,"id":"da6ed579_a30e96e3","line":112,"in_reply_to":"fa69d971_e2d92e23","updated":"2016-01-12 02:27:36.000000000","message":"The problem which Jeremy found out is: this patch requires KeyboardInterrupt twice, first one is used for stopping the native thread which is invoked by tpool.execute and second one is used for stopping main thread because KeyboardInterrupt (and SystemExit) are not passed to main thread.\n\nhttps://github.com/JeremyGrosser/python-eventlet/blob/master/eventlet/tpool.py#L82","commit_id":"01677babea1e46e54932631c9d0344f090b82c9a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ce3a3c28a4f448892183b1cea322711a61e70bb7","unresolved":false,"context_lines":[{"line_number":13,"context_line":"# See the License for the specific language governing permissions and"},{"line_number":14,"context_line":"# limitations under the License."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"# TODO(clayg): Test kill_children signal handlers"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"import os"},{"line_number":19,"context_line":"from six import StringIO"}],"source_content_type":"text/x-python","patch_set":8,"id":"ba5da102_fdc37f36","line":16,"updated":"2016-11-05 00:54:49.000000000","message":"Can this be removed now?","commit_id":"bdf83beccf6857effdb1a2721a3eb42bf7fe4ab7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ce3a3c28a4f448892183b1cea322711a61e70bb7","unresolved":false,"context_lines":[{"line_number":86,"context_line":""},{"line_number":87,"context_line":"    def test_signal(self):"},{"line_number":88,"context_line":"        d \u003d MyDaemon({})"},{"line_number":89,"context_line":"        with mock.patch(\u0027swift.common.daemon.signal\u0027) as mock_signal:"},{"line_number":90,"context_line":"            mock_signal.SIGTERM \u003d signal.SIGTERM"},{"line_number":91,"context_line":"            d.run()"},{"line_number":92,"context_line":"        signal_args, kwargs \u003d mock_signal.signal.call_args"}],"source_content_type":"text/x-python","patch_set":8,"id":"ba5da102_9d452319","line":89,"updated":"2016-11-05 00:54:49.000000000","message":"nit: maybe better to just mock out swift.common.daemon.signal.signal so we don\u0027t have to reassign mock_signal.SIGTERM below? Something like http://paste.openstack.org/show/587973/","commit_id":"bdf83beccf6857effdb1a2721a3eb42bf7fe4ab7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ce3a3c28a4f448892183b1cea322711a61e70bb7","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        sig, func \u003d signal_args"},{"line_number":94,"context_line":"        self.assertEqual(sig, signal.SIGTERM)"},{"line_number":95,"context_line":"        with mock.patch(\u0027swift.common.daemon.os\u0027) as mock_os:"},{"line_number":96,"context_line":"            func()"},{"line_number":97,"context_line":"        self.assertEqual(mock_os.method_calls, ["},{"line_number":98,"context_line":"            mock.call.killpg(0, signal.SIGTERM),"},{"line_number":99,"context_line":"            # hard exit because bare except handlers can trap SystemExit"}],"source_content_type":"text/x-python","patch_set":8,"id":"ba5da102_3d5fb776","line":96,"updated":"2016-11-05 00:54:49.000000000","message":"Hrm. Should we also mock out sys here? I\u0027m having trouble seeing this fail without the change in swift/common/daemon.py :\n\n [00:45:25] vagrant@saio : ~/swift [review/hisashi_osanai/bug/1489209*]\n $ nosetests test/unit/common/test_daemon.py:TestRunDaemon\n test_run (test.unit.common.test_daemon.TestRunDaemon) ... ok\n test_run_daemon (test.unit.common.test_daemon.TestRunDaemon) ... ok\n test_signal (test.unit.common.test_daemon.TestRunDaemon) ... \n ----------------------------------------------------------------------\n Ran 3 tests in 0.020s\n \n OK\n\n(Note that it doesn\u0027t say it succeeded; it just kinda aborted.) Strangely, if I\u0027m very very specific, it *will* fail?\n\n [00:46:13] vagrant@saio : ~/swift [review/hisashi_osanai/bug/1489209*]\n $ nosetests test/unit/common/test_daemon.py:TestRunDaemon.test_signal\n test_signal (test.unit.common.test_daemon.TestRunDaemon) ... ERROR\n \n \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n ERROR: test_signal (test.unit.common.test_daemon.TestRunDaemon)\n ----------------------------------------------------------------------\n Traceback (most recent call last):\n   File \"/vagrant/swift/test/unit/common/test_daemon.py\", line 95, in test_signal\n     func()\n   File \"/vagrant/swift/swift/common/daemon.py\", line 51, in kill_children\n     sys.exit()\n SystemExit\n \n ----------------------------------------------------------------------\n Ran 1 test in 0.009s\n \n FAILED (errors\u003d1)\n\nEven adding something like\n\n try:\n     func()\n except:  #noqa\n     import traceback\n     traceback.print_exc()\n     self.fail(\u0027Caught something bad!\u0027)\n\ndidn\u0027t help :-(","commit_id":"bdf83beccf6857effdb1a2721a3eb42bf7fe4ab7"}]}
