Determine what the calling program is

Kushal Kumaran kushal at locationd.net
Sun Apr 18 13:27:19 EDT 2021


On Sun, Apr 18 2021 at 07:46:53 AM, 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.
>
> 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()

The standard library provides locking primitives in the Unix-specific
fcntl module.  You can use those to make sure only a single instance of
your process runs.  Use the non-blocking forms of the lock to ensure
that if you are unable to get the lock, you exit rather than wait.  If
your process waits for locks, the crontab will keep piling on waiters.

There are libraries[1][2] on pypi that wrap the platform-specific
locking primitives and provide terse APIs.

A simpler solution might be to use the flock(1) command, if you have it
available, directly in the crontab entry.

[1] https://pypi.org/project/fasteners/
[2] https://pypi.org/project/oslo.concurrency/

-- 
regards,
kushal


More information about the Python-list mailing list