forked from timkay/solo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
90 lines (85 loc) · 3.42 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<html>
<head>
<title>solo - prevent simultaneous instances</title>
<meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=1;"/>
<style>
@import url("../style.css");
</style>
</head>
<body>
<h2 style="background-color: #082466; color: #fff"> solo - prevent simultaneous instances</h2>
<p>
<img align=absmiddle src=http://s3.timkay.com/timeyes.gif> <a href=../>timkay.com</a> » <a href=../tools/>tools</a> » solo
<p>
<a href=solo>solo</a> is a very simple script (10 lines) that prevents a program
from running more than one copy at a time. It is useful with cron to
make sure that a job doesn't run before a previous one has finished.
<p>
Usage:
<blockquote><xmp>solo -port=PORT COMMAND
where
PORT some arbitrary port number to be used for locking
COMMAND shell command to run
options
-verbose be verbose
-silent be silent
</xmp></blockquote>
Use it like this:
<p>
<code>* * * * * solo -port=3801 ./job.pl blah blah</code>
<p>
The script job.pl will run every minute, but only if the previous one
has finished. (Of course, you can use different parameters, if it
doesn't have to run it every minute.)
<p>
Port 3801 in the example is an arbitrary TCP port number that isn't
used elsewhere. (solo works by binding to 127.x.y.1:port. If the
chosen port is not free, then a previous instance must still be running, and the job is aborted.)
Make sure to use a different port number for each job, or they will
prevent each other from running. If you aren't running as root, the
port number should be above 1023. The maximum allowed port number
is 65535.
<p>
The loopback IP address 127.x.y.1 is used, where xy is the uid.
This way, different users will never use the same ports even if they
use the same port numbers.
<p>
(NOTE: OpenBSD doesn't allow 127.x.y.1 IP addresses. See the comment in the
code, which changes the IP address to 127.0.0.1. It will work, but it will
interlock between users. Thanks <a href="www.gotati.com">www.gotati.com</a>.)
<p>
The -silent switch tells solo to silently terminate when a previous
instance is already running. Without -silent, a message is printed to
stderr, indicating that a previous instance is already running.
<p>
Running a job this way (using crontab and solo) is much more maintainable than other methods:
<ul>
<li>you don't need root privileges</li>
<li>you avoid the complexity of /etc/rc.d files</li>
<li>you don't have problems if the job crashes (cron restarts it)</li>
<li>you can run multiple versions, one per directory, so, for example, you can have separate dev, stage, and live directories</li>
</ul>
<p>
A nice trick is to create a cron job:
<p>
<code>* * * * * solo -port=3802 find . -iname makefile -exec fgrep --silent repeatedly: {} \; -execdir make --silent repeatedly \;</code>
<p>
This cron job will find each Makefile and execute its "repeatedly"
target. Thus you can cause a job to run periodically by simply adding
a target to a Makefile. The "-exec fgrep ..." step makes sure that
the Makefile contains the target before "-execdir make ..." runs it,
so error messages are avoided.
<p>
If you like, you can create multiple jobs that run targets named
"repeatedly", "hourly", "daily", etc., to run jobs at different
intervals.
<p>
<b>Acknowledgements</b>
<p>
Thanks to Adam Fritzler for pointing out that the loopback interface is a /8.
<p>
<b>Author</b>
<p>
Timothy Kay <a href=mailto:[email protected]>[email protected]</a> +1-650-248-0123
</body>
</html>