I am using fast api to create endpoints. There are 3 basic endpoints:
- /create to add a record in json file
- /delete to delete a record in json file
- /view which displays the record from json file
This json file is called store.json. This functionality is working fine when triggering the uvicorn server locally. But after containerizing it with docker the modification done to this file is not happening correctly. For example while adding records some records are not written in the file.
Below are the code snippets:
/view
@router.get("/")
async def view():
"""
Fetched the list
"""
resp = get_records()
return {"response": resp}
def get_records():
with open("core/store/store.json") as store_file:
store = json.load(store_file)
return store
/create
@router.get("/create")
async def create():
"""
Create the record
"""
resp = create_records()
return {"response": resp}
def create_records():
with open("core/store/store.json") as store_file:
store = json.load(store_file)
store.get("students").append({
"id": random.randint(1, 101),
"date_created": datetime.now().strftime("%b-%d-%Y at %H:%M")
})
with open("core/store/store.json", "w") as outfile:
json.dump(store, outfile)
return store.get("students")[-1]
/delete
@router.get("/delete{id}")
async def delete(id):
"""
Delete the record
"""
resp = del_records(id)
return {"response": resp}
def del_records(id):
with open("core/store/store.json") as store_file:
store = json.load(store_file)
for info in store.get("students"):
if info.get("id") == id:
store.get("students").remove(info)
break
with open("core/store/store.json", "w") as outfile:
json.dump(store, outfile)
return f"deleted id {id}"
Dockerfile
FROM python:3.8
WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN python -m pip install --upgrade pip && \
python -m pip install --no-cache-dir -r /app/requirements.txt
COPY . /app
EXPOSE 4558
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "4558", "--workers", "4"]
Docker version
>> docker --version
Docker version 20.10.12, build e91ed57
CodePudding user response:
You're seeing missing writes since you're running with multiple workers (--workers 4
), and your code is prone to race conditions.
Consider the case where you have two workers running e.g. create_records
, here described as a primitive concurrency diagram, time running downwards:
Worker 1 | Worker 2 |
---|---|
receive request | ... |
open json (0 entries: []) | receive request |
add data [123] | open json (0 entries: []) |
save json ([123]) | add data [456] |
... | save json ([456]) |
receive request | ... |
open json (1 entries: [456])
|