Pulled in some other stuff from wiki. Honestly we need to rewrite most of this with better organization.

This commit is contained in:
Ryan Williams
2009-07-05 00:12:04 -07:00
parent 598b931602
commit 6ceae015cd
3 changed files with 86 additions and 2 deletions

46
doc/basic_usage.rst Normal file
View File

@@ -0,0 +1,46 @@
Basic Usage
===========
Most of the APIs required for basic eventlet usage are exported by the eventlet.api module.
Here are some basic functions that manipulate coroutines.
.. automethod:: eventlet.api::spawn
.. automethod:: eventlet.api::sleep
.. automethod:: eventlet.api::call_after
.. automethod:: eventlet.api::exc_after
Socket Functions
-----------------
Eventlet provides convenience functions that return green sockets. The green socket objects have the same interface as the standard library socket.socket object, except they will automatically cooperatively yield control to other eligible coroutines instead of blocking. Eventlet also has the ability to monkey patch the standard library socket.socket object so that code which uses it will also automatically cooperatively yield; see :ref:`using_standard_library_with_eventlet`.
''tcp_listener(address)''
Listen on the given address, a tuple of (ip, port), with a TCP socket. Returns a socket object on which one should call accept() to accept a connection on the newly bound socket.
''connect_tcp(address)''
Create a TCP connection to address, a tuple of (ip, port), and return the socket.
''ssl_listener(address, certificate, private_key)''
Listen on the given address, a tuple of (ip, port), with a TCP socket that can do SSL. certificate and private_key should be the filename of the appropriate certificate and private key files to use with the SSL socket.
.. _using_standard_library_with_eventlet:
Using the Standard Library with Eventlet
----------------------------------------
.. automethod:: eventlet.util::wrap_socket_with_coroutine_socket
Eventlet's socket object, whose implementation can be found in the ``eventlet.greenio`` module, is designed to match the interface of the standard library socket.socket object. However, it is often useful to be able to use existing code which uses socket.socket directly without modifying it to use the eventlet apis. To do this, one must call ``wrap_socket_with_coroutine_socket``. It is only necessary to do this once, at the beginning of the program, and it should be done before any socket objects which will be used are created. At some point we may decide to do this automatically upon import of eventlet; if you have an opinion about whether this is a good or a bad idea, please let us know.
.. automethod:: eventlet.util::wrap_select_with_coroutine_select
Some code which is written in a multithreaded style may perform some tricks, such as calling select with only one file descriptor and a timeout to prevent the operation from being unbounded. For this specific situation there is wrap_select_with_coroutine_select; however it<69>s always a good idea when trying any new library with eventlet to perform some tests to ensure eventlet is properly able to multiplex the operations. If you find a library which appears not to work, please mention it on the mailing list to find out whether someone has already experienced this and worked around it, or whether the library needs to be investigated and accommodated. One idea which could be implemented would add a file mapping between common module names and corresponding wrapper functions, so that eventlet could automatically execute monkey patch functions based on the modules that are imported.
TODO: We need to monkey patch os.pipe, stdin and stdout. Support for non-blocking pipes is done, but no monkey patching yet.

View File

@@ -0,0 +1,35 @@
Chat Server Example
---------------------
Let's look at a simple example, a chat server::
from eventlet import api
participants = [ ]
def read_chat_forever(writer, reader):
line = reader.readline()
while line:
print "Chat:", line.strip()
for p in participants:
if p is not writer: # Don't echo
p.write(line)
line = reader.readline()
participants.remove(writer)
print "Participant left chat."
try:
print "ChatServer starting up on port 3000"
server = api.tcp_listener(('0.0.0.0', 3000))
while True:
new_connection, address = server.accept()
print "Participant joined chat."
new_writer = new_connection.makefile('w')
participants.append(new_writer)
api.spawn(read_chat_forever, new_writer, new_connection.makefile('r'))
except KeyboardInterrupt:
print "ChatServer exiting."
The server shown here is very easy to understand. If it was written using Python's threading module instead of eventlet, the control flow and code layout would be exactly the same. The call to ``api.tcp_listener`` would be replaced with the appropriate calls to Python's built-in ``socket`` module, and the call to ``api.spawn`` would be replaced with the appropriate call to the ``thread`` module. However, if implemented using the ``thread`` module, each new connection would require the operating system to allocate another 8 MB stack, meaning this simple program would consume all of the RAM on a machine with 1 GB of memory with only 128 users connected, without even taking into account memory used by any objects on the heap! Using eventlet, this simple program should be able to accommodate thousands and thousands of simultaneous users, consuming very little RAM and very little CPU.
What sort of servers would require concurrency like this? A typical Web server might measure traffic on the order of 10 requests per second; at any given moment, the server might only have a handful of HTTP connections open simultaneously. However, a chat server, instant messenger server, or multiplayer game server will need to maintain one connection per connected user to be able to send messages to them as other users chat or make moves in the game. Also, as advanced Web development techniques such as Ajax, Ajax polling, and Comet (the "Long Poll") become more popular, Web servers will need to be able to deal with many more simultaneous requests. In fact, since the Comet technique involves the client making a new request as soon as the server closes an old one, a Web server servicing Comet clients has the same characteristics as a chat or game server: one connection per connected user.

View File

@@ -4,7 +4,7 @@ Eventlet
Eventlet is a networking library written in Python. It achieves high scalability by using `non-blocking io <http://en.wikipedia.org/wiki/Asynchronous_I/O#Select.28.2Fpoll.29_loops>`_ while at the same time retaining high programmer usability by using `coroutines <http://en.wikipedia.org/wiki/Coroutine>`_ to make the non-blocking io operations appear blocking at the source code level. Eventlet is a networking library written in Python. It achieves high scalability by using `non-blocking io <http://en.wikipedia.org/wiki/Asynchronous_I/O#Select.28.2Fpoll.29_loops>`_ while at the same time retaining high programmer usability by using `coroutines <http://en.wikipedia.org/wiki/Coroutine>`_ to make the non-blocking io operations appear blocking at the source code level.
Web Crawler Example Web Crawler Example
-------- -------------------
This is a simple web "crawler" that fetches a bunch of urls using a coroutine pool. It has as much concurrency (i.e. pages being fetched simultaneously) as coroutines in the pool. This is a simple web "crawler" that fetches a bunch of urls using a coroutine pool. It has as much concurrency (i.e. pages being fetched simultaneously) as coroutines in the pool.
@@ -73,7 +73,10 @@ Contents:
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
modules.rst basic_usage
chat_server_example
modules
Indices and tables Indices and tables
================== ==================