-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Split async server running functions #2121
Comments
aiohttp does not need to be the center of your app. Have a look at what the You can copy some of that logic in your code, and trigger your |
Anyway keeping separate startup and shutdown functions in public api makes sense. |
In my project, I've implemented AsyncServer class for the very same reasons. Something like this: class AsyncServer:
def __init__(...run_app params..)
async def start()
async def shutdown()
async def wait()
async def __aenter__()
async def __aexit__() Works fine ) Something like this will be nice to have right in the library. |
I have to add my +1 to fixing this. IMHO, the best thing would be to have a async def my_suff():
...
def main():
loop = asyncio.get_event_loop()
app = web.Application()
....
loop.run_until_complete(
asyncio.gather(
app.run("0.0.0.0", 80),
run_my_stuff(),
)
) Now wouldn't that be lovely? ;-) |
No, it should be a separate class. |
In that case, I think something like @alexmnazarenko's |
@gjcarneiro Yes, it is: https://github.com/datadvance/pRpc/blob/master/prpc/platform/ws_aiohttp.py But it's not feature complete for inclusion in aiohttp itself. I've dropped support for UDP sockets as I don't need it for know. Still, it works well for me allowing to run multiple servers on different ports in a single asyncio app. |
I don't get that part. During the lifetime of the main process you want your web service to be started and stopped? Can you explain a use case for that? @txomon @alexmnazarenko can you explain the use case? I just checked the pRpc library which does provide the lib but doesn't really use it except for tests. |
In my case, this was part of a bot, which had many other things running at the same time. If i wanted to expose an API, but it wasn't the main objective of the server, I would still need to set this as the main process. The idea is that aiohttp shouldn't be expected to be the centre of the app. |
Does the API you're exposing get not exposed at some point? Or is the API always running until the end of the process?
In the current state of the project, is it now possible to start your bot with and without API? Or did it evolve from a loop to a web service?
That I get 😁 but it seems to me that if aiohttp is not the center of the application, then the application exposes an API for some time and then remove it. This particular use case doesn't make much sense to me. |
This specific bot has several configuration options, working in some cases using websockets, other times push http notifications and others both. Coupling the main process to the webserver process would make it need to have the webserver up regardless on the configuration. Also, it has hot plugin (re)loading, and the webserver may be terminated and restarted to accommodate new endpoints. |
Thx! Makes a lot more sense now. What do you need exactly in the
|
The best for me would to actually have those features separated in different functions, that I can decide to use or not. In my case, I don't make any difference between server creation/closure and the startup, clean and shutdown hooks. I'm not familiar on the internals, but in my case, having functions that can be used like the following:
Where steps 2 and 3 can be looped (to restart the service). Maybe you don't need to have steps 1/4, but just following on the design pattern of other libs, such as libcurl |
@cecton As of my usecases:
Example of multiple apps usecase: Here I have an program that uses HTTP for everything - for RPC, for administration and more. RPC and admin apps must have different endpoints (admin is usually localhost only). |
Cool! Thanks a lot for all your feedbacks. I believe signal handling is out of the scope here so we should probably have a I'm not too much into introducing a new object. @asvetlov do you think we can add the start and stop methods on the class Then I will reduce Do you think that will cover it all? I skipped the async context and the wait method because I don't think they are any useful but let me know if I'm totally wrong. @asvetlov cecton@3b8a782 here a sample |
That should help, 'wait' and other convenience stuff can be easily implemented externally. The main point for me is to avoid copying the whole run_app signal stuff (as it can change between versions). |
Ok perfect then? I will make some tests and see if it works as expected. What is the use case of a "wait" by the way? Because you should be able to achieve the same thing by using the cleanup hook. What also would be the use case for an async context like you implemented? In tests maybe? When you say "signals" you mean the "signals"/hooks of the application right? Not the Unix signals? |
Yeap, "ok perfect" 😄
PS in your code sample "await self.cleanup()" is called twice? |
Yes it was just a sample 😫 I did it really fast to show to Andrew what I had in mind. |
I not sure should we add new methods and state into |
@asvetlov I haven't thought about that and that's a good point. From my point of view it seems that the logic of Application is well scoped in the class itself. It was weird to have it spread in a different method. |
New class is fine by me. As I wrote, I just want to remove hook/socket handling from my code as it's an 'unstable' copypaste from the framework. Also, I forgot - my implementation had a nice bonus of returning 'resolved' bound endpoints. That's very helpful when you use port '0'. |
Looks like we need a Pull Request. |
@asvetlov I will but not now 😀 after office hours |
@asvetlov so I make a different class or I put it in application? |
I suggest a different class. |
@asvetlov maybe I can make a class that takes multiple Application classes and do the whole job? Everything will be called once. |
Maybe it's good idea, let's look on API. |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a [new issue] for related bugs. |
Long story short
The requirement to have
run_app
as only execution of the server is not enough for some applications. It would be nice if this run_app functionality could be divided in two functions,start()
andcleanup()
, as many other libraries do. After all aiohttp is not the core of my app.The idea is I want to be in charge of the main loop and control how and when it runs.
Expected behaviour
Not to modify existing applications when including aiohttp.
Actual behaviour
aiohttp
get's to be the centre of the application by runningrun_forever()
inside the only provided function to run the web server part.Steps to reproduce
asyncio
applicationThe text was updated successfully, but these errors were encountered: