2

Suppose we have a library A witch behavior depends on value of some environment variable. A_CONFIG_PATH actually. Some of my tasks use this library with different A_CONFIG_PATH for each task. I do it in a way of

import os
import A

def task(**kw):
    os.environ['A_CONFIG_PATH'] = '/home/me/current/task/config/path'
    A.do_some_stuff(kw)

This fine until all tasks process synchronously. But now I need concurrency in this tasks processing.

So how I can guarantee that each task will not corrupt another with its own A_CONFIG_PATH if I run each task in separate thread/process or something like this.

shx2
  • 61,779
  • 13
  • 130
  • 153
proofit404
  • 281
  • 1
  • 13

1 Answers1

3

There are several ways to tackle the problem:

  1. run each task in a subprocess, instead all in one process in different threads
  2. change the task to take the A_CONFIG_PATH value as a parameter, instead of reading it from environment (reading from env is just as bad as relying on global variables...)
  3. instead of assigning a string to os.environ[A_CONFIG_VALUE], use a threading.local object, which allows each thread to have its own value. You'd need to slightly change the part which reads the value, though.

An example using threading.local:

#one time init
os.environ['A_CONFIG_PATH'] = threading.local()

# set the value    
def task(**kw):
    os.environ['A_CONFIG_PATH'].value = '/home/me/current/task/config/path'
    A.do_some_stuff(kw)

# read the value
config_path = os.environ['A_CONFIG_PATH'].value

EDIT: since you said the env var is being read using os.getenv, you can combine the third solution with this hack, replacing os.getenv with your own:

# one time init
orig_getenv = os.getenv
def getenv_hacked(key, default=None):
    if key == 'A_CONFIG_PATH':
       return orig_getenv(key, default).value
     else:
       return orig_getenv(key, default)
os.getenv = getenv_hacked
os.environ['A_CONFIG_PATH'] = threading.local()
shx2
  • 61,779
  • 13
  • 130
  • 153
  • The problem actually is that `A` library use this variable by `os.getenv('A_CONFIG_PATH')`, not my code. So is third way still appropriate in this case? – proofit404 Jan 21 '14 at 06:52
  • The solution #3 doesn't work for me, but I can't format the ipython output properly, so see the new question here: http://stackoverflow.com/questions/38348556/ – ilya Jul 13 '16 at 10:07