Hoocron is cron alternative with different hooks to trigger immediate execution of jobs
pip3 install hoocron
or, install right from repo:
pip3 install git+https://github.com/yaroslaff/hoocron
Hoocron has built-in dummy job TICK
which just print 'tick!' and report how long hoocron were running, lets call it with --period
5s:
$ hoocron.py -p TICK 5s
...
run TICK from cron
Tick! (uptime: 1 seconds)
Result(TICK): ticked
run TICK from cron
Tick! (uptime: 5 seconds)
Result(TICK): ticked
Surely we can replace dummy and useless job TICK with our better useless job MYTICK:
$ hoocron.py -j MYTICK echo my tick is better -p MYTICK 5s
...
run MYTICK from cron
my tick is better
Result(MYTICK): 0
run MYTICK from cron
my tick is better
Result(MYTICK): 0
This command configures job (what to run, command and arguments, -j
) and hook (when to run, -p
for cron-alike periodical run). This very similar to cron.
We can run many jobs at once, lets make two echo jobs:
$ hoocron.py -j J1 echo every5 -j J2 echo every10 -p J1 5s -p J2 10s | grep every
every5
every10
every5
every5
every10
every5
every5
every10
Most important feature of hoocron is different hooks which you can bind to jobs.
HTTP plugin provides HTTP GET and HTTP POST interface to start cron job right now.
Now, lets make it more interesting, we will also run job after getting HTTP request using --get
option.
run hoocron.py --get TICK
and (in other session) run curl http://localhost:5152/TICK
.
So, instead of running some cron job every N minutes, you may run it asynchronously, on demand. And you can combine both: hoocron.py --get TICK -p TICK 1h
will run tick every hour, but you can always trigger it over HTTP.
If you want to use HTTP POST method, use --post
instead of --get
.
Hoocron is easy to extend with other python modules. For example, every app in any programming language (supporting redis) can trigger hoocron jobs doing LPUSH
redis command. (Need to install Redis plugin for hoocron)
Websocket plugin connects to websocket (SocketIO) server (usually ws-emit) and expect signals from server. For example, to run some job when server will have new data.
User -u USER GROUP
for this:
$ sudo hoocron.py -j ID id -p ID 10 -u ID www-data www-data
Starting hoocron pid: 263973
Loaded Hooks: cron, http, redis, websocket Jobs: TICK
Job ID will run as www-data(33):www-data(33)
started cron thread with 1 jobs: ID
run ID from cron
uid=33(www-data) gid=33(www-data) groups=33(www-data),0(root)
Result(ID): 0
If you need extra HTTP features, such as https support or additional access control, run hoocron behind real webserver working as reverse proxy.
Hoocron guarantees that only one copy of job (with same job name) is running at same time (same jobs will not overlap): hoocron will never start second copy of same job until first one is finished.
But hoocron can not prevent same script started from any other source (e.g. from shell).
There are two policies for job, ignore
(default) and asap
.
With policy ignore
, if hoocron gets request to start job and this job is already running, request is ignored.
With policy asap
, if hoocron gets request to start job and this job is already running, it will set special flag and will run same job again immediately after first instance of job is finished (and again, new request will raise flag again). Note, if there are many requests during one execution of job, it will be executed just once.
To see difference, compare ignore policy (default) with this command:
hoocron.py -j J sleep 10 -p J 3
and same with asap
policy
hoocron.py -j J sleep 10 -p J 3 --policy J asap
Build deb (via fpm):
apt-get install ruby ruby-dev rubygems build-essential
gem install -N fpm
fpm --no-auto-depends --deb-systemd debian/hoocron.service --deb-systemd-enable --deb-systemd-auto-start -s python -t deb .