Hello community,

here is the log from the commit of package python-eventlet for openSUSE:Factory 
checked in at 2013-02-08 14:44:05
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-eventlet (Old)
 and      /work/SRC/openSUSE:Factory/.python-eventlet.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-eventlet", Maintainer is "[email protected]"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-eventlet/python-eventlet.changes  
2013-01-20 08:16:20.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.python-eventlet.new/python-eventlet.changes     
2013-02-08 23:24:46.000000000 +0100
@@ -1,0 +2,11 @@
+Fri Feb  8 11:19:25 UTC 2013 - [email protected]
+
+- Update to version 0.12.1:
+  * zmq: Fix 100% busy CPU in idle after .bind(PUB)
+  * greenio: Fix socket.settimeout() did not switch back to blocking mode
+  * greenio: socket.dup() made excess fcntl syscalls
+  * setup: Remove legacy --without-greenlet option and unused httplib2 
dependency
+  * wsgi: environ[REMOTE_PORT], also available in log_format, log accept event
+  * tests: Support libzmq 3.0 SNDHWM option
+
+-------------------------------------------------------------------

Old:
----
  eventlet-0.11.0.tar.gz

New:
----
  eventlet-0.12.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-eventlet.spec ++++++
--- /var/tmp/diff_new_pack.970e0Y/_old  2013-02-08 23:24:51.000000000 +0100
+++ /var/tmp/diff_new_pack.970e0Y/_new  2013-02-08 23:24:51.000000000 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           python-eventlet
-Version:        0.11.0
+Version:        0.12.1
 Release:        0
 Url:            http://eventlet.net
 Summary:        Highly concurrent networking library

++++++ eventlet-0.11.0.tar.gz -> eventlet-0.12.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/eventlet-0.11.0/AUTHORS new/eventlet-0.12.1/AUTHORS
--- old/eventlet-0.11.0/AUTHORS 2013-01-14 00:46:06.000000000 +0100
+++ new/eventlet-0.12.1/AUTHORS 2013-01-24 11:18:17.000000000 +0100
@@ -30,6 +30,7 @@
 * Nick V
 * Daniele Varrazzo
 * Ryan Williams
+* Geoff Salmon
 
 Linden Lab Contributors
 -----------------------
@@ -78,3 +79,5 @@
 * Eric Windisch, zmq getsockopt(EVENTS) wake correct threads (pull request 22)
 * Raymond Lu, fixing busy-wait in eventlet.green.ssl.socket.sendall()
 * Thomas Grainger, webcrawler example small fix, "requests" library import bug 
report
+* Peter Portante, save syscalls in socket.dup(), environ[REMOTE_PORT] in wsgi
+* Peter Skirko, fixing socket.settimeout(0) bug
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/eventlet-0.11.0/NEWS new/eventlet-0.12.1/NEWS
--- old/eventlet-0.11.0/NEWS    2013-01-13 23:43:27.000000000 +0100
+++ new/eventlet-0.12.1/NEWS    2013-01-24 11:18:17.000000000 +0100
@@ -1,3 +1,12 @@
+0.12
+====
+* zmq: Fix 100% busy CPU in idle after .bind(PUB) (thanks to Geoff Salmon)
+* greenio: Fix socket.settimeout() did not switch back to blocking mode 
(thanks to Peter Skirko)
+* greenio: socket.dup() made excess fcntl syscalls (thanks to Peter Portante)
+* setup: Remove legacy --without-greenlet option and unused httplib2 
dependency (thanks to Thomas Grainger)
+* wsgi: environ[REMOTE_PORT], also available in log_format, log accept event 
(thanks to Peter Portante)
+* tests: Support libzmq 3.0 SNDHWM option (thanks to Geoff Salmon)
+
 0.11
 ====
 * ssl: Fix 100% busy CPU in socket.sendall() (thanks to Raymon Lu)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/eventlet-0.11.0/PKG-INFO new/eventlet-0.12.1/PKG-INFO
--- old/eventlet-0.11.0/PKG-INFO        2013-01-14 01:13:35.000000000 +0100
+++ new/eventlet-0.12.1/PKG-INFO        2013-01-26 02:04:37.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: eventlet
-Version: 0.11.0
+Version: 0.12.1
 Summary: Highly concurrent networking library
 Home-page: http://eventlet.net
 Author: Linden Lab
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/eventlet-0.11.0/eventlet/__init__.py 
new/eventlet-0.12.1/eventlet/__init__.py
--- old/eventlet-0.11.0/eventlet/__init__.py    2013-01-13 23:16:35.000000000 
+0100
+++ new/eventlet-0.12.1/eventlet/__init__.py    2013-01-26 02:00:16.000000000 
+0100
@@ -1,4 +1,4 @@
-version_info = (0, 11, 0)
+version_info = (0, 12, 1)
 __version__ = ".".join(map(str, version_info))
 
 try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/eventlet-0.11.0/eventlet/green/zmq.py 
new/eventlet-0.12.1/eventlet/green/zmq.py
--- old/eventlet-0.11.0/eventlet/green/zmq.py   2013-01-13 22:41:38.000000000 
+0100
+++ new/eventlet-0.12.1/eventlet/green/zmq.py   2013-01-23 10:34:03.000000000 
+0100
@@ -205,8 +205,13 @@
             # Some events arrived at the zmq socket. This may mean
             # there's a message that can be read or there's space for
             # a message to be written.
-            self._eventlet_send_event.wake()
-            self._eventlet_recv_event.wake()
+            send_wake = self._eventlet_send_event.wake()
+            recv_wake = self._eventlet_recv_event.wake()
+            if not send_wake and not recv_wake:
+                # if no waiting send or recv thread was woken up, then
+                # force the zmq socket's events to be processed to
+                # avoid repeated wakeups
+                _Socket_getsockopt(self, EVENTS)
 
         hub = hubs.get_hub()
         self._eventlet_listener = hub.add(hub.READ, self.getsockopt(FD), event)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/eventlet-0.11.0/eventlet/greenio.py 
new/eventlet-0.12.1/eventlet/greenio.py
--- old/eventlet-0.11.0/eventlet/greenio.py     2013-01-12 01:52:22.000000000 
+0100
+++ new/eventlet-0.12.1/eventlet/greenio.py     2013-01-24 11:18:17.000000000 
+0100
@@ -97,8 +97,10 @@
                                       "(Windows pipes don't support 
non-blocking I/O)")
         # We managed to import fcntl.
         fileno = fd.fileno()
-        flags = fcntl.fcntl(fileno, fcntl.F_GETFL)
-        fcntl.fcntl(fileno, fcntl.F_SETFL, flags | os.O_NONBLOCK)
+        orig_flags = fcntl.fcntl(fileno, fcntl.F_GETFL)
+        new_flags = orig_flags | os.O_NONBLOCK
+        if new_flags != orig_flags:
+            fcntl.fcntl(fileno, fcntl.F_SETFL, new_flags)
     else:
         # socket supports setblocking()
         setblocking(0)
@@ -114,8 +116,13 @@
     """
     Green version of socket.socket class, that is intended to be 100%
     API-compatible.
+
+    It also recognizes the keyword parameter, 'set_nonblocking=True'.
+    Pass False to indicate that socket is already in non-blocking mode
+    to save syscalls.
     """
     def __init__(self, family_or_realsock=socket.AF_INET, *args, **kwargs):
+        should_set_nonblocking = kwargs.pop('set_nonblocking', True)
         if isinstance(family_or_realsock, (int, long)):
             fd = _original_socket(family_or_realsock, *args, **kwargs)
         else:
@@ -129,7 +136,8 @@
         except AttributeError:
             self._timeout = socket.getdefaulttimeout()
 
-        set_nonblocking(fd)
+        if should_set_nonblocking:
+            set_nonblocking(fd)
         self.fd = fd
         # when client calls setblocking(0) or settimeout(0) the socket must
         # act non-blocking
@@ -209,8 +217,7 @@
 
     def dup(self, *args, **kw):
         sock = self.fd.dup(*args, **kw)
-        set_nonblocking(sock)
-        newsock = type(self)(sock)
+        newsock = type(self)(sock, set_nonblocking=False)
         newsock.settimeout(self.gettimeout())
         return newsock
 
@@ -313,8 +320,10 @@
         if howlong < 0.0:
             raise ValueError('Timeout value out of range')
         if howlong == 0.0:
-            self.setblocking(howlong)
+            self.act_non_blocking = True
+            self._timeout = 0.0
         else:
+            self.act_non_blocking = False
             self._timeout = howlong
 
     def gettimeout(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/eventlet-0.11.0/eventlet/wsgi.py 
new/eventlet-0.12.1/eventlet/wsgi.py
--- old/eventlet-0.11.0/eventlet/wsgi.py        2013-01-12 01:52:22.000000000 
+0100
+++ new/eventlet-0.12.1/eventlet/wsgi.py        2013-01-24 11:18:17.000000000 
+0100
@@ -18,6 +18,7 @@
 MAX_HEADER_LINE = 8192
 MAX_TOTAL_HEADER_SIZE = 65536
 MINIMUM_CHUNK_SIZE = 4096
+# %(client_port)s is also available
 DEFAULT_LOG_FORMAT= ('%(client_ip)s - - [%(date_time)s] "%(request_line)s"'
                      ' %(status_code)s %(body_length)s %(wall_seconds).6f')
 
@@ -429,16 +430,17 @@
 
             for hook, args, kwargs in self.environ['eventlet.posthooks']:
                 hook(self.environ, *args, **kwargs)
-            
+
             if self.server.log_output:
-                
-                self.server.log_message(self.server.log_format % dict(
-                    client_ip=self.get_client_ip(),
-                    date_time=self.log_date_time_string(),
-                    request_line=self.requestline,
-                    status_code=status_code[0],
-                    body_length=length[0],
-                    wall_seconds=finish - start))
+                self.server.log_message(self.server.log_format % {
+                    'client_ip': self.get_client_ip(),
+                    'client_port': self.client_address[1],
+                    'date_time': self.log_date_time_string(),
+                    'request_line': self.requestline,
+                    'status_code': status_code[0],
+                    'body_length': length[0],
+                    'wall_seconds': finish - start,
+                })
 
     def get_client_ip(self):
         client_ip = self.client_address[0]
@@ -473,6 +475,7 @@
         env['SERVER_NAME'] = host
         env['SERVER_PORT'] = str(port)
         env['REMOTE_ADDR'] = self.client_address[0]
+        env['REMOTE_PORT'] = str(self.client_address[1])
         env['GATEWAY_INTERFACE'] = 'CGI/1.1'
 
         for h in self.headers.headers:
@@ -594,8 +597,8 @@
            minimum_chunk_size=None,
            log_x_forwarded_for=True,
            custom_pool=None,
-           keepalive=True,             
-           log_output=True,         
+           keepalive=True,
+           log_output=True,
            log_format=DEFAULT_LOG_FORMAT,
            url_length_limit=MAX_REQUEST_LINE,
            debug=True):
@@ -654,10 +657,13 @@
                 port = ''
 
         serv.log.write("(%s) wsgi starting up on %s://%s%s/\n" % (
-            os.getpid(), scheme, host, port))
+            serv.pid, scheme, host, port))
         while True:
             try:
                 client_socket = sock.accept()
+                if debug:
+                    serv.log.write("(%s) accepted %r\n" % (
+                        serv.pid, client_socket[1]))
                 try:
                     pool.spawn_n(serv.process_request, client_socket)
                 except AttributeError:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/eventlet-0.11.0/eventlet.egg-info/PKG-INFO 
new/eventlet-0.12.1/eventlet.egg-info/PKG-INFO
--- old/eventlet-0.11.0/eventlet.egg-info/PKG-INFO      2013-01-14 
01:13:35.000000000 +0100
+++ new/eventlet-0.12.1/eventlet.egg-info/PKG-INFO      2013-01-26 
02:04:33.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: eventlet
-Version: 0.11.0
+Version: 0.12.1
 Summary: Highly concurrent networking library
 Home-page: http://eventlet.net
 Author: Linden Lab
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/eventlet-0.11.0/setup.py new/eventlet-0.12.1/setup.py
--- old/eventlet-0.11.0/setup.py        2013-01-12 01:52:22.000000000 +0100
+++ new/eventlet-0.12.1/setup.py        2013-01-24 11:18:17.000000000 +0100
@@ -1,17 +1,8 @@
 #!/usr/bin/env python
-
-
 from setuptools import find_packages, setup
 from eventlet import __version__
 from os import path
-import sys
 
-requirements = []
-for flag, req in [('--without-greenlet','greenlet >= 0.3')]:
-    if flag in sys.argv:
-        sys.argv.remove(flag)
-    else:
-        requirements.append(req)
 
 setup(
     name='eventlet',
@@ -21,7 +12,9 @@
     author_email='[email protected]',
     url='http://eventlet.net',
     packages=find_packages(exclude=['tests', 'benchmarks']),
-    install_requires=requirements,
+    install_requires=(
+        'greenlet >= 0.3',
+    ),
     zip_safe=False,
     long_description=open(
         path.join(
@@ -29,21 +22,20 @@
             'README'
         )
     ).read(),
-    test_suite = 'nose.collector',
-    tests_require = 'httplib2',
+    test_suite='nose.collector',
     classifiers=[
-    "License :: OSI Approved :: MIT License",
-    "Programming Language :: Python",
-    "Operating System :: MacOS :: MacOS X",
-    "Operating System :: POSIX",
-    "Operating System :: Microsoft :: Windows",
-    "Programming Language :: Python :: 2.4",
-    "Programming Language :: Python :: 2.5",
-    "Programming Language :: Python :: 2.6",
-    "Programming Language :: Python :: 2.7",
-    "Topic :: Internet",
-    "Topic :: Software Development :: Libraries :: Python Modules",
-    "Intended Audience :: Developers",
-    "Development Status :: 4 - Beta"]
-    )
-
+        "License :: OSI Approved :: MIT License",
+        "Programming Language :: Python",
+        "Operating System :: MacOS :: MacOS X",
+        "Operating System :: POSIX",
+        "Operating System :: Microsoft :: Windows",
+        "Programming Language :: Python :: 2.4",
+        "Programming Language :: Python :: 2.5",
+        "Programming Language :: Python :: 2.6",
+        "Programming Language :: Python :: 2.7",
+        "Topic :: Internet",
+        "Topic :: Software Development :: Libraries :: Python Modules",
+        "Intended Audience :: Developers",
+        "Development Status :: 4 - Beta",
+    ]
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/eventlet-0.11.0/tests/greenio_test.py 
new/eventlet-0.12.1/tests/greenio_test.py
--- old/eventlet-0.11.0/tests/greenio_test.py   2013-01-12 03:10:06.000000000 
+0100
+++ new/eventlet-0.12.1/tests/greenio_test.py   2013-01-24 11:18:17.000000000 
+0100
@@ -4,12 +4,13 @@
 from eventlet.hubs import get_hub
 from eventlet.green import socket, time
 from eventlet.support import get_errno
-import errno
 
+import array
+import errno
 import eventlet
+import fcntl
 import os
 import sys
-import array
 import tempfile, shutil
 
 
@@ -528,6 +529,58 @@
         port = eventlet.listen(('127.0.0.1', 0)).getsockname()[1]
         self.assertRaises(socket.error, eventlet.connect, ('127.0.0.1', port))
 
+    def test_zero_timeout_and_back(self):
+        listen = eventlet.listen(('', 0))
+        # Keep reference to server side of socket
+        server = eventlet.spawn(listen.accept)
+        client = eventlet.connect(listen.getsockname())
+
+        client.settimeout(0.05)
+        # Now must raise socket.timeout
+        self.assertRaises(socket.timeout, client.recv, 1)
+
+        client.settimeout(0)
+        # Now must raise socket.error with EAGAIN
+        try:
+            client.recv(1)
+            assert False
+        except socket.error, e:
+            assert get_errno(e) == errno.EAGAIN
+
+        client.settimeout(0.05)
+        # Now socket.timeout again
+        self.assertRaises(socket.timeout, client.recv, 1)
+        server.wait()
+
+    def test_default_nonblocking(self):
+        sock1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        flags = fcntl.fcntl(sock1.fd.fileno(), fcntl.F_GETFL)
+        assert flags & os.O_NONBLOCK
+
+        sock2 = socket.socket(sock1.fd)
+        flags = fcntl.fcntl(sock2.fd.fileno(), fcntl.F_GETFL)
+        assert flags & os.O_NONBLOCK
+
+    def test_dup_nonblocking(self):
+        sock1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        flags = fcntl.fcntl(sock1.fd.fileno(), fcntl.F_GETFL)
+        assert flags & os.O_NONBLOCK
+
+        sock2 = sock1.dup()
+        flags = fcntl.fcntl(sock2.fd.fileno(), fcntl.F_GETFL)
+        assert flags & os.O_NONBLOCK
+
+    def test_skip_nonblocking(self):
+        sock1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        fd = sock1.fd.fileno()
+        flags = fcntl.fcntl(fd, fcntl.F_GETFL)
+        flags = fcntl.fcntl(fd, fcntl.F_SETFL, flags & ~os.O_NONBLOCK)
+        assert flags & os.O_NONBLOCK == 0
+
+        sock2 = socket.socket(sock1.fd, set_nonblocking=False)
+        flags = fcntl.fcntl(sock2.fd.fileno(), fcntl.F_GETFL)
+        assert flags & os.O_NONBLOCK == 0
+
 
 class TestGreenPipe(LimitedTestCase):
     @skip_on_windows
@@ -798,5 +851,16 @@
         assert maxstartdiff * 2 < runlengths[0], "Largest difference in 
starting times more than twice the shortest running time!"
         assert runlengths[0] * 2 > runlengths[-1], "Longest runtime more than 
twice as long as shortest!"
 
+
+def test_set_nonblocking():
+    sock = _orig_sock.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    fileno = sock.fileno()
+    orig_flags = fcntl.fcntl(fileno, fcntl.F_GETFL)
+    assert orig_flags & os.O_NONBLOCK == 0
+    greenio.set_nonblocking(sock)
+    new_flags = fcntl.fcntl(fileno, fcntl.F_GETFL)
+    assert new_flags == (orig_flags | os.O_NONBLOCK)
+
+
 if __name__ == '__main__':
     main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/eventlet-0.11.0/tests/zmq_test.py 
new/eventlet-0.12.1/tests/zmq_test.py
--- old/eventlet-0.11.0/tests/zmq_test.py       2013-01-13 22:59:04.000000000 
+0100
+++ new/eventlet-0.12.1/tests/zmq_test.py       2013-01-23 10:34:03.000000000 
+0100
@@ -3,7 +3,7 @@
 from eventlet import event, spawn, sleep, patcher, semaphore
 from eventlet.hubs import get_hub, _threadlocal, use_hub
 from nose.tools import *
-from tests import mock, LimitedTestCase, using_pyevent, skip_unless
+from tests import check_idle_cpu_usage, mock, LimitedTestCase, using_pyevent, 
skip_unless
 from unittest import TestCase
 
 from threading import Thread
@@ -348,7 +348,13 @@
         num_recvs = 30
         done = event.Event()
 
-        sender.setsockopt(zmq.HWM, 10)
+        try:
+            SNDHWM = zmq.SNDHWM
+        except AttributeError:
+            # ZeroMQ <3.0
+            SNDHWM = zmq.HWM
+
+        sender.setsockopt(SNDHWM, 10)
         sender.setsockopt(zmq.SNDBUF, 10)
 
         receiver.setsockopt(zmq.RCVBUF, 10)
@@ -403,6 +409,44 @@
         events = sock2.getsockopt(zmq.EVENTS)
         self.assertEqual(events & zmq.POLLIN, zmq.POLLIN)
 
+    @skip_unless(zmq_supported)
+    def test_cpu_usage_after_bind(self):
+        """zmq eats CPU after PUB socket .bind()
+
+        https://bitbucket.org/which_linden/eventlet/issue/128
+
+        According to the ZeroMQ documentation, the socket file descriptor
+        can be readable without any pending messages. So we need to ensure
+        that Eventlet wraps around ZeroMQ sockets do not create busy loops.
+
+        A naive way to test it is to measure resource usage. This will require
+        some tuning to set appropriate acceptable limits.
+        """
+        sock = self.context.socket(zmq.PUB)
+        self.sockets.append(sock)
+        sock.bind_to_random_port("tcp://127.0.0.1")
+        sleep()
+        check_idle_cpu_usage(0.2, 0.1)
+
+    @skip_unless(zmq_supported)
+    def test_cpu_usage_after_pub_send_or_dealer_recv(self):
+        """zmq eats CPU after PUB send or DEALER recv.
+
+        Same https://bitbucket.org/which_linden/eventlet/issue/128
+        """
+        pub, sub, _port = self.create_bound_pair(zmq.PUB, zmq.SUB)
+        sub.setsockopt(zmq.SUBSCRIBE, "")
+        sleep()
+        pub.send('test_send')
+        check_idle_cpu_usage(0.2, 0.1)
+
+        sender, receiver, _port = self.create_bound_pair(zmq.DEALER, 
zmq.DEALER)
+        sleep()
+        sender.send('test_recv')
+        msg = receiver.recv()
+        self.assertEqual(msg, 'test_recv')
+        check_idle_cpu_usage(0.2, 0.1)
+
 
 class TestQueueLock(LimitedTestCase):
     @skip_unless(zmq_supported)

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to