About

FAPWS (Fast Asynchronous Python Web Server) is a fully WSGI compliant web server for the Python environment with 2 main objectives: keep it small and asynchronous. That way it will not heat your HW resources and will assure to not fall into C10K troubles.

Features

As FAPWSs goal is to stay as simple as possible:

Use Cases

Static file server

FAPWS can be used to serve a huge amount of static file requests. With the help of a async database in the backend, you can use FAPWS as your own Amazon S3.

In combination with Django

Are you tired of using mod_python because Apache is sucking your memory? You can use FAPWS to run your normal Django app. If you have a lot of concurrent requests, just start 10 instances of FAPWS and let a load balancer like (Pound, HA-Proxy, NGINX) handle the requests for you.

Run your webservice on FAPWS

Do you need a fast way to server API requests? With a minimal overhead you have the possibility to speed up your API in minutes by migrating to FAPWS. Its event-based design is well suited for developing webservices.

Design

FAPWS is based on libev; and the main objectives of FAPWS are speed and light memory foot print. This explain that the majority of core functionalities are written in C. The rest will be written in python and compliant to the WSGI recommendations. The wsgi callback methods use to present the content must return a list of strings, a file object or an iterative object. Side to the core functionalities, you'll find some powerful and nice features in the "contrib" directory.

I've not the intent to implement SSH, threading, proxying, ... within the core part of FAPWS because other tools are already offering those functionalities. I recommend "pound" for those who want to have SSH, load balancing and multi tasking. Since FAPWS is very lite, do not hesitate to start 10 or 20 different instances and configure your load balancer to spread the load between all of them. You could also have one FAPWS instance to just server the static files.

FAQ

Q: FAPWS is not thread compliant !
A: It does not have and will, most probably never have. This is a hard point of view, but if you are looking for performance, take attention to the design of your application and remove bottle necks. Take advantage of the network asynchronous feature of FAPWS. Or multiply the number of FAPWS servers and spread the load via a load balancer. If you need to have 30 concurrent users, do not hesitate to run 30 FAPWS servers in parallel.

Q: How to deal with slow commit to DB tasks ?
A: Design !!! Design !!!! You have to clearly decide between persistence of data or performance. Do not ask your webserver to solve the other's problem. But here the proposed solution is to multiply the number of FAPWS servers. If possible externalize the commit within a timer (look at the timer sample).
An better alternative would be to use a non-bocking, async, DB.

Q: FAPWS crash (segmentation fault) with the hello_world sample !
A: assure you have compiled it with correct python and libev libraries. On some 64bits linux distro, you have both 32bits and 64bits libraries, do not mix them up. You can manage this via the environmental parameters: LD_LIBRARY_PATH and C_INCLUDE_PATH before compiling. An another possibility would be to change the event's backend via the environmental parameter: LIBEV_FLAGS

Q: What does asynchronous means ?
A: FAPWS is asynchronous. That means that he can deliver a new content while he is delivering an another one. All within the same process and without threads. FAPWS will not wait the end of a request before treating a new one, he is not synchronous.

Q: FAPWS is asynchronous, but my long task blocks the whole server. Why ?
A: FAPWS treats asynchronously for python file objects, iterrable object and list objects. He delivers their content blocks per blocks whatever for which requests. But since all this algorithm is encapsulated within the same process, a long processing task will block all the other requests. That’s why you have to avoid them; if not possible then start several instances of FAPWS and spread the load via a load balancer.

Q: what’s the concept of Timers ?
A: With timers you can split the tasks into 2 categories. The one immediately required for the web pages and the others (update DB, update logs, save some data on a text file, …). In that way, you will memorize some data in memory and the timers will store them into the disks. Since disks are slow, thanks to timers, you’ll be able to speed-up the rendering of your web pages. But be careful, I’m not saying that you can always externalize your commits into a timers. It depends, for sure.

Q: What’s the concept of Defer ?
A: With defer you also externalize a task from your normal path (rendering webpages). With the defer, you store some tasks into a dedicated queue: the defer queue. FAPWS will execute them (FIFO) when he will have the time to do it (idle). You can store there as many as you want, but be careful to not goes over the limit. The defer queue stores the callback function and his parameter (always required).

Q: With Defer, what’s the “combined” concept ?
A: Since, most of the time the tasks you can defer are linked to storing some data, it’s not required to execute it 100x. Once, is good. By setting the combined parameter to True, you ask FAPWS to first checks if the callback function, and his associated parameters, are already in the defer queue. Only if he not finds them, he will append them in the queue.

License

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Fork me on GitHub