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.

[FEATURE] Make event-handling optional

See original GitHub issue

I’m trying to get Uvicorn to run as a Windows service so event logging and automatic start/restart can be handled more cleanly than by just running uvicorn as a scheduled task. I’ve run into a number of roadblocks, though most of these I’ve been able to work my way around with some configuration. The main roadbloack I still have is event-loop compatibility. Due to some odd behavior of Python threads while running as a windows service (see mhammond/pywin32#1452), it’s not currently possible for Python code to register signal handlers. That makes the default ProactorEventLoop unusable, but that can be solved by falling back to a SelectorEventLoop, which used to be the default event loop for Windows before Python 3.8. Not being able to handle the signal for Ctrl+C is not too much of a problem for my use case either, since I can just set the service to trip the Server#should_exit flag manually when the service is asked to stop.

So with all this said and done, if you ignore the service boilerplate wrapping my code, I’m essentially running Uvicorn like this:

import asyncio
import logging
from logging.handlers import NTEventLogHandler

from uvicorn import Server, Config
from app import app

asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

windows_log_handler = NTEventLogHandler('myASGIApp')
logging.getLogger().addHandler(windows_log_handler)

server_config = Config(
    app, host="0.0.0.0", port=8000,
    # Can't log to stdout as a service
    log_config={"version": 1},
    # Don't let uvicorn select what loop to use
    loop="asyncio",
)
self.app_server = Server(server_config)
self.app_server.run()

The main problem I still have with this is this line, which will try to setup event handlers even though doing so will immediately fail given my event loop configuration:

https://github.com/encode/uvicorn/blob/996aa2d459360f61507caa142b89a8f5b562cb6d/uvicorn/main.py#L360

https://github.com/encode/uvicorn/blob/996aa2d459360f61507caa142b89a8f5b562cb6d/uvicorn/main.py#L518-L527

I currently have to go and comment out that line in the uvicorn module code to get my application to start at all, which is less than ideal. Would it be possible to make signal handling optional if uvicorn is running from inside a Python script, maybe?

EDIT: I would have tried import uvicorn; uvicorn.main.HANDLED_SIGNALS = (), but it turns out that uvicorn.main:main is imported by uvicorn in a way that shadows the real uvicorn.main package, so even this awful hack is not an option.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
sm-Fifteencommented, Dec 13, 2019

Yeah, pretty much. Subclassing uvicorn.Server also seems like a much better workaround than what I had. (Why didn’t I think of that?)

0reactions
euri10commented, Dec 28, 2020

This should be fixed by https://github.com/encode/uvicorn/pull/871 without the need to subclass

Read more comments on GitHub >

github_iconTop Results From Across the Web

Pass Optional Event Handler to Custom Button - Stack Overflow
How can I modify my custom component so that it's optional for me to pass an event handler. I do not modify its...
Read more >
EventTarget.addEventListener() - Web APIs | MDN
An object that specifies characteristics about the event listener. The available options are: capture Optional. A boolean value indicating that ...
Read more >
ASP.NET Core Blazor event handling - Microsoft Learn
This article explains Blazor's event handling features, including event argument types, event callbacks, and managing default browser events.
Read more >
event handler Feature - hyperscript
Event handlers are used to handle events with hyperscript. They are typically embedded directly on the element that is responding to the event....
Read more >
Once upon an event listener - Chrome Developers
addEventListener now supports a once option, making it easier to define events that clean up after themselves.
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