summaryrefslogtreecommitdiff
path: root/doc/src/advanced.rst
diff options
context:
space:
mode:
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>2010-04-04 03:10:18 +0100
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>2010-04-21 15:21:32 +0100
commita54932ee9c086f658881b4d1141646d82fdc98db (patch)
tree11d0307618bc31761ad57e7bc3daa81f268d0c7e /doc/src/advanced.rst
parent127f92f9dbbbb54930b8e9c06ba5639ec3ef201b (diff)
downloadpsycopg2-a54932ee9c086f658881b4d1141646d82fdc98db.tar.gz
Added documentation for the green features.
Diffstat (limited to 'doc/src/advanced.rst')
-rw-r--r--doc/src/advanced.rst69
1 files changed, 69 insertions, 0 deletions
diff --git a/doc/src/advanced.rst b/doc/src/advanced.rst
index b8ed537..13def38 100644
--- a/doc/src/advanced.rst
+++ b/doc/src/advanced.rst
@@ -362,6 +362,75 @@ this will be probably implemented in a future release.
+
+.. index::
+ single: Greenlet, Coroutine, eventlet, gevent, Wait callback
+
+.. _green-support:
+
+Support to coroutine libraries
+------------------------------
+
+.. versionadded:: 2.2.0
+
+Psycopg can be used together with coroutine_\-based libraries, and participate
+to cooperative multithread.
+
+Coroutine-based libraries (such as Eventlet_ or gevent_) can usually patch the
+Python standard library in order to enable a coroutine switch in presence of
+blocking I/O: the process is usually referred as making the system *green*, in
+reference to greenlet_, the basic Python micro-thread library.
+
+Because Psycopg is a C extension module, it is not possible for coroutine
+libraries to patch it: Psycopg instead enables cooperative multithreading by
+allowing the registration of a *wait callback* using the
+`psycopg2.extensions.set_wait_callback()` function. When a wait callback is
+registered, Psycopg will use `libpq non-blocking calls`__ instead of the regular
+blocking ones, and will delegate to the callback the responsibility to wait
+for available data.
+
+This way of working is less flexible of complete asynchronous I/O, but has the
+advantage of maintaining a complete |DBAPI| semantics: from the point of view
+of the end user, all Psycopg functions and objects will work transparently
+in the coroutine environment (the calling coroutine will be blocked while
+other coroutines can be scheduled to run), allowing non modified code and
+third party libraries (such as SQLAlchemy_) to be used in coroutine-based
+programs.
+
+Notice that, while I/O correctly yields control to other coroutines, each
+connection has a lock allowing a single cursor at time to communicate with the
+backend: such lock is not *green*, so blocking against it would block the
+entire program waiting for data, not the single coroutine. Therefore,
+programmers are advised to either avoid to share connections between coroutines
+or to use a library-friendly lock to synchronize shares connections, e.g. for
+pooling.
+
+Coroutine libraries authors should provide a callback implementation (and
+probably register it) to make Psycopg as green as they want. An example
+callback (using `!select()` to block) is provided as
+`psycopg2.extras.wait_select()`: it boils down to something similar to::
+
+ def wait_select(conn):
+ while 1:
+ state = conn.poll()
+ if state == extensions.POLL_OK:
+ break
+ elif state == extensions.POLL_READ:
+ select.select([conn.fileno()], [], [])
+ elif state == extensions.POLL_WRITE:
+ select.select([], [conn.fileno()], [])
+ else:
+ raise OperationalError("bad state from poll: %s" % state)
+
+.. _coroutine: http://en.wikipedia.org/wiki/Coroutine
+.. _greenlet: http://pypi.python.org/pypi/greenlet
+.. _Eventlet: http://eventlet.net/
+.. _gevent: http://www.gevent.org/
+.. _SQLAlchemy: http://www.sqlalchemy.org/
+.. __: http://www.postgresql.org/docs/8.4/static/libpq-async.html
+
+
+
.. testcode::
:hide: