-
Notifications
You must be signed in to change notification settings - Fork 40
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
[MOD-3841]: run web server in separate thread #2255
base: main
Are you sure you want to change the base?
[MOD-3841]: run web server in separate thread #2255
Conversation
If you wanted to use uvicorn.run(), couldn't you just use Right now This is also a breaking change since the |
Yeah the uvicorn was just an example of something that will block the thread. I think the reasoning for running the function in a thread is that it can be a footgun for users that their |
Right, I'm just saying that if the concern is ergonomics in eliminating one line of code ( |
Yup, that's totally fair, updated the example now to a real user issue that prompted this |
…n-a-separate-thread-in-case-user
Do we want to merge this? The issue isn't eliminating one line of code for the user, it's that users don't realize they are supposed to launch something in the background. It's a bit of a footgun. |
Can we add a small test? I agree this is valuable and prevents a common footgun. Since this is a slightly breaking change (startup_timeout, potential threading issues) we should definitely add a changelog entry about it. Maybe add a minor version bump as well? |
@@ -76,7 +77,8 @@ def construct_webhook_callable( | |||
|
|||
elif webhook_config.type == api_pb2.WEBHOOK_TYPE_WEB_SERVER: | |||
# Function spawns an HTTP web server listening at a port. | |||
user_defined_callable() | |||
server_thread = threading.Thread(target=user_defined_callable, name="web_server", daemon=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Somewhat separate from this (but made more apparent here), but it bothers me a bit that there is no clear graceful way to shut down a web server launched this way on container shutdown. (Assigning some variable to a class and adding an exit lifecycle method would work I suppose, but that's not symmetric to the launch itself)
…rom/mod-3841-run-web_server-function-in-a-separate-thread-in-case-user
Should the changelog call out the new timeout semantics? |
Yeah I understand that, but it's pretty quick to notice in development the issue and how to support it. I'd argue that the alternative is less flexible and could lead to subtle bugs in production. Developers already seem to set quite high startup timeouts, several minutes or more. With this change it would:
Would also like to implement a healthcheck / liveness loop and Elias said, which could be returned from this function. The current API is built to be forward compatible with this in mind. |
Also just wanted to mention this change is much harder to reverse than to apply, which makes it worth thinking about forward compatibility with a better API to support production workloads imo |
…rom/mod-3841-run-web_server-function-in-a-separate-thread-in-case-user
Describe your changes
Allows blocking calls in
web_server
decorated functions by running the user callable in a thread so you can do something like:instead of having to run it in a thread, since it can be confusing that the
web_server
decorator currently expects users to run everything in a background threadBackward/forward compatibility checks
Check these boxes or delete any item (or this section) if not relevant for this PR.
Note on protobuf: protobuf message changes in one place may have impact to
multiple entities (client, server, worker, database). See points above.
Changelog
Changes the
modal.web_server
decorator to run the user defined function in a thread instead of forcing users to handle this themselves. Previously you would have to do something like:but now we also support the blocking alternative:
This also changes the
startup_timeout
functionality which previously would start at the end of the function but will now start at the function beginning which may result in a need to increase the timeout.