{"action":"created","issue":{"url":"https://api.github.com/repos/flux-framework/flux-core/issues/659","repository_url":"https://api.github.com/repos/flux-framework/flux-core","labels_url":"https://api.github.com/repos/flux-framework/flux-core/issues/659/labels{/name}","comments_url":"https://api.github.com/repos/flux-framework/flux-core/issues/659/comments","events_url":"https://api.github.com/repos/flux-framework/flux-core/issues/659/events","html_url":"https://github.com/flux-framework/flux-core/pull/659","id":152616593,"number":659,"title":"flux-cron: cron-like service","user":{"login":"grondo","id":741970,"avatar_url":"https://avatars.githubusercontent.com/u/741970?v=3","gravatar_id":"","url":"https://api.github.com/users/grondo","html_url":"https://github.com/grondo","followers_url":"https://api.github.com/users/grondo/followers","following_url":"https://api.github.com/users/grondo/following{/other_user}","gists_url":"https://api.github.com/users/grondo/gists{/gist_id}","starred_url":"https://api.github.com/users/grondo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/grondo/subscriptions","organizations_url":"https://api.github.com/users/grondo/orgs","repos_url":"https://api.github.com/users/grondo/repos","events_url":"https://api.github.com/users/grondo/events{/privacy}","received_events_url":"https://api.github.com/users/grondo/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/flux-framework/flux-core/labels/review","name":"review","color":"ededed"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":28,"created_at":"2016-05-02T18:46:07Z","updated_at":"2016-05-05T16:53:19Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/flux-framework/flux-core/pulls/659","html_url":"https://github.com/flux-framework/flux-core/pull/659","diff_url":"https://github.com/flux-framework/flux-core/pull/659.diff","patch_url":"https://github.com/flux-framework/flux-core/pull/659.patch"},"body":"This PR contains a somewhat simplified cron-like service for a flux instance.\r\n\r\nIt isn't quite ready (no tests and documentation), but I thought I'd open up the PR now for feedback, as there may be a lot.\r\n\r\nTODO\r\n- [x]  Tests\r\n- [ ]  Docs\r\n- [x]  Fix cron entry counter reset on `flux cron start`\r\n- [x]  Add entry repeat count to `flux cron list` default output\r\n- [ ]  Sync cron_entry_run() to `hb` event by default for all entries\r\n- [x]  Fix `-r, --rank` option\r\n- [ ]  Add entry common options for `flux cron event ...`\r\n- [ ]  Load cron module in default rc1 script?\r\n- [ ]  cron task timeout support\r\n\r\n## cron module\r\n\r\nThe cron module itself has the following components:\r\n - A `cron_task` type, which is an asynchronous exec abstraction built around `cmb.exec` service\r\n - A `cron_entry` type, which contains the data you'd expect for cron entries: unique id, name, command to run, current and historical `cron_task` information, etc\r\n - An \"entry type\" class which controls when the cron entry is executed\r\n\r\nCurrent types implemented in this PR thus far are:\r\n * Interval: Run periodically using a `flux_timer_watcher`\r\n * Event: Run once per event, or optionally once every Nth event\r\n\r\nOther types can be easily added, though all I can think of is to add a real cron-like \"date&time\" type built on the as-yet-unported-to-flux-handle libev [ev_periodic](http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#code_ev_periodic_code_to_cron_or_not) watcher.\r\n\r\nCron entries by default are run indefinitely until stopped or deleted,  but a `repeat` flag is supported which can allow an `at(1)` like service as well\r\n\r\n## flux-cron utility\r\n\r\nIncluded is a front-end `flux-cron` utility which allows the creation/deletion, start/stop, and query of flux-cron jobs. A few examples will probably sum it up nicely:\r\n```\r\ngrondo@flux-core:~ $ flux cron help\r\nUsage: flux-cron [OPTIONS] COMMAND [OPTIONS...]\r\n  -h, --help                 Display this message.\r\nSupported commands:\r\n delete       Delete flux cron entries\r\n help         Display this help or help for a command\r\n list         List registered and stopped fluxicron jobs\r\n interval     run COMMAND once every INTERVAL\r\n start        Start a stopped flux cron job\r\n event        run COMMAND on every event matching TOPIC\r\n stop         Stop a flux cron job from executing\r\n```\r\n\r\nCreate a job to run every 10s:\r\n```\r\ngrondo@flux-core:~ $ flux cron interval 10s date\r\ninterval: cron-2 created\r\ngrondo@flux-core:~ $ flux cron list\r\n    ID CMD/NAME        STATE      #RUNS            LASTRUN             STATUS\r\n     2 date            Active         0               None               None\r\ngrondo@flux-core:~ $ flux cron list\r\n    ID CMD/NAME        STATE      #RUNS            LASTRUN             STATUS\r\n     2 date            Active         1      8 seconds ago             Exited\r\n```\r\n```\r\ngrondo@flux-core:~ $ flux cron interval --help\r\nUsage: flux-cron interval INTERVAL COMMAND\r\n  -h, --help                 Display this message.\r\nOptions:\r\n  -R, --repeat=N             Run COMMAND at most N times\r\n  -c, --history-count=N      Save information on past N runs in cron history\r\n  -r, --rank=RANK            target RANK for COMMAND execution (Default = 0)\r\n  -N, --name=S               Name cron job string S instead of default\r\n```\r\n\r\n\r\nIn one second run `false`, but only run it once:\r\nNote non-zero exit code shows status as `FAILED`.\r\n```\r\ngrondo@flux-core:~ $ flux cron interval --repeat=1 1s false\r\ninterval: cron-3 created\r\ngrondo@flux-core:~ $ flux cron list\r\n    ID CMD/NAME        STATE      #RUNS            LASTRUN             STATUS\r\n     2 date            Active         5      2 seconds ago             Exited\r\n     3 false           Stopped        1      3 seconds ago             Failed\r\n```\r\n\r\nStart/stop executing jobs:\r\n```\r\ngrondo@flux-core:~ $ flux cron stop 2\r\nStopped cron-2\r\ngrondo@flux-core:~ $ flux cron list\r\n    ID CMD/NAME        STATE      #RUNS            LASTRUN             STATUS\r\n     2 date            Stopped        6     46 seconds ago             Exited\r\n     3 false           Stopped        1     57 seconds ago             Failed\r\ngrondo@flux-core:~ $ flux cron start 2\r\nStarted cron-2\r\ngrondo@flux-core:~ $ flux cron list\r\n    ID CMD/NAME        STATE      #RUNS            LASTRUN             STATUS\r\n     2 date            Active         6       a minute ago             Exited\r\n     3 false           Stopped        1       a minute ago             Failed\r\n```\r\n\r\nflux-cron entries stay resident until they are deleted with `flux cron delete`\r\n```\r\ngrondo@flux-core:~ $ flux cron delete 2\r\nRemoved cron-2: date last ran a second ago for 24.03ms\r\n```"},"comment":{"url":"https://api.github.com/repos/flux-framework/flux-core/issues/comments/217208880","html_url":"https://github.com/flux-framework/flux-core/pull/659#issuecomment-217208880","issue_url":"https://api.github.com/repos/flux-framework/flux-core/issues/659","id":217208880,"user":{"login":"grondo","id":741970,"avatar_url":"https://avatars.githubusercontent.com/u/741970?v=3","gravatar_id":"","url":"https://api.github.com/users/grondo","html_url":"https://github.com/grondo","followers_url":"https://api.github.com/users/grondo/followers","following_url":"https://api.github.com/users/grondo/following{/other_user}","gists_url":"https://api.github.com/users/grondo/gists{/gist_id}","starred_url":"https://api.github.com/users/grondo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/grondo/subscriptions","organizations_url":"https://api.github.com/users/grondo/orgs","repos_url":"https://api.github.com/users/grondo/repos","events_url":"https://api.github.com/users/grondo/events{/privacy}","received_events_url":"https://api.github.com/users/grondo/received_events","type":"User","site_admin":false},"created_at":"2016-05-05T16:53:19Z","updated_at":"2016-05-05T16:53:19Z","body":"Oops, also noticed there's still some debug printfs in the current code. Sorry about that..."}}