Skip to content

Instantly share code, notes, and snippets.

@jn0
Created September 1, 2017 08:05
Show Gist options
  • Save jn0/67009be5c5ebb8ed014fe70cd2cf55a8 to your computer and use it in GitHub Desktop.
Save jn0/67009be5c5ebb8ed014fe70cd2cf55a8 to your computer and use it in GitHub Desktop.
Host-wide exclusive lock without any file use (instead of flock -x $0 $0 "$@")
#!/usr/bin/python
# a tool to allow only one instance of the command to be ran at once
# host-wide exclusive lock
# no lock- or pid- files, never-used-port is "locked" instead
# written after http://timkay.com/solo/ idea
THE_POINT_TO_LOCK = ("127.1.2.3", 9000)
import sys
import os
import socket
import errno
if len(sys.argv) < 2:
sys.stderr.write('What to run?\n')
sys.exit(1)
sock = socket.socket()
def abort(msg, s=sock):
sys.stderr.write(msg)
try:
s.close()
except:
pass
sys.exit(1)
try:
sock.bind(THE_POINT_TO_LOCK)
except socket.error as why:
if why.errno == errno.EADDRINUSE:
abort('Command processor is busy.\n')
abort('Cannot bind %r: %r\n' % (THE_POINT_TO_LOCK, why))
try:
cmd = sys.argv[1]
os.execv(cmd, sys.argv[1:])
except Exception as why:
abort('Cannot exec(%r, %r): %r\n' % (cmd, sys.argv[1:], why))
abort('Could not exec %r\n' % (sys.argv[1:],))
# vim: set ft=python :EOF #
@jn0
Copy link
Author

jn0 commented Sep 1, 2017

If you need a traditional solution, consider something like

#!/bin/bash

[ "$1" != LoCkEd ] && {
    flock -n -x -E 199 "$0" "$0" LoCkEd "$@"
    rc=$?
    [ $rc = 199 ] && { echo "Busy." >&2; exit 2; }
    exit $rc # done
}
shift # pop LoCkEd "arg"

echo "Working..."; sleep 30; echo "Done." # continue with regular payload...

# EOF #

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment