Skip to content
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

WIP Server class to start applications #2465

Closed
wants to merge 4 commits into from

Conversation

cecton
Copy link
Contributor

@cecton cecton commented Nov 5, 2017

What do these changes do?

Attempt to answer to the issue raised on #2121 and #2375 by creating a Server class capable of registering multiple applications and providing a start() and a stop() asynchronous methods to allow the developers to open and close the server sockets to the application.

Are there changes in behavior for the user?

Added a Server class. web.run_app is preserved.

Related issue number

#2121 #2375

Checklist

  • I think the code is well written
  • Unit tests for the changes exist
  • Documentation reflects the changes
  • If you provide code modification, please add yourself to CONTRIBUTORS.txt
    • The format is <Name> <Surname>.
    • Please keep alphabetical order, the file is sorted by names.
  • Add a new news fragment into the CHANGES folder
    • name it <issue_id>.<type> for example (588.bug)
    • if you don't have an issue_id change it to the pr id after creating the pr
    • ensure type is one of the following:
      • .feature: Signifying a new feature.
      • .bugfix: Signifying a bug fix.
      • .doc: Signifying a documentation improvement.
      • .removal: Signifying a deprecation or removal of public API.
      • .misc: A ticket has been closed, but it is not of interest to users.
    • Make sure to use full sentences with correct case and punctuation, for example: "Fix issue with non-ascii contents in doctest text files."

@cecton cecton self-assigned this Nov 5, 2017
@cecton cecton requested a review from asvetlov November 5, 2017 09:16
@cecton
Copy link
Contributor Author

cecton commented Nov 5, 2017

@asvetlov is it more or less the idea you had in mind?

@@ -27,7 +27,7 @@
from .web_protocol import * # noqa
from .web_request import * # noqa
from .web_response import * # noqa
from .web_server import Server
from .web_server import Server as WebServer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rename web_server.Server into web_server.WebServer to avoid collisions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will break retro compatibility but we can maybe

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I just saw this in a test traceback:

>       srv = web.Server(handler)
E       TypeError: __init__() takes 1 positional argument but 2 were given

Which means the name Server is exported in aiohttp.web so I need to find another name than Server to avoid breaking compatibility.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, better to avoid this name collision somehow.

aiohttp/web.py Outdated
self.backlog = backlog
self.access_log_format = access_log_format
self.access_log = access_log
self.base_url = URL('{}://localhost'.format(scheme)).with_port(port)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URL.build was pretty nice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops sorry I missed this one 😀 I based my branch on an old version by mistake then I rebased too late when I realized my mistake.

Copy link
Member

@kxepal kxepal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice idea! Would be nice to see few examples about it usage.

return asyncio.gather(*server_creations, loop=self.loop)

@asyncio.coroutine
def start(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How could I start specific app in runtime after starting all the apps?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you mean. This is not meant to start selectively the applications. This is meant to group all the target applications and run them together on one connection. I mostly inspired on hapi's Glue for the concept.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean if Server object manages multiple applications, then why not you can't use it to register/start/stop arbitrary application is runtime? Quite oblivious task for it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't make it with the idea of changing the applications during runtime at all but it sounds like an interesting use case.

return self.uris

@asyncio.coroutine
def stop(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How could I stop specific app in runtime?

self._apps = []
self._servers = None

def register(self, app, *, prefix="/"):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How could I unregister specific app in runtime?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't at the moment. It's not meant to be mutable. I can try to implement it but this is not my priority. The code to create a server and register apps is pretty small and I suppose it's best to just re-instantiate a new one if you need to change something.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-instantiate a new server means to stop all the applications and cause a downtime. Not a good behaviour for adding a new app.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Same comment: it wasn't meant to avoid downtime, it was meant to allow running the apps without having to make aiohttp the center of the process)

@cecton
Copy link
Contributor Author

cecton commented Nov 5, 2017

I will give thorough examples and documentation if this is what we want for aiohttp to handle multiple applications (and running the applications without being the main process). Right now all I can say is that you could potentially do this:

Imagine you want to run side by side a grpc server and an application. Now you can by creating dynamically a Server object and registering your application. You just start it and it will work while your main program can do something else. You can stop anytime if you don't want to expose it all the time.

It also helps to gather Application objects and run them together. But then maybe it would be a good idea to allow web.run_app to take multiple positional arguments for apps and register all the apps to the server. [edit: done]

I suppose there are a lot of use cases for this but to be honest I have never encountered one yet professionally since I mostly did microservices.

Maybe @alexmnazarenko could give his input on this feature. It's just a sample at this point, we can add wait() or other things quite easily I suppose.

@asvetlov
Copy link
Member

asvetlov commented Nov 5, 2017

Looks as good concept.
I have a couple ideas for discussion.
We have too many server classes :)
We need another name.
What is the best name for Application instance serving specific TCP or UNIX port? Site maybe? I'm thinking about documentation.

Server from ./aiottp.web_server is a protocol factory for making a HTTP protocol for incoming connections. It could be used alone for making proxies etc.

Application is the most used kind of Server. It has a state, route table, nested apps etc.
The application creates a Server internally with handler hook to process routes etc.

Running Application could serve several sites on different ports or unix paths.

P.S.
From my taste web._make_server_creators function is a mess: it tries to solve too many use cases.
What's about making a Site base class with TCPSite, UNIXSite and SocketSite derivatives for processing host/port, path and sock parameters of run_app correspondingly? These classes shares almost everything except socket creation procedure.

@cecton
Copy link
Contributor Author

cecton commented Nov 5, 2017

Looks as good concept.

It tried to read in your mind 😀

We have too many server classes :)

👍

We need another name.
What's about making a Site base class with TCPSite, UNIXSite and SocketSite derivatives for processing host/port, path and sock parameters of run_app correspondingly? These classes shares almost everything except socket creation procedure.

That sounds like a great idea!

Running Application could serve several sites on different ports or unix paths.

Wait I'm lost. So you would rename Application to Site and this new Server to Application? But then it's TCPApplication, UnixApplication and SocketApplication isn't it? Also you can do a major release if you rename everything like that.

@asvetlov
Copy link
Member

asvetlov commented Nov 5, 2017

Wait I'm lost. So you would rename Application to Site and this new Server to Application? But then it's TCPApplication, UnixApplication and SocketApplication isn't it? Also you can do a major release if you rename everything like that.

No. Application should not be touched.
Site use Application for serving the app on specific host/port.
Another site could do the same for other port (think about HTTP/HTTPS).

@asvetlov asvetlov mentioned this pull request Nov 22, 2017
@asvetlov
Copy link
Member

Superseded by #2530

@asvetlov asvetlov closed this Nov 22, 2017
@asvetlov
Copy link
Member

@cecton I believe #2530 solves the problem better.
Big thank you for working on prototypes -- it allowed me to look on the problem from different points and find the final solution.

@cecton
Copy link
Contributor Author

cecton commented Nov 22, 2017

You're welcome :) I'm glad it helped!

@lock
Copy link

lock bot commented Oct 28, 2019

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.
If you feel like there's important points made in this discussion, please include those exceprts into that [new issue].
[new issue]: https://github.com/aio-libs/aiohttp/issues/new

@lock lock bot added the outdated label Oct 28, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 28, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants