Search code examples
pythonlinuxterminalbsd

When to use blocking and non-blocking functions?


I am making a python module to help manage some tasks in Linux (and BSD) - namely managing Linux Containers. I'm aware of a couple of the ways to run terminal commands from python, such as Popen(), call(), and check_call(). When should I use these specific functions? More specifically, when is it proper to use the blocking or non-blocking function?

I have functions which build the commands to be run, which then pass the command (a list) to another function to execute it, using Popen.

Passing a command such as:

['lxc-start', '-n', 'myContainer']

to

...
def executeCommand(command, blocking=False):
    try:
        if blocking:
            subprocess.check_call(command)
        else:
            (stdout, stderr) = Popen(command, stdout=PIPE).communicate()
            self.logSelf(stdout)
    except:
        as_string = ' '.join(command)
        logSelf("Could not execute :", as_string) #logging function
    return
...

the code defaults to using Popen(), which is a non-blocking function. Under which kinds of cases should I override blocking and let the function perform check_call()?

My initial thoughts were to using blocking when the process is a one-time temporary process, such as the creation of the container, and to use non-blocking when the process is continuously running, such as starting a container.

Am I understanding the purpose of these functions correctly?


Solution

  • To answer the wider question - I would suggest :

    Use a blocking call when you are doing something which either :

    1. You know will always be quick - regardless of whether it works or fails.
    2. Something which is critical to your application, and where is make no sense for your application to do anything else unless and until that task is complete - for instance connecting to or creating critical resources.

    Use non-blocking calls in all other cases if you can, and especially if :

    1. The task could take a while or
    2. It would be useful to be doing something else while the task executes (even if that is a gui update to show progress).