{"action":"closed","issue":{"url":"https://api.github.com/repos/cylc/cylc/issues/3039","repository_url":"https://api.github.com/repos/cylc/cylc","labels_url":"https://api.github.com/repos/cylc/cylc/issues/3039/labels{/name}","comments_url":"https://api.github.com/repos/cylc/cylc/issues/3039/comments","events_url":"https://api.github.com/repos/cylc/cylc/issues/3039/events","html_url":"https://github.com/cylc/cylc/issues/3039","id":424576542,"node_id":"MDU6SXNzdWU0MjQ1NzY1NDI=","number":3039,"title":"Should xrandom be defensive against ZeroDivisionError?","user":{"login":"kinow","id":304786,"node_id":"MDQ6VXNlcjMwNDc4Ng==","avatar_url":"https://avatars1.githubusercontent.com/u/304786?v=4","gravatar_id":"","url":"https://api.github.com/users/kinow","html_url":"https://github.com/kinow","followers_url":"https://api.github.com/users/kinow/followers","following_url":"https://api.github.com/users/kinow/following{/other_user}","gists_url":"https://api.github.com/users/kinow/gists{/gist_id}","starred_url":"https://api.github.com/users/kinow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kinow/subscriptions","organizations_url":"https://api.github.com/users/kinow/orgs","repos_url":"https://api.github.com/users/kinow/repos","events_url":"https://api.github.com/users/kinow/events{/privacy}","received_events_url":"https://api.github.com/users/kinow/received_events","type":"User","site_admin":false},"labels":[{"id":18458798,"node_id":"MDU6TGFiZWwxODQ1ODc5OA==","url":"https://api.github.com/repos/cylc/cylc/labels/bug?","name":"bug?","color":"FF6000","default":false}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2019-03-24T05:20:02Z","updated_at":"2019-03-26T10:07:40Z","closed_at":"2019-03-26T10:07:40Z","author_association":"MEMBER","body":"Hi,\r\n\r\nAt the moment if the parameter provided for the percent in the `xrandom` random external trigger is zero, there will be a `ZeroDivisionError`.\r\n\r\n```bash\r\n2019-03-24T18:10:24+13:00 DEBUG - END TASK PROCESSING (took 0.002267599105834961 seconds)\r\n2019-03-24T18:10:25+13:00 DEBUG - [xtrigger-func cmd] cylc-function-run xrandom '[]' '{\"percent\": 0, \"secs\": 2, \"_\": \"1\"}' /home/kinow/Development/python/workspace/cylc/etc/examples/xtrigger/xrandom\r\n\t[xtrigger-func ret_code] 1\r\n\t[xtrigger-func err]\r\n\tTraceback (most recent call last):\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/bin/cylc-function-run\", line 37, in <module>\r\n\t    run_function(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/subprocpool.py\", line 85, in run_function\r\n\t    res = func(*func_args, **func_kwargs)\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/xtriggers/xrandom.py\", line 44, in xrandom\r\n\t    satisfied = (1 == randint(1, 100 / int(percent)))\r\n\tZeroDivisionError: division by zero\r\n2019-03-24T18:10:25+13:00 ERROR - the JSON object must be str, bytes or bytearray, not NoneType\r\n\tTraceback (most recent call last):\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/scheduler.py\", line 257, in start\r\n\t    self.run()\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/scheduler.py\", line 1534, in run\r\n\t    self.proc_pool.process()\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/subprocpool.py\", line 174, in process\r\n\t    self._proc_exit(proc, \"\", ctx, callback, callback_args)\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/subprocpool.py\", line 165, in _proc_exit\r\n\t    self._run_command_exit(ctx, callback, callback_args)\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/subprocpool.py\", line 360, in _run_command_exit\r\n\t    callback(ctx, *callback_args)\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/xtrigger_mgr.py\", line 263, in callback\r\n\t    satisfied, results = json.loads(ctx.out)\r\n\t  File \"/home/kinow/Development/python/anaconda3/lib/python3.7/json/__init__.py\", line 341, in loads\r\n\t    raise TypeError(f'the JSON object must be str, bytes or bytearray, '\r\n\tTypeError: the JSON object must be str, bytes or bytearray, not NoneType\r\n2019-03-24T18:10:25+13:00 ERROR - error caught: cleaning up before exit\r\n2019-03-24T18:10:25+13:00 INFO - Suite shutting down - ERROR: the JSON object must be str, bytes or bytearray, not NoneType\r\n2019-03-24T18:10:25+13:00 ERROR - [Errno 3] No such process\r\n\tTraceback (most recent call last):\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/scheduler.py\", line 257, in start\r\n\t    self.run()\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/scheduler.py\", line 1534, in run\r\n\t    self.proc_pool.process()\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/subprocpool.py\", line 174, in process\r\n\t    self._proc_exit(proc, \"\", ctx, callback, callback_args)\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/subprocpool.py\", line 165, in _proc_exit\r\n\t    self._run_command_exit(ctx, callback, callback_args)\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/subprocpool.py\", line 360, in _run_command_exit\r\n\t    callback(ctx, *callback_args)\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/xtrigger_mgr.py\", line 263, in callback\r\n\t    satisfied, results = json.loads(ctx.out)\r\n\t  File \"/home/kinow/Development/python/anaconda3/lib/python3.7/json/__init__.py\", line 341, in loads\r\n\t    raise TypeError(f'the JSON object must be str, bytes or bytearray, '\r\n\tTypeError: the JSON object must be str, bytes or bytearray, not NoneType\r\n\t\r\n\tDuring handling of the above exception, another exception occurred:\r\n\t\r\n\tTraceback (most recent call last):\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/scheduler.py\", line 283, in start\r\n\t    self.shutdown('ERROR: ' + str(exc))\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/scheduler.py\", line 1727, in shutdown\r\n\t    self.proc_pool.terminate()\r\n\t  File \"/home/kinow/Development/python/workspace/cylc/lib/cylc/subprocpool.py\", line 263, in terminate\r\n\t    os.killpg(proc.pid, SIGKILL)\r\n\tProcessLookupError: [Errno 3] No such process\r\n2019-03-24T18:10:25+13:00 INFO - DONE\r\n```\r\n\r\nSimply doing \r\n\r\n```diff\r\ndiff --git a/lib/cylc/xtriggers/xrandom.py b/lib/cylc/xtriggers/xrandom.py\r\nindex 43f4ca4cb..0a36c3b86 100644\r\n--- a/lib/cylc/xtriggers/xrandom.py\r\n+++ b/lib/cylc/xtriggers/xrandom.py\r\n@@ -41,7 +41,7 @@ def xrandom(percent, secs=0, _=None, debug=False):\r\n     \"\"\"\r\n     sleep(float(secs))\r\n     results = {}\r\n-    satisfied = (1 == randint(1, 100 / int(percent)))\r\n+    satisfied = int(percent) != 0 and (1 == randint(1, 100 / int(percent)))\r\n     if satisfied:\r\n         results = {\r\n             'COLOR': COLORS[randint(0, len(COLORS) - 1)],\r\n```\r\n\r\nWould return `False` when zero, however, the trigger would simply never succeed. So the following could be useful to prevent the `ZeroDivisionError`? If for whatever reason the percent is zero, then just consider it as done.\r\n\r\n```diff\r\ndiff --git a/lib/cylc/xtriggers/xrandom.py b/lib/cylc/xtriggers/xrandom.py\r\nindex 43f4ca4cb..4793411d2 100644\r\n--- a/lib/cylc/xtriggers/xrandom.py\r\n+++ b/lib/cylc/xtriggers/xrandom.py\r\n@@ -41,7 +41,7 @@ def xrandom(percent, secs=0, _=None, debug=False):\r\n     \"\"\"\r\n     sleep(float(secs))\r\n     results = {}\r\n-    satisfied = (1 == randint(1, 100 / int(percent)))\r\n+    satisfied = int(percent) == 0 or (1 == randint(1, 100 / int(percent)))\r\n     if satisfied:\r\n         results = {\r\n             'COLOR': COLORS[randint(0, len(COLORS) - 1)],\r\n```"}}
{"actor":{"display_login":"hjoliver"}}