-
Notifications
You must be signed in to change notification settings - Fork 176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gdal_config option doesn't work for threaded readers #186
Comments
possible solution: do not use from contextlib import contextmanager
@contextmanager
def Env(**env):
"""Temporarily set environment variables inside the context manager and
fully restore previous environment afterwards
from: https://gist.github.com/igniteflow/7267431#gistcomment-2553451
"""
env = env or {}
original_env = {key: os.getenv(key) for key in env}
os.environ.update(env)
try:
yield
finally:
for key, value in original_env.items():
if value is None:
del os.environ[key]
else:
os.environ[key] = value taken from https://gist.github.com/igniteflow/7267431#gistcomment-2553451#185 when entering |
Just to be clear the problem is because we are setting def f():
return get_gdal_config("ENV")
def g():
with rasterio.Env(ENV="FALSE"):
with futures.ThreadPoolExecutor() as executor:
r = executor.submit(f)
return r.result()
print(g())
>> "FALSE"
with futures.ThreadPoolExecutor() as executor:
r = executor.submit(g)
print(r.result())
>> None |
I don't think you can do this. Really what's happening is there are two thread pool executors. The first is used by FastAPI to execute the I think another good solution is to stop using |
Yes this will work but won't allow us to deploy application with different supports, e.g. :
Ideally, yes global env variable would be enought but won't give flexibility 🤷♂️ |
We already tried to solve this using
apiroute_factory
https://developmentseed.org/titiler/concepts/APIRoute_and_environment_variables/
While this approach worked for a while, it didn't seems to work in python 3.8 and felt quite of a hack.
We then switched and added
gdal_config
options in the factory (ref #170). I though this worked ... but I was wrong.In FastAPI, when you define a function with a simple
def myfunction(...
, fastapi will use starlette'srun_in_threadpool
to run the function (so the API isn't blocked). This makes the function to be run in a thread ... which isn't the MainThread, and this is important. In Rasterio, when usingwith rasterio.Env(
block, rasterio will check if we are running it in the MainThread or not (https://github.com/mapbox/rasterio/blob/master/rasterio/_env.pyx#L158-L161) and then use different function to set the GDAL config.The problem here seems that because we use simple
def
we run theendpoint function
in a sub Thread (ThreadPoolExecutor-X_X
) and then the env cannot be forwarded to threads within the threads... (yes threads within threads seems bad anyway).It's kinda hard for me to explain so here is an example
☝️ where we use
run_in_threadpool
we simulate the actual setting in titiler (def
), fastAPI doesn't userun_in_threadpool
when usingasync def
.Fix ?
async def
for functions definitionFastAPI docs seems to say we shouldn't (and I think @geospatial-jeff told the same in the past)
Not an expert here, but I guess there is a good reason to use
CPLSetConfigOption
only in MainThread (cc @sgillies, sorry for the ping but it's only a FYI)ref: rasterio/rasterio#1012 & rasterio/rasterio#997
Seems the safest choice 😭
The text was updated successfully, but these errors were encountered: