Determine what the calling program is

Barry Scott barry at barrys-emacs.org
Mon Apr 19 11:09:45 EDT 2021



> On 18 Apr 2021, at 14:46, Jason Friedman <jsf80238 at 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
> 



More information about the Python-list mailing list