> On 18 Apr 2021, at 14:46, Jason Friedman <jsf80...@gmail.com> wrote:
>
> I should state at the start that I have a solution to my problem. I am
> writing to see if there is a better solution.
>
> I have a program that runs via crontab every five minutes. It polls a
> Box.com folder for files and, if any are found, it copies them locally and
> performs a computation on them that can exceed five minutes. It pushes the
> results back up to Box. (Box.com ensures that only complete files are
> visible when I poll.) Files are dropped into this Box.com folder rarely,
> but to ensure a good customer experience I do not want to set my crontab to
> run less frequently. My hardware cannot support multiple simultaneous
> computations.
>
> I have written a piece of code to detect if more than 1 instance of my
> program is running, and I put this code into a separate module (support.py)
> so that other programs can use it.
The way to do this simply on a unix system is to use a lock file and code like
this:
lock_file = open(os.path.join(lock_dir, 'lockfile'), 'w')
try:
fcntl.flock(lock_file, fcntl.LOCK_EX|fcntl.LOCK_NB)
except IOError as e:
if e.errno == errno.EWOULDBLOCK:
log('CA base directory "%s" already locked, exiting', ca_base_dir)
sys.exit(0)
else:
log('Non-locking related IOError for file %s', lock_file)
raise
Only the first time the code runs will the lock be granted.
You can then do the possible long running task.
When a second copy of the program runs from cron it will get the
EWOULDBLOCK error and you can just exit.
Barry
>
> support.py contains:
> --------------------------------------------------------------------------------
> import sys
> def check(calling_program):
> import psutil
> # some logic here to count
> # count = N
> if count > 1:
> print(f"I was called by {calling_program}.")
> sys.exit()
> if __name__ == "__main__":
> check()
> --------------------------------------------------------------------------------
>
> actual-program.py contains:
> --------------------------------------------------------------------------------
> import support.py
> support.check(__file__)
> # Poll, and if files download, perform expensive computations, push results
> --------------------------------------------------------------------------------
>
> To me it would be more elegant to be able to do something like this:
>
> def check():
> # Something here that tells me the name of the calling program
> import psutil
> # ...
>
> And then the calling program just does:
> support.check()
> --
> https://mail.python.org/mailman/listinfo/python-list
>
--
https://mail.python.org/mailman/listinfo/python-list