-
Notifications
You must be signed in to change notification settings - Fork 176
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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: