[Web-SIG] Starting Web Servers using socket FDs

2012-06-05 Thread Tarek Ziadé

Hey

I am doing this experimentation where the WGSI server is not started 
with an host/port or a unix socket, but rather a FD value,

corresponding to a socket already bound by the parent process.

The server would then just accept new connection on the FD, using 
socket.fromfd() to get a socket object back,

and forget about all the binding work.

Here's a prototype based on wsgiref : 
https://github.com/tarekziade/chaussette


The goal I have is to be able to just spawn web workers using subprocess 
and take care myself  of the process
management part.  I wrote a blog post on my motivations here : 
http://blog.ziade.org/2012/06/12/shared-sockets-in-circus

if you want more background.

Anyways, the idea I wanted to bring here was the following:

most web servers out there support regular host/port or Unix Socket, 
which are usually the unix: prefix followed by a path on the system.


What if web servers had these two standards *and* a new one which would 
be a fd: prefix.


For instance, we would start server foo with:

$ foo --fd:12:localhost:8080

Where 12 is the fd number the foo server would use for getting the 
socket, and localhost:8080 would just be there

as an information to be able to fill some WGSI headers that requires it.

From there I could just spawn foo and pass to it socket.fileno()

Thoughts ?

Cheers
Tarek
___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] Starting Web Servers using socket FDs

2012-06-05 Thread Roberto De Ioris

Il giorno 05/giu/2012, alle ore 11:30, Tarek Ziadé ha scritto:

 Hey 
 
 I am doing this experimentation where the WGSI server is not started with an 
 host/port or a unix socket, but rather a FD value, 
 corresponding to a socket already bound by the parent process. 
 
 The server would then just accept new connection on the FD, using 
 socket.fromfd() to get a socket object back, 
 and forget about all the binding work. 
 
 Here's a prototype based on wsgiref : 
 https://github.com/tarekziade/chaussette 
 
 The goal I have is to be able to just spawn web workers using subprocess and 
 take care myself  of the process 
 management part.  I wrote a blog post on my motivations here : 
 http://blog.ziade.org/2012/06/12/shared-sockets-in-circus 
 if you want more background. 
 
 Anyways, the idea I wanted to bring here was the following: 
 
 most web servers out there support regular host/port or Unix Socket, which 
 are usually the unix: prefix followed by a path on the system. 
 
 What if web servers had these two standards *and* a new one which would be a 
 fd: prefix. 
 
 For instance, we would start server foo with: 
 
 $ foo --fd:12:localhost:8080 
 
 Where 12 is the fd number the foo server would use for getting the socket, 
 and localhost:8080 would just be there 
 as an information to be able to fill some WGSI headers that requires it. 
 
 From there I could just spawn foo and pass to it socket.fileno() 
 
 Thoughts ? 
 

This is the approach used by fastcgi (even if only on file descriptor 0), old 
inetd-style daemons, and newer upstart and systemd daemons.

Gunicorn can already bind (or better, accept) from file descriptors specifying 
an environment variable. uWSGI supports by-default the inheritance of file 
descriptor 0 for fcgi-like startup,
and working on generic file descriptor or inet/upstart/systemd socket 
activation.

The vast majority of modern systems expects the file descriptor number on an 
environment variable:

upstart: UPSTART_FDS
systemd: LISTEN_FDS

Circus, could follow the same behaviour, but i do not know if a standard will 
be required for that.

Regarding the --fd:12:localhost:8080 syntax, is redundant as you can get the 
name of the socket mapped to a file descriptor
with getsockname:

http://linux.die.net/man/2/getsockname

--
Roberto De Ioris
http://unbit.it
JID: robe...@jabber.unbit.it

___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] Starting Web Servers using socket FDs

2012-06-05 Thread Tarek Ziadé

On 6/5/12 11:46 AM, Roberto De Ioris wrote:

...
Gunicorn can already bind (or better, accept) from file descriptors specifying 
an environment variable.
I don't think you can start gunicorn using a file descriptor, or I 
failed to do it. The best I was able to do was to create a small wsgi server

using Gunicorn as a lib.

Gunicorn uses an environment variable when it respawns workers but it 
does not offer it as a public option as far as I understand how it works



uWSGI supports by-default the inheritance of file descriptor 0 for fcgi-like 
startup,
and working on generic file descriptor or inet/upstart/systemd socket 
activation.
I did not find a way to start it using a provided fd -- they are 
plethora of options though, maybe I missed it

The vast majority of modern systems expects the file descriptor number on an 
environment variable:

upstart: UPSTART_FDS
systemd: LISTEN_FDS

Yes, this seem fairly standard.


Circus, could follow the same behaviour, but i do not know if a standard will 
be required for that.
The goal of the standard is just to be able to place any wsgi server out 
there and have it working out of the box.


So far I was not able to run an existing wsgi server like this without 
changing its code because they

all make the assumption they will be run with a host and port.



Regarding the --fd:12:localhost:8080 syntax, is redundant as you can get the 
name of the socket mapped to a file descriptor
with getsockname:

http://linux.die.net/man/2/getsockname

Will look into this again, I had an issue trying to do it.

Thanks for the feedback!



--
Roberto De Ioris
http://unbit.it
JID: robe...@jabber.unbit.it



___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] Starting Web Servers using socket FDs

2012-06-05 Thread Benoit Chesneau
On Tue, Jun 5, 2012 at 12:26 PM, Tarek Ziadé ta...@ziade.org wrote:
 On 6/5/12 11:46 AM, Roberto De Ioris wrote:

 ...

 Gunicorn can already bind (or better, accept) from file descriptors
 specifying an environment variable.

 I don't think you can start gunicorn using a file descriptor, or I failed to
 do it. The best I was able to do was to create a small wsgi server
 using Gunicorn as a lib.

 Gunicorn uses an environment variable when it respawns workers but it does
 not offer it as a public option as far as I understand how it works


export GUNICORN_FD=your fd

and then gunicorn will use this file descriptor when it starts.

But it should be possible to pass it directly using a config option if
it's needed.

- benoît
___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] Starting Web Servers using socket FDs

2012-06-05 Thread Tarek Ziadé

On 6/5/12 11:41 AM, anatoly techtonik wrote:

On Tue, Jun 5, 2012 at 12:30 PM, Tarek Ziadéta...@ziade.org  wrote:

Thoughts ?

I've skimmed over the text and couldn't find any user story. What is
the end goal?
use a web server as a standalone, isolated process, with nothing but a 
single main thread that gets request then send back response.


then have Circus do all the processes management.


What is the responsibility of web server, web app and your controlling app?


- The web server accept() connections on a socket and transforms a 
request into a wsgi environ it passes to a wsgi application  [Meinheld, 
Bjoern, Whatever..]
- The web app is a classical wsgi application that handles 
start_response and return a list of strings   [the application that 
follows the wsgi standard]
- The controlling app manages the life of the sockets and also manage 
the life of web app processes   [Circus]



Who should control keep-alives and connection drops?


I don't know I did not get into those details yet.


Cheers
Tarek

___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] Starting Web Servers using socket FDs

2012-06-05 Thread Tarek Ziadé

On 6/5/12 12:31 PM, Benoit Chesneau wrote:

On Tue, Jun 5, 2012 at 12:26 PM, Tarek Ziadéta...@ziade.org  wrote:

On 6/5/12 11:46 AM, Roberto De Ioris wrote:

...

Gunicorn can already bind (or better, accept) from file descriptors
specifying an environment variable.

I don't think you can start gunicorn using a file descriptor, or I failed to
do it. The best I was able to do was to create a small wsgi server
using Gunicorn as a lib.

Gunicorn uses an environment variable when it respawns workers but it does
not offer it as a public option as far as I understand how it works



export GUNICORN_FD=your fd

and then gunicorn will use this file descriptor when it starts.

But it should be possible to pass it directly using a config option if
it's needed.
What you be great then is to be able to run Gunicorn as a single process 
without having it forking workers,
because the main goal is to be able to manage that process directly in 
Circus -- e.g. skip all the arbiter part in Gunicorn


My attempt at this was this hack : 
https://github.com/tarekziade/chaussette/commit/075003a24ffe92253da60aafc6f99062e0af267d#diff-3


Cheers
Tarek



- benoît


___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] Starting Web Servers using socket FDs

2012-06-05 Thread Tarek Ziadé

On 6/5/12 1:56 PM, Roberto De Ioris wrote:

uWSGI supports by-default the inheritance of file descriptor 0 for fcgi-like 
startup,
and working on generic file descriptor or inet/upstart/systemd socket 
activation.

I did not find a way to start it using a provided fd -- they are plethora of 
options though, maybe I missed it


it is automatic if the fd is the zero one, otherwise you have to authenticate 
it adding a --socket/--http-socket/--fastcgi-socket directive
mapping to the address (this is required for avoiding uWSGI inheriting 
unrelated sockets, like the ones created by ssh-agents and whatever you want).

For example if you map fd 17 to 192.168.1.1:4040 you have to run uwsgi with

--socket 192.168.1.1:4040

it will find fd 17 mapped to a socket, and it will know the socket is 
authorized to be used.

Other components take the special fd://n  syntax (like the various routers) 
but i do not think you are intersted in them


Great, thanks, will try this





The vast majority of modern systems expects the file descriptor number on an 
environment variable:

upstart: UPSTART_FDS
systemd: LISTEN_FDS

Yes, this seem fairly standard.

Circus, could follow the same behaviour, but i do not know if a standard will 
be required for that.

The goal of the standard is just to be able to place any wsgi server out there 
and have it working out of the box.

if this is your objective i suggest you to follow the inetd/fastcgi style 
approach and use file descriptor 0 as the communication socket.
Flup and uWSGI will work over this automatically. Gunicorn will work simply 
adding GUNICORN_FD=0

Adding another env-var will mean each server will need to add a condition for 
that (like upstart and systemd)
The thing is, the main process might bind several sockets, and have 
various subprocesses linked to specific ones, so I guess the uWsgi --socket

approach is the most straightforward

Thanks for all the info


--
Roberto De Ioris
http://unbit.it
JID: robe...@jabber.unbit.it



___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com


Re: [Web-SIG] Starting Web Servers using socket FDs

2012-06-05 Thread Roberto De Ioris

Il giorno 05/giu/2012, alle ore 12:26, Tarek Ziadé ha scritto:

 On 6/5/12 11:46 AM, Roberto De Ioris wrote:
 ...
 Gunicorn can already bind (or better, accept) from file descriptors 
 specifying an environment variable.
 I don't think you can start gunicorn using a file descriptor, or I failed to 
 do it. The best I was able to do was to create a small wsgi server
 using Gunicorn as a lib.
 
 Gunicorn uses an environment variable when it respawns workers but it does 
 not offer it as a public option as far as I understand how it works


benoit has already answered about that

 
 uWSGI supports by-default the inheritance of file descriptor 0 for fcgi-like 
 startup,
 and working on generic file descriptor or inet/upstart/systemd socket 
 activation.
 I did not find a way to start it using a provided fd -- they are plethora of 
 options though, maybe I missed it


it is automatic if the fd is the zero one, otherwise you have to authenticate 
it adding a --socket/--http-socket/--fastcgi-socket directive
mapping to the address (this is required for avoiding uWSGI inheriting 
unrelated sockets, like the ones created by ssh-agents and whatever you want).

For example if you map fd 17 to 192.168.1.1:4040 you have to run uwsgi with

--socket 192.168.1.1:4040 

it will find fd 17 mapped to a socket, and it will know the socket is 
authorized to be used.

Other components take the special fd://n syntax (like the various routers) 
but i do not think you are intersted in them



 The vast majority of modern systems expects the file descriptor number on an 
 environment variable:
 
 upstart: UPSTART_FDS
 systemd: LISTEN_FDS
 Yes, this seem fairly standard.
 
 Circus, could follow the same behaviour, but i do not know if a standard 
 will be required for that.
 The goal of the standard is just to be able to place any wsgi server out 
 there and have it working out of the box.

if this is your objective i suggest you to follow the inetd/fastcgi style 
approach and use file descriptor 0 as the communication socket.
Flup and uWSGI will work over this automatically. Gunicorn will work simply 
adding GUNICORN_FD=0

Adding another env-var will mean each server will need to add a condition for 
that (like upstart and systemd)

--
Roberto De Ioris
http://unbit.it
JID: robe...@jabber.unbit.it

___
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com