I have a simple FastAPI demo app which achieve a function:
get different response json by calling a post api named changeResponse
.
The changeResponse
api just changed a global variable, another api return different response through the same global variable. On local env, it works correctly, but the response always changes after i just call changeResponse
once, when i build this on docker.The code is as follows:
from typing import Optional
from fastapi import FastAPI
from util import read_json
import enum
app = FastAPI()
type = "00"
@app.post("/changeResponse")
async def handle_change_download_response(param:Optional[str]):
global type
type = param
print("type is "+type)
return {"success":"true"}
@app.post("/download")
async def handle_download(param:Optional[str]):
print("get download param: "+param)
if legalDownload(param):
print("type is "+type)
return read_json.readDownloadSuccessRes(type)
else:
return read_json.readDownloadFailRes()
def legalDownload(data:str)->bool:
return True
the dockerfile is as follows:
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
COPY ./app /app
what i except:
call changeResponse
param is 7, get response for 7,
call changeResponse
param is 8, get response for 8.
what i get:
call changeResponse
param is 7, get reponse for 7, call changeReponse
8, sometime the response is 7, sometime is 8, impossible to predict
tiangolo/uvicorn-gunicorn-fastapi
is based on uvicorn-gunicorn-docker image, which by defaults creates multiple workers. Excerpt from gunicorn_conf.py:
default_web_concurrency = workers_per_core * cores
Thus, the described situation arises because the request is processed by different workers (processes). Each of which has its own copy of the global variable
Update: If you want to change the count of workers, use the following environment variables:
You can set it like:
docker run -d -p 80:80 -e WEB_CONCURRENCY="2" myimage
A more detailed description of these variables and examples here
If you want to share data between workers, pay attention to this topic.