question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to properly close a background child process in a shutdown event?

See original GitHub issue

First check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn’t find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google “How to X in FastAPI” and didn’t find any information.
  • I already read and followed all the tutorial in the docs and didn’t find an answer.
  • I already checked if it is not related to FastAPI but to Pydantic.
  • I already checked if it is not related to FastAPI but to Swagger UI.
  • I already checked if it is not related to FastAPI but to ReDoc.
  • After submitting this, I commit to one of:
    • Read open issues with questions until I find 2 issues where I can help someone and add a comment to help there.
    • I already hit the “watch” button in this repository to receive notifications and I commit to help at least 2 people that ask questions in the future.
    • Implement a Pull Request for a confirmed bug.

Example

Here’s a self-contained, minimal, reproducible, example with my use case:

from multiprocessing import Process, Value

from fastapi import FastAPI

app = FastAPI()

terminate_flag = Value('h', 0)


def work_hard(terminate_flag: Value):
    while terminate_flag.value == 0:
        # CPU-bound calculations
        pass


@app.get('/hello-world')
def hello_world():
    return {
        'message': 'hello world'
    }


process = Process(target=work_hard, args=(terminate_flag,))


@app.on_event('startup')
def startup_event():
    process.start()


@app.on_event('shutdown')
def shutdown_event():
    terminate_flag.value = 1
    process.join()

Description

I have some CPU-bound calculations known as work_hard, which contains a flagged loop to control its flow.

The function is designed to be executed in a child process that starts within FastAPI startup event, and joins within FastAPI shutdown event.

However, it seems that the FastAPI shutdown event does not get executed while uvicorn is shutting down by the user pressing Ctrl + C. It stuck at the log “Finished server process” and never really terminates.

I did try to look up for the standard practice of using multiprocessing module in FastAPI, but there are no concrete examples about it. Concurrency and async/await section mentioned that “To see how to achieve this parallelism in production see the section about Deployment.”, yet Deployment section has no such examples as well.

Thank you in advance!

Environment

  • OS: Ubuntu 18.04.4 TLS
  • FastAPI Version : 0.61.1
  • Python version: 3.6.8

Additional context

cliff@cliff-pc:~/repo/fastapi-multiprocessing$ uvicorn app.main:app
INFO:     Started server process [24032]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
^CINFO:     Shutting down
INFO:     Finished server process [24032]

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:13 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
raphaelauvcommented, Sep 9, 2020

Also to respond to your question :

FastAPI shutdown event does not get executed while uvicorn is shutting down by the user pressing Ctrl + C.

No it does


from fastapi import FastAPI
import uvicorn

async def on_shutdown():
    print("HERE")

if __name__ == '__main__': 
    web_app = FastAPI(docs_url="/", on_shutdown=[on_shutdown])
    uvicorn.run(web_app, host="0.0.0.0", port=8000)

give

INFO:     Started server process [10579]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
^CINFO:     Shutting down
INFO:     Waiting for application shutdown.
HERE
INFO:     Application shutdown complete.
INFO:     Finished server process [10579]

Probably you run the code inside a docker and do not use tini

0reactions
tiangolocommented, Nov 5, 2022

Thanks for the help and discussion here everyone and thanks @clifflau1120 for coming back to close the issue. ☕

Sorry for the long delay! 🙈 I wanted to personally address each issue/PR and they piled up through time, but now I’m checking each one in order.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Kill child process when parent process is killed - Stack Overflow
Quit () and Process.Kill() are possible solutions, but have proven to be unreliable. When your main application dies, you are still left with...
Read more >
Waiting for background programs to close when shutting down
When I either shutdown or restart my computer I get a screen that says "waiting for background program to close" and click the...
Read more >
Shutdown a Spring Boot Application - Baeldung
The execution of shutdown.bat extracts the Process ID from the shutdown.pid file and uses the kill command to terminate the Boot application. 6....
Read more >
Implementing Graceful Shutdown in Go | RudderStack Blog
To shutdown gracefully is for the program to terminate after: All pending processes (web request, loops) are completed - no new processes should ......
Read more >
Background process - Wikipedia
Typical tasks for these processes include logging, system monitoring, scheduling, and user notification. The background process usually is a child process ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found