Merge
This commit is contained in:
@@ -1,24 +1,21 @@
|
||||
"""\
|
||||
@file __init__.py
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
version_info = (0, 8, 10)
|
||||
version_info = (0, 8, 11)
|
||||
__version__ = '%s.%s.%s' % version_info
|
||||
|
@@ -1,27 +1,24 @@
|
||||
"""\
|
||||
@file api.py
|
||||
@author Bob Ippolito
|
||||
|
||||
Copyright (c) 2005-2006, Bob Ippolito
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# @author Bob Ippolito
|
||||
#
|
||||
# Copyright (c) 2005-2006, Bob Ippolito
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import sys
|
||||
import socket
|
||||
|
@@ -1,29 +1,26 @@
|
||||
"""\
|
||||
@file backdoor.py
|
||||
@author Bob Ippolito
|
||||
|
||||
Copyright (c) 2005-2006, Bob Ippolito
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Copyright (c) 2008, Donovan Preston
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# @author Bob Ippolito
|
||||
#
|
||||
# Copyright (c) 2005-2006, Bob Ippolito
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Copyright (c) 2008, Donovan Preston
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import socket
|
||||
import sys
|
||||
|
@@ -12,4 +12,5 @@ class channel(coros.queue):
|
||||
def balance(self):
|
||||
return self.sem.balance
|
||||
|
||||
|
||||
import warnings
|
||||
warnings.warn("channel is deprecated; use coros.queue(0) which behaves the same", DeprecationWarning, stacklevel=2)
|
||||
|
@@ -1,26 +1,23 @@
|
||||
"""\
|
||||
@file coros.py
|
||||
@author Donovan Preston
|
||||
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# @author Donovan Preston
|
||||
#
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import collections
|
||||
import time
|
||||
@@ -196,13 +193,11 @@ class event(object):
|
||||
>>> api.sleep(0)
|
||||
received stuff
|
||||
"""
|
||||
# why is waiter not used?
|
||||
if waiter in self._waiters:
|
||||
del self._waiters[waiter]
|
||||
# XXX This does not check that waiter still waits when throw actually happens
|
||||
# XXX and therefore is broken (see how send() deals with this)
|
||||
api.get_hub().schedule_call(
|
||||
0, waiter.throw, Cancelled())
|
||||
api.get_hub().schedule_call(0, waiter.throw, Cancelled())
|
||||
|
||||
def send(self, result=None, exc=None):
|
||||
"""Makes arrangements for the waiters to be woken with the
|
||||
@@ -458,29 +453,8 @@ def execute(func, *args, **kw):
|
||||
|
||||
|
||||
def CoroutinePool(*args, **kwargs):
|
||||
from eventlet.pools import CoroutinePool
|
||||
return CoroutinePool(*args, **kwargs)
|
||||
|
||||
|
||||
class pipe(object):
|
||||
""" Implementation of pipe using events. Not tested! Not used, either."""
|
||||
def __init__(self):
|
||||
self._event = event()
|
||||
self._buffer = ''
|
||||
|
||||
def send(self, txt):
|
||||
self._buffer += txt
|
||||
evt, self._event = self._event, event()
|
||||
evt.send()
|
||||
|
||||
def recv(self, num=16384):
|
||||
if not self._buffer:
|
||||
self._event.wait()
|
||||
if num >= len(self._buffer):
|
||||
buf, self._buffer = self._buffer, ''
|
||||
else:
|
||||
buf, self._buffer = self._buffer[:num], self._buffer[num:]
|
||||
return buf
|
||||
from eventlet.pool import Pool
|
||||
return Pool(*args, **kwargs)
|
||||
|
||||
|
||||
class queue(object):
|
||||
|
@@ -1,28 +1,26 @@
|
||||
"""\
|
||||
@file db_pool.py
|
||||
@brief A pool of nonblocking database connections.
|
||||
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
# @brief A pool of nonblocking database connections.
|
||||
#
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
"""
|
||||
The db_pool module is useful for managing database connections. It provides three primary benefits: cooperative yielding during database operations, concurrency limiting to a database host, and connection reuse. db_pool is intended to be db-agnostic, compatible with any DB-API 2.0 database module; however it has currently only been tested and used with MySQLdb.
|
||||
|
||||
== ConnectionPool ==
|
||||
@@ -79,11 +77,11 @@ The constructor arguments:
|
||||
>>> dc = DatabaseConnector(MySQLdb,
|
||||
{'db.internal.example.com':
|
||||
{'user':'internal', 'passwd':'s33kr1t'},
|
||||
'localhost':
|
||||
'localhost':
|
||||
{'user':'root', 'passwd':''})
|
||||
|
||||
|
||||
If the credentials contain a host named 'default', then the value for 'default' is used whenever trying to connect to a host that has no explicit entry in the database. This is useful if there is some pool of hosts that share arguments.
|
||||
|
||||
|
||||
* conn_pool : The connection pool class to use. Defaults to db_pool.ConnectionPool.
|
||||
|
||||
The rest of the arguments to the DatabaseConnector constructor are passed on to the ConnectionPool.
|
||||
@@ -92,7 +90,6 @@ NOTE: The DatabaseConnector is a bit unfinished, it only suits a subset of use c
|
||||
"""
|
||||
|
||||
from collections import deque
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
@@ -106,28 +103,28 @@ class ConnectTimeout(Exception):
|
||||
|
||||
|
||||
class BaseConnectionPool(Pool):
|
||||
def __init__(self, db_module,
|
||||
min_size = 0, max_size = 4,
|
||||
def __init__(self, db_module,
|
||||
min_size = 0, max_size = 4,
|
||||
max_idle = 10, max_age = 30,
|
||||
connect_timeout = 5,
|
||||
*args, **kwargs):
|
||||
"""
|
||||
Constructs a pool with at least *min_size* connections and at most
|
||||
*max_size* connections. Uses *db_module* to construct new connections.
|
||||
|
||||
|
||||
The *max_idle* parameter determines how long pooled connections can
|
||||
remain idle, in seconds. After *max_idle* seconds have elapsed
|
||||
without the connection being used, the pool closes the connection.
|
||||
|
||||
remain idle, in seconds. After *max_idle* seconds have elapsed
|
||||
without the connection being used, the pool closes the connection.
|
||||
|
||||
*max_age* is how long any particular connection is allowed to live.
|
||||
Connections that have been open for longer than *max_age* seconds are
|
||||
closed, regardless of idle time. If *max_age* is 0, all connections are
|
||||
closed, regardless of idle time. If *max_age* is 0, all connections are
|
||||
closed on return to the pool, reducing it to a concurrency limiter.
|
||||
|
||||
*connect_timeout* is the duration in seconds that the pool will wait
|
||||
|
||||
*connect_timeout* is the duration in seconds that the pool will wait
|
||||
before timing out on connect() to the database. If triggered, the
|
||||
timeout will raise a ConnectTimeout from get().
|
||||
|
||||
|
||||
The remainder of the arguments are used as parameters to the
|
||||
*db_module*'s connection constructor.
|
||||
"""
|
||||
@@ -139,33 +136,33 @@ class BaseConnectionPool(Pool):
|
||||
self.max_age = max_age
|
||||
self.connect_timeout = connect_timeout
|
||||
self._expiration_timer = None
|
||||
super(BaseConnectionPool, self).__init__(min_size=min_size,
|
||||
super(BaseConnectionPool, self).__init__(min_size=min_size,
|
||||
max_size=max_size,
|
||||
order_as_stack=True)
|
||||
|
||||
|
||||
def _schedule_expiration(self):
|
||||
""" Sets up a timer that will call _expire_old_connections when the
|
||||
""" Sets up a timer that will call _expire_old_connections when the
|
||||
oldest connection currently in the free pool is ready to expire. This
|
||||
is the earliest possible time that a connection could expire, thus, the
|
||||
timer will be running as infrequently as possible without missing a
|
||||
timer will be running as infrequently as possible without missing a
|
||||
possible expiration.
|
||||
|
||||
If this function is called when a timer is already scheduled, it does
|
||||
|
||||
If this function is called when a timer is already scheduled, it does
|
||||
nothing.
|
||||
|
||||
|
||||
If max_age or max_idle is 0, _schedule_expiration likewise does nothing.
|
||||
"""
|
||||
if self.max_age is 0 or self.max_idle is 0:
|
||||
# expiration is unnecessary because all connections will be expired
|
||||
# on put
|
||||
return
|
||||
|
||||
if ( self._expiration_timer is not None
|
||||
|
||||
if ( self._expiration_timer is not None
|
||||
and not getattr(self._expiration_timer, 'called', False)
|
||||
and not getattr(self._expiration_timer, 'cancelled', False) ):
|
||||
# the next timer is already scheduled
|
||||
return
|
||||
|
||||
return
|
||||
|
||||
try:
|
||||
now = time.time()
|
||||
self._expire_old_connections(now)
|
||||
@@ -174,23 +171,23 @@ class BaseConnectionPool(Pool):
|
||||
idle_delay = (self.free_items[-1][0] - now) + self.max_idle
|
||||
oldest = min([t[1] for t in self.free_items])
|
||||
age_delay = (oldest - now) + self.max_age
|
||||
|
||||
|
||||
next_delay = min(idle_delay, age_delay)
|
||||
except IndexError, ValueError:
|
||||
# no free items, unschedule ourselves
|
||||
self._expiration_timer = None
|
||||
return
|
||||
|
||||
|
||||
if next_delay > 0:
|
||||
# set up a continuous self-calling loop
|
||||
self._expiration_timer = api.call_after(next_delay,
|
||||
self._schedule_expiration)
|
||||
|
||||
|
||||
def _expire_old_connections(self, now):
|
||||
""" Iterates through the open connections contained in the pool, closing
|
||||
ones that have remained idle for longer than max_idle seconds, or have
|
||||
been in existence for longer than max_age seconds.
|
||||
|
||||
|
||||
*now* is the current time, as returned by time.time().
|
||||
"""
|
||||
original_count = len(self.free_items)
|
||||
@@ -207,8 +204,8 @@ class BaseConnectionPool(Pool):
|
||||
if not self._is_expired(now, last_used, created_at)]
|
||||
self.free_items.clear()
|
||||
self.free_items.extend(new_free)
|
||||
|
||||
# adjust the current size counter to account for expired
|
||||
|
||||
# adjust the current size counter to account for expired
|
||||
# connections
|
||||
self.current_size -= original_count - len(self.free_items)
|
||||
|
||||
@@ -220,7 +217,7 @@ class BaseConnectionPool(Pool):
|
||||
or now - created_at > self.max_age ):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _unwrap_connection(self, conn):
|
||||
""" If the connection was wrapped by a subclass of
|
||||
BaseConnectionWrapper and is still functional (as determined
|
||||
@@ -253,7 +250,7 @@ class BaseConnectionPool(Pool):
|
||||
|
||||
def get(self):
|
||||
conn = super(BaseConnectionPool, self).get()
|
||||
|
||||
|
||||
# None is a flag value that means that put got called with
|
||||
# something it couldn't use
|
||||
if conn is None:
|
||||
@@ -273,7 +270,7 @@ class BaseConnectionPool(Pool):
|
||||
_last_used, created_at, conn = conn
|
||||
else:
|
||||
created_at = time.time()
|
||||
|
||||
|
||||
# wrap the connection so the consumer can call close() safely
|
||||
wrapped = PooledConnectionWrapper(conn, self)
|
||||
# annotating the wrapper so that when it gets put in the pool
|
||||
@@ -285,7 +282,7 @@ class BaseConnectionPool(Pool):
|
||||
created_at = getattr(conn, '_db_pool_created_at', 0)
|
||||
now = time.time()
|
||||
conn = self._unwrap_connection(conn)
|
||||
|
||||
|
||||
if self._is_expired(now, now, created_at):
|
||||
self._safe_close(conn, quiet=False)
|
||||
conn = None
|
||||
@@ -317,7 +314,7 @@ class BaseConnectionPool(Pool):
|
||||
self._schedule_expiration()
|
||||
|
||||
def clear(self):
|
||||
""" Close all connections that this pool still holds a reference to,
|
||||
""" Close all connections that this pool still holds a reference to,
|
||||
and removes all references to them.
|
||||
"""
|
||||
if self._expiration_timer:
|
||||
@@ -325,10 +322,10 @@ class BaseConnectionPool(Pool):
|
||||
free_items, self.free_items = self.free_items, deque()
|
||||
for _last_used, _created_at, conn in free_items:
|
||||
self._safe_close(conn, quiet=True)
|
||||
|
||||
|
||||
def __del__(self):
|
||||
self.clear()
|
||||
|
||||
|
||||
|
||||
class SaranwrappedConnectionPool(BaseConnectionPool):
|
||||
"""A pool which gives out saranwrapped database connections.
|
||||
@@ -346,9 +343,9 @@ class SaranwrappedConnectionPool(BaseConnectionPool):
|
||||
return saranwrap.wrap(db_module).connect(*args, **kw)
|
||||
finally:
|
||||
timeout.cancel()
|
||||
|
||||
|
||||
connect = classmethod(connect)
|
||||
|
||||
|
||||
|
||||
class TpooledConnectionPool(BaseConnectionPool):
|
||||
"""A pool which gives out tpool.Proxy-based database connections.
|
||||
@@ -422,16 +419,12 @@ class GenericConnectionWrapper(object):
|
||||
def set_sql_mode(self, sql_mode): return self._base.set_sql_mode(sql_mode)
|
||||
def show_warnings(self): return self._base.show_warnings()
|
||||
def warning_count(self): return self._base.warning_count()
|
||||
def literal(self, o): return self._base.literal(o)
|
||||
def ping(self,*args, **kwargs): return self._base.ping(*args, **kwargs)
|
||||
def query(self,*args, **kwargs): return self._base.query(*args, **kwargs)
|
||||
def rollback(self,*args, **kwargs): return self._base.rollback(*args, **kwargs)
|
||||
def select_db(self,*args, **kwargs): return self._base.select_db(*args, **kwargs)
|
||||
def set_server_option(self,*args, **kwargs): return self._base.set_server_option(*args, **kwargs)
|
||||
def set_character_set(self, charset): return self._base.set_character_set(charset)
|
||||
def set_sql_mode(self, sql_mode): return self._base.set_sql_mode(sql_mode)
|
||||
def server_capabilities(self,*args, **kwargs): return self._base.server_capabilities(*args, **kwargs)
|
||||
def show_warnings(self): return self._base.show_warnings()
|
||||
def shutdown(self,*args, **kwargs): return self._base.shutdown(*args, **kwargs)
|
||||
def sqlstate(self,*args, **kwargs): return self._base.sqlstate(*args, **kwargs)
|
||||
def stat(self,*args, **kwargs): return self._base.stat(*args, **kwargs)
|
||||
@@ -439,7 +432,6 @@ class GenericConnectionWrapper(object):
|
||||
def string_literal(self,*args, **kwargs): return self._base.string_literal(*args, **kwargs)
|
||||
def thread_id(self,*args, **kwargs): return self._base.thread_id(*args, **kwargs)
|
||||
def use_result(self,*args, **kwargs): return self._base.use_result(*args, **kwargs)
|
||||
def warning_count(self): return self._base.warning_count()
|
||||
|
||||
|
||||
class PooledConnectionWrapper(GenericConnectionWrapper):
|
||||
@@ -470,7 +462,7 @@ class PooledConnectionWrapper(GenericConnectionWrapper):
|
||||
if self and self._pool:
|
||||
self._pool.put(self)
|
||||
self._destroy()
|
||||
|
||||
|
||||
def __del__(self):
|
||||
self.close()
|
||||
|
||||
@@ -479,7 +471,7 @@ class DatabaseConnector(object):
|
||||
"""\
|
||||
@brief This is an object which will maintain a collection of database
|
||||
connection pools on a per-host basis."""
|
||||
def __init__(self, module, credentials,
|
||||
def __init__(self, module, credentials,
|
||||
conn_pool=None, *args, **kwargs):
|
||||
"""\
|
||||
@brief constructor
|
||||
|
@@ -1,28 +1,26 @@
|
||||
"""\
|
||||
@file exc.py
|
||||
@brief Takes an exception object and returns a dictionary suitable for use debugging the exception later.
|
||||
# Copyright (c) 2005-2009, Donovan Preston
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
Copyright (c) 2005-2009, Donovan Preston
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
Takes an exception object and returns a dictionary suitable for use debugging the exception later.
|
||||
"""
|
||||
|
||||
import linecache
|
||||
import re
|
||||
@@ -39,7 +37,7 @@ def format_exc(exc=None):
|
||||
frames = []
|
||||
while exc_tb is not None:
|
||||
f = exc_tb.tb_frame
|
||||
|
||||
|
||||
frames.append((
|
||||
f.f_code.co_name,
|
||||
f.f_code.co_filename,
|
||||
|
@@ -1,26 +1,22 @@
|
||||
"""\
|
||||
@file greenio.py
|
||||
|
||||
Copyright (c) 2005-2006, Bob Ippolito
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# Copyright (c) 2005-2006, Bob Ippolito
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
from eventlet.api import trampoline, get_hub
|
||||
from eventlet import util
|
||||
@@ -293,7 +289,9 @@ class GreenSocket(object):
|
||||
def dup(self, *args, **kw):
|
||||
sock = self.fd.dup(*args, **kw)
|
||||
set_nonblocking(sock)
|
||||
return type(self)(sock)
|
||||
newsock = type(self)(sock)
|
||||
newsock.settimeout(self.timeout)
|
||||
return newsock
|
||||
|
||||
def fileno(self, *args, **kw):
|
||||
fn = self.fileno = self.fd.fileno
|
||||
@@ -352,7 +350,6 @@ class GreenSocket(object):
|
||||
return self.fd.sendto(*args)
|
||||
|
||||
def setblocking(self, flag):
|
||||
self.fd.setblocking(flag)
|
||||
if flag:
|
||||
self.act_non_blocking = False
|
||||
self.timeout = None
|
||||
|
@@ -1,7 +1,4 @@
|
||||
"""\
|
||||
@file greenlib.py
|
||||
@author Bob Ippolito
|
||||
|
||||
Copyright (c) 2005-2006, Bob Ippolito
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
@@ -22,11 +19,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
from eventlet.api import Greenlet
|
||||
|
||||
class SwitchingToDeadGreenlet(Exception):
|
||||
pass
|
||||
|
||||
def switch(other=None, value=None, exc=None):
|
||||
"""
|
||||
Switch to another greenlet, passing value or exception
|
||||
"""
|
||||
self = greenlet.getcurrent()
|
||||
self = Greenlet.getcurrent()
|
||||
if other is None:
|
||||
other = self.parent
|
||||
if other is None:
|
||||
@@ -37,3 +36,6 @@ def switch(other=None, value=None, exc=None):
|
||||
return other.throw(exc)
|
||||
else:
|
||||
return other.switch(value)
|
||||
|
||||
import warnings
|
||||
warnings.warn("greenlib is deprecated; use greenlet methods directly", DeprecationWarning, stacklevel=2)
|
||||
|
@@ -1,30 +1,26 @@
|
||||
"""\
|
||||
@file httpc.py
|
||||
@author Donovan Preston
|
||||
|
||||
Copyright (c) 2005-2006, Donovan Preston
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# @author Donovan Preston
|
||||
#
|
||||
# Copyright (c) 2005-2006, Donovan Preston
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import copy
|
||||
import datetime
|
||||
from eventlet.green import httplib
|
||||
import os.path
|
||||
import os
|
||||
|
@@ -1,27 +1,24 @@
|
||||
"""\
|
||||
@file httpd.py
|
||||
@author Donovan Preston
|
||||
|
||||
Copyright (c) 2005-2006, Donovan Preston
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# @author Donovan Preston
|
||||
#
|
||||
# Copyright (c) 2005-2006, Donovan Preston
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import cgi
|
||||
import errno
|
||||
@@ -29,7 +26,6 @@ import socket
|
||||
import sys
|
||||
import time
|
||||
import urllib
|
||||
import socket
|
||||
import traceback
|
||||
import BaseHTTPServer
|
||||
|
||||
|
@@ -1,39 +1,3 @@
|
||||
"""\
|
||||
@file httpdate.py
|
||||
@author Donovan Preston
|
||||
|
||||
Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
import time
|
||||
|
||||
__all__ = ['format_date_time']
|
||||
|
||||
# Weekday and month names for HTTP date/time formatting; always English!
|
||||
_weekdayname = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
|
||||
_monthname = [None, # Dummy so we can use 1-based month numbers
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
|
||||
|
||||
def format_date_time(timestamp):
|
||||
year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp)
|
||||
return "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
|
||||
_weekdayname[wd], day, _monthname[month], year, hh, mm, ss
|
||||
)
|
||||
from wsgi import format_date_time
|
||||
import warnings
|
||||
warnings.warn("httpdate module is deprecated; its contents is moved to wsgi.py", DeprecationWarning, stacklevel=2)
|
||||
|
@@ -1,25 +1,21 @@
|
||||
"""\
|
||||
@file hub.py
|
||||
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import bisect
|
||||
import sys
|
||||
|
@@ -1,38 +1,28 @@
|
||||
"""\
|
||||
@file libev.py
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
import bisect
|
||||
import signal
|
||||
import sys
|
||||
import socket
|
||||
import errno
|
||||
import traceback
|
||||
import time
|
||||
|
||||
from eventlet.hubs import hub
|
||||
|
||||
from eventlet.support import greenlets as greenlet
|
||||
|
||||
# XXX for debugging only
|
||||
#raise ImportError()
|
||||
|
||||
@@ -81,7 +71,7 @@ class Hub(hub.BaseHub):
|
||||
|
||||
def signal_received(self, signal):
|
||||
# can't do more than set this flag here because the pyevent callback
|
||||
# mechanism swallows exceptions raised here, so we have to raise in
|
||||
# mechanism swallows exceptions raised here, so we have to raise in
|
||||
# the 'main' greenlet (in wait()) to kill the program
|
||||
self.interrupted = True
|
||||
self._evloop.unloop()
|
||||
@@ -107,7 +97,7 @@ class Hub(hub.BaseHub):
|
||||
# raise any signals that deserve raising
|
||||
if self.interrupted:
|
||||
self.interrupted = False
|
||||
raise KeyboardInterrupt()
|
||||
raise KeyboardInterrupt()
|
||||
|
||||
def add_timer(self, timer):
|
||||
# store the pyevent timer object so that we can cancel later
|
||||
|
@@ -1,38 +1,28 @@
|
||||
"""\
|
||||
@file libevent.py
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
import bisect
|
||||
import signal
|
||||
import sys
|
||||
import socket
|
||||
import errno
|
||||
import traceback
|
||||
import time
|
||||
|
||||
from eventlet.timer import Timer
|
||||
from eventlet.hubs import hub
|
||||
|
||||
from eventlet.support import greenlets as greenlet
|
||||
|
||||
# XXX for debugging only
|
||||
#raise ImportError()
|
||||
|
@@ -1,168 +0,0 @@
|
||||
"""\
|
||||
@file nginx.py
|
||||
@author Donovan Preston
|
||||
|
||||
Copyright (c) 2008, Linden Research, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
from os.path import abspath, dirname
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
sys.stdout = sys.stderr
|
||||
mydir = dirname(dirname(dirname(abspath(__file__))))
|
||||
if mydir not in sys.path:
|
||||
sys.path.append(mydir)
|
||||
|
||||
|
||||
from eventlet import api
|
||||
from eventlet import httpc
|
||||
from eventlet.hubs import hub
|
||||
|
||||
|
||||
def hello_world(env, start_response):
|
||||
result = httpc.get('http://www.google.com/')
|
||||
start_response('200 OK', [('Content-type', 'text/plain')])
|
||||
return [result]
|
||||
|
||||
|
||||
def wrap_application(master, env, start_response):
|
||||
try:
|
||||
real_application = api.named(env['eventlet_nginx_wsgi_app'])
|
||||
except:
|
||||
real_application = hello_world
|
||||
result = real_application(env, start_response)
|
||||
master.switch((result, None))
|
||||
return None, None
|
||||
|
||||
|
||||
class StartResponse(object):
|
||||
def __call__(self, *args):
|
||||
self.args = args
|
||||
|
||||
|
||||
pythonpath_already_set = False
|
||||
|
||||
|
||||
|
||||
|
||||
WSGI_POLLIN = 0x01
|
||||
WSGI_POLLOUT = 0x04
|
||||
|
||||
import traceback
|
||||
class Hub(hub.BaseHub):
|
||||
def __init__(self, *args, **kw):
|
||||
hub.BaseHub.__init__(self, *args, **kw)
|
||||
self._connection_wrappers = {}
|
||||
|
||||
def add_descriptor(self, fileno, read=None, write=None, exc=None):
|
||||
print "ADD DESCRIPTOR", fileno, read, write, exc
|
||||
traceback.print_stack()
|
||||
|
||||
result = super(Hub, self).add_descriptor(fileno, read, write, exc)
|
||||
flag = 0
|
||||
if read:
|
||||
flag |= WSGI_POLLIN
|
||||
if write:
|
||||
flag |= WSGI_POLLOUT
|
||||
conn = self.connection_wrapper(fileno)
|
||||
self._connection_wrappers[fileno] = conn
|
||||
print "POLL REGISTER", flag
|
||||
self.poll_register(conn, flag)
|
||||
return result
|
||||
|
||||
def remove_descriptor(self, fileno):
|
||||
super(Hub, self).remove_descriptor(fileno)
|
||||
|
||||
try:
|
||||
self.poll_unregister(self._connection_wrappers[fileno])
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
def wait(self, seconds=0):
|
||||
to_call = getattr(self, 'to_call', None)
|
||||
print "WAIT", self, to_call
|
||||
if to_call:
|
||||
print "CALL TOCALL"
|
||||
result = to_call[0](to_call[1])
|
||||
del self.to_call
|
||||
return result
|
||||
self.current_application.switch(self.poll(int(seconds*1000)))
|
||||
|
||||
def application(self, env, start_response):
|
||||
print "ENV",env
|
||||
self.poll_register = env['ngx.poll_register']
|
||||
self.poll_unregister = env['ngx.poll_unregister']
|
||||
self.poll = env['ngx.poll']
|
||||
self.connection_wrapper = env['ngx.connection_wrapper']
|
||||
self.current_application = api.getcurrent()
|
||||
|
||||
slave = api.greenlet.greenlet(wrap_application)
|
||||
response = StartResponse()
|
||||
result = slave.switch(
|
||||
api.getcurrent(), env, response)
|
||||
|
||||
while True:
|
||||
self.current_application = api.getcurrent()
|
||||
print "RESULT", result, callable(result[0])
|
||||
if result and callable(result[0]):
|
||||
print "YIELDING!"
|
||||
yield ''
|
||||
print "AFTER YIELD!"
|
||||
conn, flags = result[0]()
|
||||
fileno = conn.fileno()
|
||||
if flags & WSGI_POLLIN:
|
||||
self.readers[fileno](fileno)
|
||||
elif flags & WSGI_POLLOUT:
|
||||
self.writers[fileno](fileno)
|
||||
print "POLL STATE", conn, flags, dir(conn)
|
||||
else:
|
||||
start_response(*response.args)
|
||||
if isinstance(result, tuple):
|
||||
for x in result[0]:
|
||||
yield x
|
||||
else:
|
||||
for x in result:
|
||||
yield x
|
||||
return
|
||||
result = self.switch()
|
||||
#if not isinstance(result, tuple):
|
||||
# result = (result, None) ## TODO Fix greenlib's return values
|
||||
|
||||
|
||||
def application(env, start_response):
|
||||
hub = api.get_hub()
|
||||
|
||||
if not isinstance(hub, Hub):
|
||||
api.use_hub(sys.modules[Hub.__module__])
|
||||
hub = api.get_hub()
|
||||
|
||||
global pythonpath_already_set
|
||||
if not pythonpath_already_set:
|
||||
pythonpath = env.get('eventlet_python_path', '').split(':')
|
||||
for seg in pythonpath:
|
||||
if seg not in sys.path:
|
||||
sys.path.append(seg)
|
||||
|
||||
return hub.application(env, start_response)
|
||||
|
@@ -1,33 +1,28 @@
|
||||
"""\
|
||||
@file poll.py
|
||||
@author Bob Ippolito
|
||||
|
||||
Copyright (c) 2005-2006, Bob Ippolito
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# @author Bob Ippolito
|
||||
#
|
||||
# Copyright (c) 2005-2006, Bob Ippolito
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import sys
|
||||
import select
|
||||
import socket
|
||||
import errno
|
||||
import traceback
|
||||
from time import sleep
|
||||
import time
|
||||
|
||||
@@ -60,7 +55,7 @@ class Hub(hub.BaseHub):
|
||||
mask |= WRITE_MASK
|
||||
return mask
|
||||
|
||||
|
||||
|
||||
def remove_descriptor(self, fileno):
|
||||
super(Hub, self).remove_descriptor(fileno)
|
||||
try:
|
||||
|
@@ -1,26 +1,22 @@
|
||||
"""\
|
||||
@file select.py
|
||||
|
||||
Copyright (c) 2005-2006, Bob Ippolito
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# Copyright (c) 2005-2006, Bob Ippolito
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import sys
|
||||
import select
|
||||
@@ -29,7 +25,6 @@ import time
|
||||
|
||||
from eventlet.hubs import hub
|
||||
|
||||
from eventlet.support import greenlets as greenlet
|
||||
|
||||
class Hub(hub.BaseHub):
|
||||
def wait(self, seconds=None):
|
||||
|
@@ -1,26 +1,23 @@
|
||||
"""\
|
||||
@file jsonhttp.py
|
||||
@author Donovan Preston
|
||||
|
||||
Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# @author Donovan Preston
|
||||
#
|
||||
# Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
from eventlet import httpc
|
||||
|
||||
|
@@ -1,26 +1,23 @@
|
||||
"""\
|
||||
@file logutil.py
|
||||
@author Donovan Preston
|
||||
|
||||
Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# @author Donovan Preston
|
||||
#
|
||||
# Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import syslog
|
||||
import logging
|
||||
|
@@ -1,27 +1,24 @@
|
||||
"""\
|
||||
@file channel.py
|
||||
@author Bob Ippolito
|
||||
|
||||
Copyright (c) 2005-2006, Bob Ippolito
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# @author Bob Ippolito
|
||||
#
|
||||
# Copyright (c) 2005-2006, Bob Ippolito
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import collections
|
||||
|
||||
@@ -100,3 +97,6 @@ class channel(object):
|
||||
|
||||
def send_exception(self, exc):
|
||||
return self._send_tasklet(None, exc)
|
||||
|
||||
import warnings
|
||||
warnings.warn("channel is deprecated; use coros.queue(0) which behaves the same", DeprecationWarning, stacklevel=2)
|
||||
|
@@ -15,6 +15,10 @@ class Pool(object):
|
||||
else:
|
||||
self.results = None
|
||||
|
||||
@property
|
||||
def current_size(self):
|
||||
return len(self.procs)
|
||||
|
||||
def free(self):
|
||||
return self.sem.counter
|
||||
|
||||
@@ -50,7 +54,7 @@ class Pool(object):
|
||||
execute_async = execute
|
||||
|
||||
def _execute(self, evt, func, args, kw):
|
||||
p = self.execute(func, args, kw)
|
||||
p = self.execute(func, *args, **kw)
|
||||
p.link(evt)
|
||||
return p
|
||||
|
||||
|
@@ -1,32 +1,27 @@
|
||||
"""\
|
||||
@file pools.py
|
||||
@author Donovan Preston, Aaron Brashears
|
||||
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# @author Donovan Preston, Aaron Brashears
|
||||
#
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import collections
|
||||
import traceback
|
||||
|
||||
from eventlet import api
|
||||
from eventlet import channel
|
||||
from eventlet import coros
|
||||
|
||||
class FanFailed(RuntimeError):
|
||||
@@ -76,7 +71,7 @@ class Pool(object):
|
||||
self.max_size = max_size
|
||||
self.order_as_stack = order_as_stack
|
||||
self.current_size = 0
|
||||
self.channel = channel.channel()
|
||||
self.channel = coros.queue(0)
|
||||
self.free_items = collections.deque()
|
||||
for x in xrange(min_size):
|
||||
self.current_size += 1
|
||||
@@ -91,7 +86,7 @@ class Pool(object):
|
||||
created = self.create()
|
||||
self.current_size += 1
|
||||
return created
|
||||
return self.channel.receive()
|
||||
return self.channel.wait()
|
||||
|
||||
def put(self, item):
|
||||
"""Put an item back into the pool, when done
|
||||
@@ -100,7 +95,7 @@ class Pool(object):
|
||||
self.current_size -= 1
|
||||
return
|
||||
|
||||
if self.channel.balance < 0:
|
||||
if self.channel.sem.balance < 0:
|
||||
self.channel.send(item)
|
||||
else:
|
||||
if self.order_as_stack:
|
||||
@@ -121,8 +116,8 @@ class Pool(object):
|
||||
def waiting(self):
|
||||
"""Return the number of routines waiting for a pool item.
|
||||
"""
|
||||
if self.channel.balance < 0:
|
||||
return -self.channel.balance
|
||||
if self.channel.sem.balance < 0:
|
||||
return -self.channel.sem.balance
|
||||
return 0
|
||||
|
||||
def create(self):
|
||||
@@ -212,458 +207,6 @@ class ExceptionWrapper(object):
|
||||
def __init__(self, e):
|
||||
self.e = e
|
||||
|
||||
|
||||
class CoroutinePool(Pool):
|
||||
""" Like a thread pool, but with coroutines.
|
||||
|
||||
Coroutine pools are useful for splitting up tasks or globally controlling
|
||||
concurrency. You don't retrieve the coroutines directly with get() --
|
||||
instead use the execute() and execute_async() methods to run code.
|
||||
|
||||
>>> from eventlet import coros, api
|
||||
>>> p = coros.CoroutinePool(max_size=2)
|
||||
>>> def foo(a):
|
||||
... print "foo", a
|
||||
...
|
||||
>>> evt = p.execute(foo, 1)
|
||||
>>> evt.wait()
|
||||
foo 1
|
||||
|
||||
Once the pool is exhausted, calling an execute forces a yield.
|
||||
|
||||
>>> p.execute_async(foo, 2)
|
||||
>>> p.execute_async(foo, 3)
|
||||
>>> p.free()
|
||||
0
|
||||
>>> p.execute_async(foo, 4)
|
||||
foo 2
|
||||
foo 3
|
||||
|
||||
>>> api.sleep(0)
|
||||
foo 4
|
||||
"""
|
||||
|
||||
def __init__(self, min_size=0, max_size=4, track_events=False):
|
||||
self._greenlets = set()
|
||||
if track_events:
|
||||
self._tracked_events = []
|
||||
self._next_event = None
|
||||
else:
|
||||
self._tracked_events = None
|
||||
self.requested = coros.metaphore()
|
||||
super(CoroutinePool, self).__init__(min_size, max_size)
|
||||
|
||||
## This doesn't yet pass its own doctest -- but I'm not even sure it's a
|
||||
## wonderful idea.
|
||||
## def __del__(self):
|
||||
## """Experimental: try to prevent the calling script from exiting until
|
||||
## all coroutines in this pool have run to completion.
|
||||
|
||||
## >>> from eventlet import coros
|
||||
## >>> pool = coros.CoroutinePool()
|
||||
## >>> def saw(x): print "I saw %s!"
|
||||
## ...
|
||||
## >>> pool.launch_all(saw, "GHI")
|
||||
## >>> del pool
|
||||
## I saw G!
|
||||
## I saw H!
|
||||
## I saw I!
|
||||
## """
|
||||
## self.wait_all()
|
||||
|
||||
def _main_loop(self, sender):
|
||||
""" Private, infinite loop run by a pooled coroutine. """
|
||||
try:
|
||||
# not really a loop anymore because we want the greenlet
|
||||
# to die so all its timers get canceled
|
||||
if True:
|
||||
recvd = sender.wait()
|
||||
# Delete the sender's result here because the very
|
||||
# first event through the loop is referenced by
|
||||
# spawn_startup, and therefore is not itself deleted.
|
||||
# This means that we have to free up its argument
|
||||
# because otherwise said argument persists in memory
|
||||
# forever. This is generally only a problem in unit
|
||||
# tests.
|
||||
sender._result = coros.NOT_USED
|
||||
|
||||
(evt, func, args, kw) = recvd
|
||||
self._safe_apply(evt, func, args, kw)
|
||||
# Likewise, delete these variables or else they will
|
||||
# be referenced by this frame until replaced by the
|
||||
# next recvd, which may or may not be a long time from
|
||||
# now.
|
||||
del evt, func, args, kw, recvd
|
||||
finally:
|
||||
self.put(self.create())
|
||||
|
||||
def _safe_apply(self, evt, func, args, kw):
|
||||
""" Private method that runs the function, catches exceptions, and
|
||||
passes back the return value in the event."""
|
||||
try:
|
||||
result = func(*args, **kw)
|
||||
if evt is not None:
|
||||
evt.send(result)
|
||||
if self._tracked_events is not None:
|
||||
if self._next_event is None:
|
||||
self._tracked_events.append(result)
|
||||
else:
|
||||
|
||||
ne = self._next_event
|
||||
self._next_event = None
|
||||
ne.send(result)
|
||||
except api.GreenletExit, e:
|
||||
# we're printing this out to see if it ever happens
|
||||
# in practice
|
||||
print "GreenletExit raised in coroutine pool", e
|
||||
if evt is not None:
|
||||
evt.send(e) # sent as a return value, not an exception
|
||||
except KeyboardInterrupt:
|
||||
raise # allow program to exit
|
||||
except Exception, e:
|
||||
traceback.print_exc()
|
||||
if evt is not None:
|
||||
evt.send(exc=e)
|
||||
if self._tracked_events is not None:
|
||||
if self._next_event is None:
|
||||
self._tracked_events.append(ExceptionWrapper(e))
|
||||
else:
|
||||
ne = self._next_event
|
||||
self._next_event = None
|
||||
ne.send(exc=e)
|
||||
|
||||
def _execute(self, evt, func, args, kw):
|
||||
""" Private implementation of the execute methods.
|
||||
"""
|
||||
# if reentering an empty pool, don't try to wait on a coroutine freeing
|
||||
# itself -- instead, just execute in the current coroutine
|
||||
if self.free() == 0 and api.getcurrent() in self._greenlets:
|
||||
self._safe_apply(evt, func, args, kw)
|
||||
else:
|
||||
sender = self.get()
|
||||
sender.send((evt, func, args, kw))
|
||||
|
||||
def create(self):
|
||||
"""Private implementation of eventlet.pools.Pool
|
||||
interface. Creates an event and spawns the
|
||||
_main_loop coroutine, passing the event.
|
||||
The event is used to send a callable into the
|
||||
new coroutine, to be executed.
|
||||
"""
|
||||
sender = coros.event()
|
||||
self._greenlets.add(api.spawn(self._main_loop, sender))
|
||||
return sender
|
||||
|
||||
def get(self):
|
||||
"""Override of eventlet.pools.Pool interface"""
|
||||
# Track the number of requested CoroutinePool coroutines
|
||||
self.requested.inc()
|
||||
# forward call to base class
|
||||
return super(CoroutinePool, self).get()
|
||||
|
||||
def put(self, item):
|
||||
"""Override of eventlet.pools.Pool interface"""
|
||||
# forward call to base class
|
||||
super(CoroutinePool, self).put(item)
|
||||
# Track the number of outstanding CoroutinePool coroutines
|
||||
self.requested.dec()
|
||||
|
||||
def execute(self, func, *args, **kw):
|
||||
"""Execute func in one of the coroutines maintained
|
||||
by the pool, when one is free.
|
||||
|
||||
Immediately returns an eventlet.coros.event object which
|
||||
func's result will be sent to when it is available.
|
||||
|
||||
>>> from eventlet import coros
|
||||
>>> p = coros.CoroutinePool()
|
||||
>>> evt = p.execute(lambda a: ('foo', a), 1)
|
||||
>>> evt.wait()
|
||||
('foo', 1)
|
||||
"""
|
||||
receiver = coros.event()
|
||||
self._execute(receiver, func, args, kw)
|
||||
return receiver
|
||||
|
||||
def execute_async(self, func, *args, **kw):
|
||||
"""Execute func in one of the coroutines maintained
|
||||
by the pool, when one is free.
|
||||
|
||||
No return value is provided.
|
||||
>>> from eventlet import coros, api
|
||||
>>> p = coros.CoroutinePool()
|
||||
>>> def foo(a):
|
||||
... print "foo", a
|
||||
...
|
||||
>>> p.execute_async(foo, 1)
|
||||
>>> api.sleep(0)
|
||||
foo 1
|
||||
"""
|
||||
self._execute(None, func, args, kw)
|
||||
|
||||
def wait(self):
|
||||
"""Wait for the next execute in the pool to complete,
|
||||
and return the result.
|
||||
|
||||
You must pass track_events=True to the CoroutinePool constructor
|
||||
in order to use this method.
|
||||
"""
|
||||
assert self._tracked_events is not None, (
|
||||
"Must pass track_events=True to the constructor to use CoroutinePool.wait()")
|
||||
if self._next_event is not None:
|
||||
return self._next_event.wait()
|
||||
|
||||
if not self._tracked_events:
|
||||
self._next_event = coros.event()
|
||||
return self._next_event.wait()
|
||||
|
||||
result = self._tracked_events.pop(0)
|
||||
if isinstance(result, ExceptionWrapper):
|
||||
raise result.e
|
||||
|
||||
if not self._tracked_events:
|
||||
self._next_event = coros.event()
|
||||
return result
|
||||
|
||||
def killall(self):
|
||||
for g in self._greenlets:
|
||||
api.kill(g)
|
||||
|
||||
def wait_all(self):
|
||||
"""Wait until all coroutines started either by execute() or
|
||||
execute_async() have completed. If you kept the event objects returned
|
||||
by execute(), you can then call their individual wait() methods to
|
||||
retrieve results with no further actual waiting.
|
||||
|
||||
>>> from eventlet import coros
|
||||
>>> pool = coros.CoroutinePool()
|
||||
>>> pool.wait_all()
|
||||
>>> def hi(name):
|
||||
... print "Hello, %s!" % name
|
||||
... return name
|
||||
...
|
||||
>>> evt = pool.execute(hi, "world")
|
||||
>>> pool.execute_async(hi, "darkness, my old friend")
|
||||
>>> pool.wait_all()
|
||||
Hello, world!
|
||||
Hello, darkness, my old friend!
|
||||
>>> evt.wait()
|
||||
'world'
|
||||
>>> pool.wait_all()
|
||||
"""
|
||||
self.requested.wait()
|
||||
|
||||
def launch_all(self, function, iterable):
|
||||
"""For each tuple (sequence) in iterable, launch function(*tuple) in
|
||||
its own coroutine -- like itertools.starmap(), but in parallel.
|
||||
Discard values returned by function(). You should call wait_all() to
|
||||
wait for all coroutines, newly-launched plus any previously-submitted
|
||||
execute() or execute_async() calls, to complete.
|
||||
|
||||
>>> from eventlet import coros
|
||||
>>> pool = coros.CoroutinePool()
|
||||
>>> def saw(x):
|
||||
... print "I saw %s!" % x
|
||||
...
|
||||
>>> pool.launch_all(saw, "ABC")
|
||||
>>> pool.wait_all()
|
||||
I saw A!
|
||||
I saw B!
|
||||
I saw C!
|
||||
"""
|
||||
for tup in iterable:
|
||||
self.execute_async(function, *tup)
|
||||
|
||||
def process_all(self, function, iterable):
|
||||
"""For each tuple (sequence) in iterable, launch function(*tuple) in
|
||||
its own coroutine -- like itertools.starmap(), but in parallel.
|
||||
Discard values returned by function(). Don't return until all
|
||||
coroutines, newly-launched plus any previously-submitted execute() or
|
||||
execute_async() calls, have completed.
|
||||
|
||||
>>> from eventlet import coros
|
||||
>>> pool = coros.CoroutinePool()
|
||||
>>> def saw(x): print "I saw %s!" % x
|
||||
...
|
||||
>>> pool.process_all(saw, "DEF")
|
||||
I saw D!
|
||||
I saw E!
|
||||
I saw F!
|
||||
"""
|
||||
self.launch_all(function, iterable)
|
||||
self.wait_all()
|
||||
|
||||
def generate_results(self, function, iterable, qsize=None):
|
||||
"""For each tuple (sequence) in iterable, launch function(*tuple) in
|
||||
its own coroutine -- like itertools.starmap(), but in parallel.
|
||||
Yield each of the values returned by function(), in the order they're
|
||||
completed rather than the order the coroutines were launched.
|
||||
|
||||
Iteration stops when we've yielded results for each arguments tuple in
|
||||
iterable. Unlike wait_all() and process_all(), this function does not
|
||||
wait for any previously-submitted execute() or execute_async() calls.
|
||||
|
||||
Results are temporarily buffered in a queue. If you pass qsize=, this
|
||||
value is used to limit the max size of the queue: an attempt to buffer
|
||||
too many results will suspend the completed CoroutinePool coroutine
|
||||
until the requesting coroutine (the caller of generate_results()) has
|
||||
retrieved one or more results by calling this generator-iterator's
|
||||
next().
|
||||
|
||||
If any coroutine raises an uncaught exception, that exception will
|
||||
propagate to the requesting coroutine via the corresponding next() call.
|
||||
|
||||
What I particularly want these tests to illustrate is that using this
|
||||
generator function:
|
||||
|
||||
for result in generate_results(function, iterable):
|
||||
# ... do something with result ...
|
||||
|
||||
executes coroutines at least as aggressively as the classic eventlet
|
||||
idiom:
|
||||
|
||||
events = [pool.execute(function, *args) for args in iterable]
|
||||
for event in events:
|
||||
result = event.wait()
|
||||
# ... do something with result ...
|
||||
|
||||
even without a distinct event object for every arg tuple in iterable,
|
||||
and despite the funny flow control from interleaving launches of new
|
||||
coroutines with yields of completed coroutines' results.
|
||||
|
||||
(The use case that makes this function preferable to the classic idiom
|
||||
above is when the iterable, which may itself be a generator, produces
|
||||
millions of items.)
|
||||
|
||||
>>> from eventlet import coros
|
||||
>>> import string
|
||||
>>> pool = coros.CoroutinePool(max_size=5)
|
||||
>>> pausers = [coros.event() for x in xrange(2)]
|
||||
>>> def longtask(evt, desc):
|
||||
... print "%s woke up with %s" % (desc, evt.wait())
|
||||
...
|
||||
>>> pool.launch_all(longtask, zip(pausers, "AB"))
|
||||
>>> def quicktask(desc):
|
||||
... print "returning %s" % desc
|
||||
... return desc
|
||||
...
|
||||
|
||||
(Instead of using a for loop, step through generate_results()
|
||||
items individually to illustrate timing)
|
||||
|
||||
>>> step = iter(pool.generate_results(quicktask, string.ascii_lowercase))
|
||||
>>> print step.next()
|
||||
returning a
|
||||
returning b
|
||||
returning c
|
||||
a
|
||||
>>> print step.next()
|
||||
b
|
||||
>>> print step.next()
|
||||
c
|
||||
>>> print step.next()
|
||||
returning d
|
||||
returning e
|
||||
returning f
|
||||
d
|
||||
>>> pausers[0].send("A")
|
||||
>>> print step.next()
|
||||
e
|
||||
>>> print step.next()
|
||||
f
|
||||
>>> print step.next()
|
||||
A woke up with A
|
||||
returning g
|
||||
returning h
|
||||
returning i
|
||||
g
|
||||
>>> print "".join([step.next() for x in xrange(3)])
|
||||
returning j
|
||||
returning k
|
||||
returning l
|
||||
returning m
|
||||
hij
|
||||
>>> pausers[1].send("B")
|
||||
>>> print "".join([step.next() for x in xrange(4)])
|
||||
B woke up with B
|
||||
returning n
|
||||
returning o
|
||||
returning p
|
||||
returning q
|
||||
klmn
|
||||
"""
|
||||
# Get an iterator because of our funny nested loop below. Wrap the
|
||||
# iterable in enumerate() so we count items that come through.
|
||||
tuples = iter(enumerate(iterable))
|
||||
# If the iterable is empty, this whole function is a no-op, and we can
|
||||
# save ourselves some grief by just quitting out. In particular, once
|
||||
# we enter the outer loop below, we're going to wait on the queue --
|
||||
# but if we launched no coroutines with that queue as the destination,
|
||||
# we could end up waiting a very long time.
|
||||
try:
|
||||
index, args = tuples.next()
|
||||
except StopIteration:
|
||||
return
|
||||
# From this point forward, 'args' is the current arguments tuple and
|
||||
# 'index+1' counts how many such tuples we've seen.
|
||||
# This implementation relies on the fact that _execute() accepts an
|
||||
# event-like object, and -- unless it's None -- the completed
|
||||
# coroutine calls send(result). We slyly pass a queue rather than an
|
||||
# event -- the same queue instance for all coroutines. This is why our
|
||||
# queue interface intentionally resembles the event interface.
|
||||
q = coros.queue(max_size=qsize)
|
||||
# How many results have we yielded so far?
|
||||
finished = 0
|
||||
# This first loop is only until we've launched all the coroutines. Its
|
||||
# complexity is because if iterable contains more args tuples than the
|
||||
# size of our pool, attempting to _execute() the (poolsize+1)th
|
||||
# coroutine would suspend until something completes and send()s its
|
||||
# result to our queue. But to keep down queue overhead and to maximize
|
||||
# responsiveness to our caller, we'd rather suspend on reading the
|
||||
# queue. So we stuff the pool as full as we can, then wait for
|
||||
# something to finish, then stuff more coroutines into the pool.
|
||||
try:
|
||||
while True:
|
||||
# Before each yield, start as many new coroutines as we can fit.
|
||||
# (The self.free() test isn't 100% accurate: if we happen to be
|
||||
# executing in one of the pool's coroutines, we could _execute()
|
||||
# without waiting even if self.free() reports 0. See _execute().)
|
||||
# The point is that we don't want to wait in the _execute() call,
|
||||
# we want to wait in the q.wait() call.
|
||||
# IMPORTANT: at start, and whenever we've caught up with all
|
||||
# coroutines we've launched so far, we MUST iterate this inner
|
||||
# loop at least once, regardless of self.free() -- otherwise the
|
||||
# q.wait() call below will deadlock!
|
||||
# Recall that index is the index of the NEXT args tuple that we
|
||||
# haven't yet launched. Therefore it counts how many args tuples
|
||||
# we've launched so far.
|
||||
while self.free() > 0 or finished == index:
|
||||
# Just like the implementation of execute_async(), save that
|
||||
# we're passing our queue instead of None as the "event" to
|
||||
# which to send() the result.
|
||||
self._execute(q, function, args, {})
|
||||
# We've consumed that args tuple, advance to next.
|
||||
index, args = tuples.next()
|
||||
# Okay, we've filled up the pool again, yield a result -- which
|
||||
# will probably wait for a coroutine to complete. Although we do
|
||||
# have q.ready(), so we could iterate without waiting, we avoid
|
||||
# that because every yield could involve considerable real time.
|
||||
# We don't know how long it takes to return from yield, so every
|
||||
# time we do, take the opportunity to stuff more requests into the
|
||||
# pool before yielding again.
|
||||
yield q.wait()
|
||||
# Be sure to count results so we know when to stop!
|
||||
finished += 1
|
||||
except StopIteration:
|
||||
pass
|
||||
# Here we've exhausted the input iterable. index+1 is the total number
|
||||
# of coroutines we've launched. We probably haven't yielded that many
|
||||
# results yet. Wait for the rest of the results, yielding them as they
|
||||
# arrive.
|
||||
while finished < index + 1:
|
||||
yield q.wait()
|
||||
finished += 1
|
||||
|
||||
if __name__=='__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
@@ -683,6 +683,9 @@ class RunningProcSet(object):
|
||||
for p in self.args[0]:
|
||||
p.link(lambda p: self.procs.discard(p))
|
||||
|
||||
def __len__(self):
|
||||
return len(self.procs)
|
||||
|
||||
def __contains__(self, item):
|
||||
if isinstance(item, api.Greenlet):
|
||||
# special case for "api.getcurrent() in running_proc_set" to work
|
||||
|
@@ -1,36 +1,30 @@
|
||||
"""\
|
||||
@file processes.py
|
||||
|
||||
Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import errno
|
||||
import os
|
||||
import popen2
|
||||
import signal
|
||||
import sys
|
||||
|
||||
from eventlet import coros
|
||||
from eventlet import pools
|
||||
from eventlet import greenio
|
||||
from eventlet import util
|
||||
|
||||
|
||||
class DeadProcess(RuntimeError):
|
||||
|
@@ -1,29 +1,28 @@
|
||||
"""\
|
||||
@file saranwrap.py
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
"""
|
||||
@author Phoenix
|
||||
@date 2007-07-13
|
||||
@brief A simple, pickle based rpc mechanism which reflects python
|
||||
objects and callables.
|
||||
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@brief A simple, pickle based rpc mechanism which reflects python objects and
|
||||
callables.
|
||||
|
||||
This file provides classes and exceptions used for simple python level
|
||||
remote procedure calls. This is achieved by intercepting the basic
|
||||
@@ -91,12 +90,6 @@ import os
|
||||
import struct
|
||||
import sys
|
||||
|
||||
try:
|
||||
set = set
|
||||
frozenset = frozenset
|
||||
except NameError:
|
||||
from sets import Set as set, ImmutableSet as frozenset
|
||||
|
||||
from eventlet.processes import Process, DeadProcess
|
||||
from eventlet import api, pools
|
||||
|
||||
@@ -282,7 +275,7 @@ class ChildProcess(object):
|
||||
retval = _read_response(_id, attribute, self._in, self)
|
||||
finally:
|
||||
self._lock.put(t)
|
||||
|
||||
|
||||
return retval
|
||||
|
||||
def __del__(self):
|
||||
@@ -330,7 +323,7 @@ not supported, so you have to know what has been exported.
|
||||
_dead_list.remove(dead_object)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
|
||||
# Pass all public attributes across to find out if it is
|
||||
# callable or a simple attribute.
|
||||
request = Request('getattr', {'id':my_id, 'attribute':attribute})
|
||||
@@ -339,7 +332,7 @@ not supported, so you have to know what has been exported.
|
||||
def __setattr__(self, attribute, value):
|
||||
#_prnt("Proxy::__setattr__: %s" % attribute)
|
||||
if _is_local(attribute):
|
||||
# It must be local to this actual object, so we have to apply
|
||||
# It must be local to this actual object, so we have to apply
|
||||
# it to the dict in a roundabout way
|
||||
attribute = _unmunge_attr_name(attribute)
|
||||
super(Proxy, self).__getattribute__('__dict__')[attribute]=value
|
||||
@@ -377,7 +370,7 @@ not need to deal with this class directly."""
|
||||
my_id = self.__local_dict['_id']
|
||||
request = Request('getitem', {'id':my_id, 'key':key})
|
||||
return my_cp.make_request(request, attribute=key)
|
||||
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
my_cp = self.__local_dict['_cp']
|
||||
my_id = self.__local_dict['_id']
|
||||
@@ -429,7 +422,7 @@ not need to deal with this class directly."""
|
||||
# since the remote object is being serialized whole anyway,
|
||||
# there's no semantic difference between copy and deepcopy
|
||||
__copy__ = __deepcopy__
|
||||
|
||||
|
||||
|
||||
def proxied_type(self):
|
||||
""" Returns the type of the object in the child process.
|
||||
@@ -439,7 +432,7 @@ def proxied_type(self):
|
||||
'real' type value."""
|
||||
if type(self) is not ObjectProxy:
|
||||
return type(self)
|
||||
|
||||
|
||||
my_cp = self.__local_dict['_cp']
|
||||
my_id = self.__local_dict['_id']
|
||||
request = Request('type', {'id':my_id})
|
||||
@@ -506,7 +499,7 @@ when the id is None."""
|
||||
else:
|
||||
raise e
|
||||
#_log('getattr: %s' % str(response))
|
||||
|
||||
|
||||
def handle_setattr(self, obj, req):
|
||||
try:
|
||||
return setattr(obj, req['attribute'], req['value'])
|
||||
@@ -541,7 +534,7 @@ when the id is None."""
|
||||
fn = obj[req['name']]
|
||||
else:
|
||||
raise e
|
||||
|
||||
|
||||
return fn(*req['args'],**req['kwargs'])
|
||||
|
||||
def handle_del(self, obj, req):
|
||||
|
@@ -1,36 +1,30 @@
|
||||
"""\
|
||||
@file support.pylib.py
|
||||
@author Donovan Preston
|
||||
|
||||
Copyright (c) 2005-2006, Donovan Preston
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
# @author Donovan Preston
|
||||
#
|
||||
# Copyright (c) 2005-2006, Donovan Preston
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
from py.magic import greenlet
|
||||
|
||||
|
||||
import sys
|
||||
import types
|
||||
|
||||
|
||||
def emulate():
|
||||
module = types.ModuleType('greenlet')
|
||||
sys.modules['greenlet'] = module
|
||||
@@ -38,5 +32,3 @@ def emulate():
|
||||
module.getcurrent = greenlet.getcurrent
|
||||
module.GreenletExit = greenlet.GreenletExit
|
||||
|
||||
|
||||
|
||||
|
@@ -1,35 +1,29 @@
|
||||
"""\
|
||||
@file stacklesspypysupport.py
|
||||
@author Donovan Preston
|
||||
|
||||
Copyright (c) 2008, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
# @author Donovan Preston
|
||||
#
|
||||
# Copyright (c) 2008, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
from stackless import greenlet
|
||||
|
||||
|
||||
import sys
|
||||
import types
|
||||
|
||||
|
||||
def emulate():
|
||||
module = types.ModuleType('greenlet')
|
||||
sys.modules['greenlet'] = module
|
||||
@@ -37,8 +31,3 @@ def emulate():
|
||||
module.getcurrent = greenlet.getcurrent
|
||||
module.GreenletExit = greenlet.GreenletExit
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -1,41 +1,34 @@
|
||||
"""\
|
||||
@file __init__.py
|
||||
@brief Support for using stackless python. Broken and riddled with
|
||||
print statements at the moment. Please fix it!
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
Support for using stackless python. Broken and riddled with print statements
|
||||
at the moment. Please fix it!
|
||||
"""
|
||||
|
||||
import sys
|
||||
import types
|
||||
|
||||
import stackless
|
||||
import traceback
|
||||
|
||||
|
||||
caller = None
|
||||
|
||||
|
||||
coro_args = {}
|
||||
|
||||
|
||||
tasklet_to_greenlet = {}
|
||||
|
||||
|
||||
|
@@ -1,142 +0,0 @@
|
||||
"""\
|
||||
@file support.twisted.py
|
||||
@author Donovan Preston
|
||||
|
||||
Copyright (c) 2005-2006, Donovan Preston
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
from eventlet import api
|
||||
from eventlet import timer
|
||||
|
||||
from twisted.internet import posixbase
|
||||
from twisted.internet.interfaces import IReactorFDSet
|
||||
|
||||
try:
|
||||
from zope.interface import implements
|
||||
_working = True
|
||||
except ImportError:
|
||||
_working = False
|
||||
def implements(*args, **kw):
|
||||
pass
|
||||
|
||||
|
||||
class TwistedTimer(object):
|
||||
def __init__(self, timer):
|
||||
self.timer = timer
|
||||
|
||||
def cancel(self):
|
||||
self.timer.cancel()
|
||||
|
||||
def getTime(self):
|
||||
return self.timer.scheduled_time
|
||||
|
||||
def delay(self, seconds):
|
||||
hub = api.get_hub()
|
||||
new_time = hub.clock() - self.timer_scheduled_time + seconds
|
||||
self.timer.cancel()
|
||||
cb, args, kw = self.timer.tpl
|
||||
self.timer = hub.schedule_call(new_time, cb, *args, **kw)
|
||||
|
||||
def reset(self, new_time):
|
||||
self.timer.cancel()
|
||||
cb, args, kw = self.timer.tpl
|
||||
self.timer = api.get_hub().schedule_call(new_time, cb, *args, **kw)
|
||||
|
||||
def active(self):
|
||||
return not self.timer.called
|
||||
|
||||
|
||||
class EventletReactor(posixbase.PosixReactorBase):
|
||||
implements(IReactorFDSet)
|
||||
|
||||
def __init__(self, *args, **kw):
|
||||
self._readers = {}
|
||||
self._writers = {}
|
||||
posixbase.PosixReactorBase.__init__(self, *args, **kw)
|
||||
|
||||
def callLater(self, func, *args, **kw):
|
||||
return TwistedTimer(api.call_after(func, *args, **kw))
|
||||
|
||||
def run(self):
|
||||
self.running = True
|
||||
self._stopper = api.call_after(sys.maxint / 1000.0, lambda: None)
|
||||
## schedule a call way in the future, and cancel it in stop?
|
||||
api.get_hub().run()
|
||||
|
||||
def stop(self):
|
||||
self._stopper.cancel()
|
||||
posixbase.PosixReactorBase.stop(self)
|
||||
api.get_hub().remove_descriptor(self._readers.keys()[0])
|
||||
api.get_hub().abort()
|
||||
|
||||
def addReader(self, reader):
|
||||
print "NEW READER", reader.fileno()
|
||||
fileno = reader.fileno()
|
||||
self._readers[fileno] = reader
|
||||
api.get_hub().add_descriptor(fileno, read=self._got_read)
|
||||
|
||||
def _got_read(self, fileno):
|
||||
print "got read on", fileno, self._readers[fileno]
|
||||
api.get_hub().add_descriptor(fileno, read=self._got_read)
|
||||
self._readers[fileno].doRead()
|
||||
|
||||
def addWriter(self, writer):
|
||||
print "NEW WRITER", writer.fileno()
|
||||
fileno = writer.fileno()
|
||||
self._writers[fileno] = writer
|
||||
api.get_hub().add_descriptor(fileno, write=self._got_write)
|
||||
|
||||
def _got_write(self, fileno):
|
||||
print "got write on", fileno, self._writers[fileno]
|
||||
api.get_hub().add_descriptor(fileno, write=self._got_write)
|
||||
self._writers[fileno].doWrite()
|
||||
|
||||
def removeReader(self, reader):
|
||||
print "removing reader", reader.fileno()
|
||||
fileno = reader.fileno()
|
||||
if fileno in self._readers:
|
||||
self._readers.pop(fileno)
|
||||
api.get_hub().remove_descriptor(fileno)
|
||||
|
||||
def removeWriter(self, writer):
|
||||
print "removing writer", writer.fileno()
|
||||
fileno = writer.fileno()
|
||||
if fileno in self._writers:
|
||||
self._writers.pop(fileno)
|
||||
api.get_hub().remove_descriptor(fileno)
|
||||
|
||||
def removeAll(self):
|
||||
return self._removeAll(self._readers.values(), self._writers.values())
|
||||
|
||||
|
||||
def install():
|
||||
if not _working:
|
||||
raise RuntimeError, "Can't use support.twisted because zope.interface is not installed."
|
||||
reactor = EventletReactor()
|
||||
from twisted.internet.main import installReactor
|
||||
installReactor(reactor)
|
||||
|
||||
|
||||
__all__ = ['install']
|
||||
|
@@ -1,27 +1,25 @@
|
||||
"""\
|
||||
@file timer.py
|
||||
@author Bob Ippolito
|
||||
# @author Bob Ippolito
|
||||
#
|
||||
# Copyright (c) 2005-2006, Bob Ippolito
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
Copyright (c) 2005-2006, Bob Ippolito
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
from eventlet.api import get_hub, getcurrent
|
||||
|
||||
""" If true, captures a stack trace for each timer when constructed. This is
|
||||
@@ -95,7 +93,7 @@ class Timer(object):
|
||||
pass
|
||||
|
||||
class LocalTimer(Timer):
|
||||
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.greenlet = getcurrent()
|
||||
Timer.__init__(self, *args, **kwargs)
|
||||
|
@@ -1,21 +1,17 @@
|
||||
"""\
|
||||
@file tpool.py
|
||||
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Copyright (c) 2007, IBM Corp.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Copyright (c) 2007, IBM Corp.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
import threading
|
||||
@@ -75,7 +71,7 @@ def tworker():
|
||||
except SYS_EXCS:
|
||||
raise
|
||||
except Exception,exn:
|
||||
import sys, traceback
|
||||
import sys
|
||||
(a,b,tb) = sys.exc_info()
|
||||
rv = (exn,a,b,tb)
|
||||
_rspq.put((e,rv))
|
||||
@@ -86,7 +82,7 @@ def tworker():
|
||||
def erecv(e):
|
||||
rv = e.wait()
|
||||
if isinstance(rv,tuple) and len(rv) == 4 and isinstance(rv[0],Exception):
|
||||
import sys, traceback
|
||||
import traceback
|
||||
(e,a,b,tb) = rv
|
||||
if not QUIET:
|
||||
traceback.print_exception(Exception,e,tb)
|
||||
|
@@ -1,32 +1,28 @@
|
||||
"""\
|
||||
@file util.py
|
||||
@author Bob Ippolito
|
||||
|
||||
Copyright (c) 2005-2006, Bob Ippolito
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# @author Bob Ippolito
|
||||
#
|
||||
# Copyright (c) 2005-2006, Bob Ippolito
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import os
|
||||
import select
|
||||
import socket
|
||||
import sys
|
||||
import errno
|
||||
|
||||
try:
|
||||
@@ -81,7 +77,7 @@ except AttributeError:
|
||||
|
||||
def wrap_ssl(sock, certificate=None, private_key=None):
|
||||
from OpenSSL import SSL
|
||||
from eventlet import greenio, util
|
||||
from eventlet import greenio
|
||||
context = SSL.Context(SSL.SSLv23_METHOD)
|
||||
if certificate is not None:
|
||||
context.use_certificate_file(certificate)
|
||||
@@ -174,7 +170,7 @@ def wrap_pipes_with_coroutine_pipes():
|
||||
return pid, evt.wait()
|
||||
return 0, 0
|
||||
elif options:
|
||||
return __original_waitpid__(pid, result)
|
||||
return __original_waitpid__(pid, options)
|
||||
return pid, evt.wait()
|
||||
os.fdopen = new_fdopen
|
||||
os.read = new_read
|
||||
@@ -238,7 +234,7 @@ def wrap_threading_local_with_coro_local():
|
||||
class local(object):
|
||||
def __init__(self):
|
||||
self.__dict__['__objs'] = {}
|
||||
|
||||
|
||||
def __getattr__(self, attr, g=get_ident):
|
||||
try:
|
||||
return self.__dict__['__objs'][g()][attr]
|
||||
@@ -246,10 +242,10 @@ def wrap_threading_local_with_coro_local():
|
||||
raise AttributeError(
|
||||
"No variable %s defined for the thread %s"
|
||||
% (attr, g()))
|
||||
|
||||
|
||||
def __setattr__(self, attr, value, g=get_ident):
|
||||
self.__dict__['__objs'].setdefault(g(), {})[attr] = value
|
||||
|
||||
|
||||
def __delattr__(self, attr, g=get_ident):
|
||||
try:
|
||||
del self.__dict__['__objs'][g()][attr]
|
||||
|
@@ -1,27 +1,24 @@
|
||||
"""\
|
||||
@file wsgi.py
|
||||
@author Bob Ippolito
|
||||
|
||||
Copyright (c) 2005-2006, Bob Ippolito
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# @author Bob Ippolito
|
||||
#
|
||||
# Copyright (c) 2005-2006, Bob Ippolito
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import errno
|
||||
import os
|
||||
@@ -124,7 +121,7 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
if e[0] != errno.EBADF:
|
||||
raise
|
||||
self.raw_requestline = ''
|
||||
|
||||
|
||||
if not self.raw_requestline:
|
||||
self.close_connection = 1
|
||||
return
|
||||
@@ -254,7 +251,7 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
start_response("500 Internal Server Error", [('Content-type', 'text/plain')])
|
||||
write(exc)
|
||||
return
|
||||
|
||||
|
||||
if towrite:
|
||||
write(''.join(towrite))
|
||||
if not headers_sent:
|
||||
@@ -346,7 +343,7 @@ class Server(BaseHTTPServer.HTTPServer):
|
||||
self.log = sys.stderr
|
||||
self.app = app
|
||||
self.environ = environ
|
||||
self.max_http_version = max_http_version
|
||||
self.max_http_version = max_http_version
|
||||
self.protocol = protocol
|
||||
self.pid = os.getpid()
|
||||
if minimum_chunk_size is not None:
|
||||
|
@@ -1,38 +1,32 @@
|
||||
"""\
|
||||
@file api_test.py
|
||||
@author Donovan Preston
|
||||
|
||||
Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# @author Donovan Preston
|
||||
#
|
||||
# Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import os
|
||||
import socket
|
||||
import os.path
|
||||
|
||||
from eventlet import api
|
||||
from eventlet import greenio
|
||||
from greentest import tests
|
||||
from eventlet import util
|
||||
|
||||
import os.path
|
||||
import socket
|
||||
|
||||
|
||||
def check_hub():
|
||||
# Clear through the descriptor queue
|
||||
@@ -50,10 +44,10 @@ def check_hub():
|
||||
|
||||
class TestApi(tests.TestCase):
|
||||
mode = 'static'
|
||||
|
||||
|
||||
certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt')
|
||||
private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key')
|
||||
|
||||
|
||||
def test_tcp_listener(self):
|
||||
socket = api.tcp_listener(('0.0.0.0', 0))
|
||||
assert socket.getsockname()[0] == '0.0.0.0'
|
||||
@@ -86,27 +80,27 @@ class TestApi(tests.TestCase):
|
||||
check_hub()
|
||||
|
||||
def test_connect_ssl(self):
|
||||
def accept_once(listenfd):
|
||||
try:
|
||||
def accept_once(listenfd):
|
||||
try:
|
||||
conn, addr = listenfd.accept()
|
||||
fl = conn.makeGreenFile('w')
|
||||
fl.write('hello\r\n')
|
||||
fl.close()
|
||||
conn.close()
|
||||
finally:
|
||||
listenfd.close()
|
||||
|
||||
server = api.ssl_listener(('0.0.0.0', 0),
|
||||
self.certificate_file,
|
||||
self.private_key_file)
|
||||
api.spawn(accept_once, server)
|
||||
|
||||
client = util.wrap_ssl(
|
||||
conn.close()
|
||||
finally:
|
||||
listenfd.close()
|
||||
|
||||
server = api.ssl_listener(('0.0.0.0', 0),
|
||||
self.certificate_file,
|
||||
self.private_key_file)
|
||||
api.spawn(accept_once, server)
|
||||
|
||||
client = util.wrap_ssl(
|
||||
api.connect_tcp(('127.0.0.1', server.getsockname()[1])))
|
||||
client = client.makeGreenFile()
|
||||
|
||||
assert client.readline() == 'hello\r\n'
|
||||
assert client.read() == ''
|
||||
assert client.readline() == 'hello\r\n'
|
||||
assert client.read() == ''
|
||||
client.close()
|
||||
|
||||
def test_server(self):
|
||||
|
@@ -1,32 +1,27 @@
|
||||
"""\
|
||||
@file coros_test.py
|
||||
@author Donovan Preston, Ryan Williams
|
||||
# @author Donovan Preston, Ryan Williams
|
||||
#
|
||||
# Copyright (c) 2000-2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
Copyright (c) 2000-2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
from greentest import tests
|
||||
from eventlet import timer
|
||||
from eventlet import coros, api
|
||||
|
||||
import sys
|
||||
|
||||
class TestEvent(tests.TestCase):
|
||||
mode = 'static'
|
||||
def setUp(self):
|
||||
@@ -114,121 +109,6 @@ class TestEvent(tests.TestCase):
|
||||
self.assertRaises(api.TimeoutError, evt.wait)
|
||||
|
||||
|
||||
class TestCoroutinePool(tests.TestCase):
|
||||
mode = 'static'
|
||||
def setUp(self):
|
||||
# raise an exception if we're waiting forever
|
||||
self._cancel_timeout = api.exc_after(1, api.TimeoutError)
|
||||
|
||||
def tearDown(self):
|
||||
self._cancel_timeout.cancel()
|
||||
|
||||
def test_execute_async(self):
|
||||
done = coros.event()
|
||||
def some_work():
|
||||
done.send()
|
||||
pool = coros.CoroutinePool(0, 2)
|
||||
pool.execute_async(some_work)
|
||||
done.wait()
|
||||
|
||||
def test_execute(self):
|
||||
value = 'return value'
|
||||
def some_work():
|
||||
return value
|
||||
pool = coros.CoroutinePool(0, 2)
|
||||
worker = pool.execute(some_work)
|
||||
self.assertEqual(value, worker.wait())
|
||||
|
||||
def test_multiple_coros(self):
|
||||
evt = coros.event()
|
||||
results = []
|
||||
def producer():
|
||||
results.append('prod')
|
||||
evt.send()
|
||||
|
||||
def consumer():
|
||||
results.append('cons1')
|
||||
evt.wait()
|
||||
results.append('cons2')
|
||||
|
||||
pool = coros.CoroutinePool(0, 2)
|
||||
done = pool.execute(consumer)
|
||||
pool.execute_async(producer)
|
||||
done.wait()
|
||||
self.assertEquals(['cons1', 'prod', 'cons2'], results)
|
||||
|
||||
# since CoroutinePool does not kill the greenlet, the following does not work
|
||||
# def test_timer_cancel(self):
|
||||
# def some_work():
|
||||
# t = timer.LocalTimer(5, lambda: None)
|
||||
# t.schedule()
|
||||
# return t
|
||||
# pool = coros.CoroutinePool(0, 2)
|
||||
# worker = pool.execute(some_work)
|
||||
# t = worker.wait()
|
||||
# api.sleep(0)
|
||||
# self.assertEquals(t.cancelled, True)
|
||||
|
||||
def test_reentrant(self):
|
||||
pool = coros.CoroutinePool(0,1)
|
||||
def reenter():
|
||||
waiter = pool.execute(lambda a: a, 'reenter')
|
||||
self.assertEqual('reenter', waiter.wait())
|
||||
|
||||
outer_waiter = pool.execute(reenter)
|
||||
outer_waiter.wait()
|
||||
|
||||
evt = coros.event()
|
||||
def reenter_async():
|
||||
pool.execute_async(lambda a: a, 'reenter')
|
||||
evt.send('done')
|
||||
|
||||
pool.execute_async(reenter_async)
|
||||
evt.wait()
|
||||
|
||||
def test_horrible_main_loop_death(self):
|
||||
# testing the case that causes the run_forever
|
||||
# method to exit unwantedly
|
||||
pool = coros.CoroutinePool(min_size=1, max_size=1)
|
||||
def crash(*args, **kw):
|
||||
raise RuntimeError("Whoa")
|
||||
class FakeFile(object):
|
||||
write = crash
|
||||
|
||||
# we're going to do this by causing the traceback.print_exc in
|
||||
# safe_apply to raise an exception and thus exit _main_loop
|
||||
normal_err = sys.stderr
|
||||
try:
|
||||
sys.stderr = FakeFile()
|
||||
waiter = pool.execute(crash)
|
||||
self.assertRaises(RuntimeError, waiter.wait)
|
||||
# the pool should have something free at this point since the
|
||||
# waiter returned
|
||||
self.assertEqual(pool.free(), 1)
|
||||
# shouldn't block when trying to get
|
||||
t = api.exc_after(0.1, api.TimeoutError)
|
||||
self.assert_(pool.get())
|
||||
t.cancel()
|
||||
finally:
|
||||
sys.stderr = normal_err
|
||||
|
||||
def test_track_events(self):
|
||||
pool = coros.CoroutinePool(track_events=True)
|
||||
for x in range(6):
|
||||
pool.execute(lambda n: n, x)
|
||||
for y in range(6):
|
||||
print "wait", y
|
||||
pool.wait()
|
||||
|
||||
def test_track_slow_event(self):
|
||||
pool = coros.CoroutinePool(track_events=True)
|
||||
def slow():
|
||||
api.sleep(0.1)
|
||||
return 'ok'
|
||||
pool.execute(slow)
|
||||
self.assertEquals(pool.wait(), 'ok')
|
||||
|
||||
|
||||
class IncrActor(coros.Actor):
|
||||
def received(self, evt):
|
||||
self.value = getattr(self, 'value', 0) + 1
|
||||
@@ -340,9 +220,11 @@ class TestActor(tests.TestCase):
|
||||
self.assertEqual(total[0], 2)
|
||||
# both coroutines should have been used
|
||||
self.assertEqual(self.actor._pool.current_size, 2)
|
||||
api.sleep(0)
|
||||
self.assertEqual(self.actor._pool.free(), 1)
|
||||
evt.wait()
|
||||
self.assertEqual(total[0], 3)
|
||||
api.sleep(0)
|
||||
self.assertEqual(self.actor._pool.free(), 2)
|
||||
|
||||
|
||||
|
@@ -22,8 +22,6 @@
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import os.path
|
||||
|
||||
from eventlet import api, coros
|
||||
from greentest import tests
|
||||
from eventlet import db_pool
|
||||
|
@@ -1,28 +1,24 @@
|
||||
"""\
|
||||
@file greenio_test.py
|
||||
|
||||
Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
from greentest import tests
|
||||
from eventlet import api, greenio, util
|
||||
from eventlet import api
|
||||
import socket
|
||||
|
||||
# TODO try and reuse unit tests from within Python itself
|
||||
|
@@ -1,33 +1,28 @@
|
||||
"""\
|
||||
@file httpc_test.py
|
||||
@author Bryan O'Sullivan
|
||||
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# @author Bryan O'Sullivan
|
||||
#
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import cgi
|
||||
|
||||
from eventlet import api
|
||||
from eventlet import httpc
|
||||
from eventlet import processes
|
||||
from eventlet import util
|
||||
from eventlet import wsgi
|
||||
|
||||
import time
|
||||
|
@@ -1,27 +1,23 @@
|
||||
"""\
|
||||
@file httpd_test.py
|
||||
@author Donovan Preston
|
||||
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
# @author Donovan Preston
|
||||
#
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
from eventlet import api
|
||||
from eventlet import httpd
|
||||
@@ -33,8 +29,6 @@ try:
|
||||
except ImportError:
|
||||
from StringIO import StringIO
|
||||
|
||||
from eventlet import greenio
|
||||
|
||||
|
||||
util.wrap_socket_with_coroutine_socket()
|
||||
|
||||
@@ -106,7 +100,7 @@ class TestHttpd(tests.TestCase):
|
||||
def test_001_server(self):
|
||||
sock = api.connect_tcp(
|
||||
('127.0.0.1', 12346))
|
||||
|
||||
|
||||
fd = sock.makeGreenFile()
|
||||
fd.write('GET / HTTP/1.0\r\nHost: localhost\r\n\r\n')
|
||||
result = fd.read()
|
||||
@@ -118,7 +112,7 @@ class TestHttpd(tests.TestCase):
|
||||
def test_002_keepalive(self):
|
||||
sock = api.connect_tcp(
|
||||
('127.0.0.1', 12346))
|
||||
|
||||
|
||||
fd = sock.makeGreenFile()
|
||||
fd.write('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n')
|
||||
read_http(sock)
|
||||
@@ -130,7 +124,7 @@ class TestHttpd(tests.TestCase):
|
||||
# This should go in greenio_test
|
||||
sock = api.connect_tcp(
|
||||
('127.0.0.1', 12346))
|
||||
|
||||
|
||||
fd = sock.makeGreenFile()
|
||||
fd.write('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n')
|
||||
cancel = api.exc_after(1, RuntimeError)
|
||||
@@ -172,7 +166,7 @@ class TestHttpd(tests.TestCase):
|
||||
status = result.split(' ')[1]
|
||||
self.assertEqual(status, '414')
|
||||
fd.close()
|
||||
|
||||
|
||||
def test_007_get_arg(self):
|
||||
# define a new handler that does a get_arg as well as a read_body
|
||||
def new_handle_request(req):
|
||||
@@ -180,28 +174,28 @@ class TestHttpd(tests.TestCase):
|
||||
body = req.read_body()
|
||||
req.write('a is %s, body is %s' % (a, body))
|
||||
self.site.handle_request = new_handle_request
|
||||
|
||||
|
||||
sock = api.connect_tcp(
|
||||
('127.0.0.1', 12346))
|
||||
request = '\r\n'.join((
|
||||
'POST /%s HTTP/1.0',
|
||||
'Host: localhost',
|
||||
'Content-Length: 3',
|
||||
'POST /%s HTTP/1.0',
|
||||
'Host: localhost',
|
||||
'Content-Length: 3',
|
||||
'',
|
||||
'a=a'))
|
||||
fd = sock.makeGreenFile()
|
||||
fd.write(request)
|
||||
|
||||
|
||||
# send some junk after the actual request
|
||||
fd.write('01234567890123456789')
|
||||
reqline, headers, body = read_http(sock)
|
||||
self.assertEqual(body, 'a is a, body is a=a')
|
||||
fd.close()
|
||||
|
||||
|
||||
def test_008_correctresponse(self):
|
||||
sock = api.connect_tcp(
|
||||
('127.0.0.1', 12346))
|
||||
|
||||
|
||||
fd = sock.makeGreenFile()
|
||||
fd.write('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n')
|
||||
response_line_200,_,_ = read_http(sock)
|
||||
|
@@ -93,7 +93,6 @@ def main(db):
|
||||
'parsed_command_record.id=command_record.id)')
|
||||
for row in c.execute(SQL).fetchall():
|
||||
id, command, stdout, exitcode = row
|
||||
stdout = stdout.encode()
|
||||
try:
|
||||
testname, hub = parse_stdout(stdout)
|
||||
if unittest_delim in stdout:
|
||||
|
@@ -1,35 +1,29 @@
|
||||
"""\
|
||||
@file test_pools.py
|
||||
@author Donovan Preston, Aaron Brashears
|
||||
|
||||
Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
import sys
|
||||
# @author Donovan Preston, Aaron Brashears
|
||||
#
|
||||
# Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
from eventlet import api
|
||||
from eventlet import channel
|
||||
from eventlet import coros
|
||||
from eventlet import pools
|
||||
from greentest import tests
|
||||
from eventlet import timer
|
||||
|
||||
class IntPool(pools.Pool):
|
||||
def create(self):
|
||||
@@ -240,190 +234,6 @@ class TestFan(tests.TestCase):
|
||||
self.assertRaises(pools.SomeFailed, self.pool.fan, my_failing_callable, range(4))
|
||||
|
||||
|
||||
class TestCoroutinePool(tests.TestCase):
|
||||
mode = 'static'
|
||||
def setUp(self):
|
||||
# raise an exception if we're waiting forever
|
||||
self._cancel_timeout = api.exc_after(1, TestTookTooLong())
|
||||
|
||||
def tearDown(self):
|
||||
self._cancel_timeout.cancel()
|
||||
|
||||
def test_execute_async(self):
|
||||
done = coros.event()
|
||||
def some_work():
|
||||
done.send()
|
||||
pool = pools.CoroutinePool(0, 2)
|
||||
pool.execute_async(some_work)
|
||||
done.wait()
|
||||
|
||||
def test_execute(self):
|
||||
value = 'return value'
|
||||
def some_work():
|
||||
return value
|
||||
pool = pools.CoroutinePool(0, 2)
|
||||
worker = pool.execute(some_work)
|
||||
self.assertEqual(value, worker.wait())
|
||||
|
||||
def test_multiple_coros(self):
|
||||
evt = coros.event()
|
||||
results = []
|
||||
def producer():
|
||||
results.append('prod')
|
||||
evt.send()
|
||||
|
||||
def consumer():
|
||||
results.append('cons1')
|
||||
evt.wait()
|
||||
results.append('cons2')
|
||||
|
||||
pool = pools.CoroutinePool(0, 2)
|
||||
done = pool.execute(consumer)
|
||||
pool.execute_async(producer)
|
||||
done.wait()
|
||||
self.assertEquals(['cons1', 'prod', 'cons2'], results)
|
||||
|
||||
def test_timer_cancel(self):
|
||||
timer_fired = []
|
||||
def fire_timer():
|
||||
timer_fired.append(True)
|
||||
def some_work():
|
||||
api.get_hub().schedule_call_local(0, fire_timer)
|
||||
pool = pools.CoroutinePool(0, 2)
|
||||
worker = pool.execute(some_work)
|
||||
worker.wait()
|
||||
api.sleep(0)
|
||||
self.assertEquals(timer_fired, [])
|
||||
|
||||
def test_reentrant(self):
|
||||
pool = pools.CoroutinePool(0,1)
|
||||
def reenter():
|
||||
waiter = pool.execute(lambda a: a, 'reenter')
|
||||
self.assertEqual('reenter', waiter.wait())
|
||||
|
||||
outer_waiter = pool.execute(reenter)
|
||||
outer_waiter.wait()
|
||||
|
||||
evt = coros.event()
|
||||
def reenter_async():
|
||||
pool.execute_async(lambda a: a, 'reenter')
|
||||
evt.send('done')
|
||||
|
||||
pool.execute_async(reenter_async)
|
||||
evt.wait()
|
||||
|
||||
def test_horrible_main_loop_death(self):
|
||||
# testing the case that causes the run_forever
|
||||
# method to exit unwantedly
|
||||
pool = pools.CoroutinePool(min_size=1, max_size=1)
|
||||
def crash(*args, **kw):
|
||||
raise RuntimeError("Whoa")
|
||||
class FakeFile(object):
|
||||
write = crash
|
||||
|
||||
# we're going to do this by causing the traceback.print_exc in
|
||||
# safe_apply to raise an exception and thus exit _main_loop
|
||||
normal_err = sys.stderr
|
||||
try:
|
||||
sys.stderr = FakeFile()
|
||||
waiter = pool.execute(crash)
|
||||
self.assertRaises(RuntimeError, waiter.wait)
|
||||
# the pool should have something free at this point since the
|
||||
# waiter returned
|
||||
self.assertEqual(pool.free(), 1)
|
||||
# shouldn't block when trying to get
|
||||
t = api.exc_after(0.1, api.TimeoutError)
|
||||
self.assert_(pool.get())
|
||||
t.cancel()
|
||||
finally:
|
||||
sys.stderr = normal_err
|
||||
|
||||
def test_track_events(self):
|
||||
pool = pools.CoroutinePool(track_events=True)
|
||||
for x in range(6):
|
||||
pool.execute(lambda n: n, x)
|
||||
for y in range(6):
|
||||
pool.wait()
|
||||
|
||||
def test_track_slow_event(self):
|
||||
pool = pools.CoroutinePool(track_events=True)
|
||||
def slow():
|
||||
api.sleep(0.1)
|
||||
return 'ok'
|
||||
pool.execute(slow)
|
||||
self.assertEquals(pool.wait(), 'ok')
|
||||
|
||||
def test_channel_smash(self):
|
||||
# The premise is that the coroutine in the pool exhibits an
|
||||
# interest in receiving data from the channel, but then times
|
||||
# out and gets recycled, so it ceases to care about what gets
|
||||
# sent over the channel. The pool should be able to tell the
|
||||
# channel about the sudden change of heart, or else, when we
|
||||
# eventually do send something into the channel it will catch
|
||||
# the coroutine pool's coroutine in an awkward place, losing
|
||||
# the data that we're sending.
|
||||
from eventlet import pools
|
||||
pool = pools.CoroutinePool(min_size=1, max_size=1)
|
||||
tp = pools.TokenPool(max_size=1)
|
||||
token = tp.get() # empty pool
|
||||
def do_receive(tp):
|
||||
api.exc_after(0, RuntimeError())
|
||||
try:
|
||||
t = tp.get()
|
||||
self.fail("Shouldn't have recieved anything from the pool")
|
||||
except RuntimeError:
|
||||
return 'timed out'
|
||||
|
||||
# the execute makes the pool expect that coroutine, but then
|
||||
# immediately cuts bait
|
||||
e1 = pool.execute(do_receive, tp)
|
||||
self.assertEquals(e1.wait(), 'timed out')
|
||||
|
||||
# the pool can get some random item back
|
||||
def send_wakeup(tp):
|
||||
tp.put('wakeup')
|
||||
api.spawn(send_wakeup, tp)
|
||||
|
||||
# now we ask the pool to run something else, which should not
|
||||
# be affected by the previous send at all
|
||||
def resume():
|
||||
return 'resumed'
|
||||
e2 = pool.execute(resume)
|
||||
self.assertEquals(e2.wait(), 'resumed')
|
||||
|
||||
# we should be able to get out the thing we put in there, too
|
||||
self.assertEquals(tp.get(), 'wakeup')
|
||||
|
||||
def test_channel_death(self):
|
||||
# In here, we have a coroutine trying to receive data from a
|
||||
# channel, but timing out immediately and dying. The channel
|
||||
# should be smart enough to not try to send data to a dead
|
||||
# coroutine, because if it tries to, it'll lose the data.
|
||||
from eventlet import pools
|
||||
tp = pools.TokenPool(max_size=1)
|
||||
token = tp.get()
|
||||
e1 = coros.event()
|
||||
def do_receive(evt, tp):
|
||||
api.exc_after(0, RuntimeError())
|
||||
try:
|
||||
t = tp.get()
|
||||
evt.send(t)
|
||||
except RuntimeError:
|
||||
evt.send('timed out')
|
||||
|
||||
# the execute gets the pool to add a waiter, but then kills
|
||||
# itself off
|
||||
api.spawn(do_receive, e1, tp)
|
||||
self.assertEquals(e1.wait(), 'timed out')
|
||||
|
||||
def send_wakeup(tp):
|
||||
tp.put('wakeup')
|
||||
api.spawn(send_wakeup, tp)
|
||||
|
||||
# should be able to retrieve the message
|
||||
self.assertEquals(tp.get(), 'wakeup')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
tests.main()
|
||||
|
||||
|
@@ -1,30 +1,27 @@
|
||||
"""\
|
||||
@file processes_test.py
|
||||
@author Donovan Preston, Aaron Brashears
|
||||
# @author Donovan Preston, Aaron Brashears
|
||||
#
|
||||
# Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
import sys
|
||||
|
||||
from greentest import tests
|
||||
from eventlet import api
|
||||
from eventlet import processes
|
||||
|
||||
class TestEchoPool(tests.TestCase):
|
||||
|
@@ -26,6 +26,7 @@ Usage: %prog program [args]
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
import codecs
|
||||
try:
|
||||
import sqlite3
|
||||
except ImportError:
|
||||
@@ -63,7 +64,7 @@ def main():
|
||||
print arg
|
||||
returncode = os.system(arg)>>8
|
||||
print arg, 'finished with code', returncode
|
||||
stdout = file(output_name).read()
|
||||
stdout = codecs.open(output_name, mode='r', encoding='utf-8', errors='replace').read().replace('\x00', '?')
|
||||
if not debug:
|
||||
if returncode==1:
|
||||
pass
|
||||
|
@@ -37,7 +37,7 @@ COMMAND = sys.executable + ' ./record_results.py ' + sys.executable + ' ./with_t
|
||||
PARSE_PERIOD = 10
|
||||
|
||||
# the following aren't in the default list unless --all option present
|
||||
NOT_HUBS = set(['nginx'])
|
||||
NOT_HUBS = set()
|
||||
NOT_REACTORS = set(['wxreactor', 'glib2reactor', 'gtk2reactor'])
|
||||
NOT_TESTS = set()
|
||||
|
||||
|
@@ -1,4 +1,3 @@
|
||||
import sys
|
||||
from eventlet import pool, coros, api
|
||||
from greentest import LimitedTestCase
|
||||
from unittest import main
|
||||
|
@@ -20,7 +20,7 @@
|
||||
# THE SOFTWARE.
|
||||
|
||||
from twisted.internet import reactor
|
||||
from greentest import exit_unless_twisted, LimitedTestCase
|
||||
from greentest import exit_unless_twisted
|
||||
exit_unless_twisted()
|
||||
|
||||
import unittest
|
||||
@@ -188,53 +188,6 @@ class TestGreenTransport_bufsize1(TestGreenTransport):
|
||||
# self.assertEqual('', self.conn.recv())
|
||||
#
|
||||
|
||||
# class TestHalfClose_TCP(LimitedTestCase):
|
||||
#
|
||||
# def _test_server(self, conn):
|
||||
# conn.write('hello')
|
||||
# conn.loseWriteConnection()
|
||||
# self.assertRaises(pr.ConnectionDone, conn.write, 'hey')
|
||||
# data = conn.read()
|
||||
# self.assertEqual('bye', data)
|
||||
# conn.loseConnection()
|
||||
# self.assertRaises(ConnectionDone, conn._wait)
|
||||
# self.check.append('server')
|
||||
#
|
||||
# def setUp(self):
|
||||
# LimitedTestCase.setUp(self)
|
||||
# self.factory = pr.SpawnFactory(self._test_server)
|
||||
# self.port = reactor.listenTCP(0, self.factory)
|
||||
# self.conn = pr.GreenClientCreator(reactor).connectTCP('localhost', self.port.getHost().port)
|
||||
# self.port.stopListening()
|
||||
# self.check = []
|
||||
#
|
||||
# def test(self):
|
||||
# conn = self.conn
|
||||
# data = conn.read()
|
||||
# self.assertEqual('hello', data)
|
||||
# conn.write('bye')
|
||||
# conn.loseWriteConnection()
|
||||
# self.assertRaises(pr.ConnectionDone, conn.write, 'hoy')
|
||||
# self.factory.waitall()
|
||||
# self.assertRaises(ConnectionDone, conn._wait)
|
||||
# assert self.check == ['server']
|
||||
#
|
||||
# class TestHalfClose_TLS(TestHalfClose_TCP):
|
||||
#
|
||||
# def setUp(self):
|
||||
# LimitedTestCase.setUp(self)
|
||||
# from gnutls.crypto import X509PrivateKey, X509Certificate
|
||||
# from gnutls.interfaces.twisted import X509Credentials
|
||||
# cert = X509Certificate(open('gnutls_valid.crt').read())
|
||||
# key = X509PrivateKey(open('gnutls_valid.key').read())
|
||||
# server_credentials = X509Credentials(cert, key)
|
||||
# self.factory = pr.SpawnFactory(self._test_server)
|
||||
# self.port = reactor.listenTLS(0, self.factory, server_credentials)
|
||||
# self.conn = pr.GreenClientCreator(reactor).connectTLS('localhost', self.port.getHost().port, X509Credentials())
|
||||
# self.port.stopListening()
|
||||
# self.check = []
|
||||
#
|
||||
|
||||
if socket is not None:
|
||||
|
||||
class TestUnbufferedTransport_socketserver(TestUnbufferedTransport):
|
||||
@@ -275,7 +228,6 @@ try:
|
||||
import gnutls.interfaces.twisted
|
||||
except ImportError:
|
||||
del TestTLSError
|
||||
del TestHalfClose_TLS
|
||||
|
||||
if __name__=='__main__':
|
||||
unittest.main()
|
||||
|
@@ -1,27 +1,24 @@
|
||||
"""\
|
||||
@file tests.py
|
||||
@author Donovan Preston
|
||||
@brief Indirection layer for tests in case we want to fix unittest.
|
||||
|
||||
Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# @author Donovan Preston
|
||||
# @brief Indirection layer for tests in case we want to fix unittest.
|
||||
#
|
||||
# Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import errno
|
||||
import os
|
||||
@@ -44,24 +41,24 @@ def find_command(command):
|
||||
if os.access(p, os.X_OK):
|
||||
return p
|
||||
raise IOError(errno.ENOENT, 'Command not found: %r' % command)
|
||||
|
||||
|
||||
def run_all_tests(test_files = doc_test_files):
|
||||
""" Runs all the unit tests, returning immediately after the
|
||||
""" Runs all the unit tests, returning immediately after the
|
||||
first failed test.
|
||||
|
||||
|
||||
Returns true if the tests all succeeded. This method is really much longer
|
||||
than it ought to be.
|
||||
"""
|
||||
eventlet_dir = os.path.realpath(os.path.dirname(__file__))
|
||||
if eventlet_dir not in sys.path:
|
||||
sys.path.append(eventlet_dir)
|
||||
|
||||
|
||||
# add all _test files as a policy
|
||||
import glob
|
||||
test_files += [os.path.splitext(os.path.basename(x))[0]
|
||||
test_files += [os.path.splitext(os.path.basename(x))[0]
|
||||
for x in glob.glob(os.path.join(eventlet_dir, "*_test.py"))]
|
||||
test_files.sort()
|
||||
|
||||
|
||||
for test_file in test_files:
|
||||
print "-=", test_file, "=-"
|
||||
try:
|
||||
@@ -69,21 +66,21 @@ def run_all_tests(test_files = doc_test_files):
|
||||
except ImportError:
|
||||
print "Unable to import %s, skipping" % test_file
|
||||
continue
|
||||
|
||||
|
||||
if test_file.endswith('_test'):
|
||||
# gawd, unittest, why you make it so difficult to just run some tests!
|
||||
suite = unittest.findTestCases(test_module)
|
||||
result = unittest.TextTestRunner().run(suite)
|
||||
if not result.wasSuccessful():
|
||||
return False
|
||||
else:
|
||||
else:
|
||||
failures, tests = doctest.testmod(test_module)
|
||||
if failures:
|
||||
return False
|
||||
else:
|
||||
print "OK"
|
||||
|
||||
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run_all_tests()
|
||||
|
@@ -1,26 +1,23 @@
|
||||
"""\
|
||||
@file timer_test.py
|
||||
@author Donovan Preston
|
||||
|
||||
Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
# @author Donovan Preston
|
||||
#
|
||||
# Copyright (c) 2006-2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import unittest
|
||||
|
||||
|
@@ -1,27 +1,22 @@
|
||||
"""\
|
||||
@file tpool_test.py
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Copyright (c) 2007, IBM Corp.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Copyright (c) 2007, IBM Corp.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
import os, socket, time, threading
|
||||
import time
|
||||
from eventlet import coros, api, tpool
|
||||
from greentest import tests
|
||||
|
||||
from eventlet.tpool import erpc
|
||||
from sys import stdout
|
||||
|
||||
import random
|
||||
|
@@ -1,26 +1,24 @@
|
||||
"""\
|
||||
@file wsgi_test.py
|
||||
@author Donovan Preston
|
||||
# @author Donovan Preston
|
||||
#
|
||||
# Copyright (c) 2007, Linden Research, Inc.
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
Copyright (c) 2007, Linden Research, Inc.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
import cgi
|
||||
import os
|
||||
@@ -28,7 +26,6 @@ import os
|
||||
from eventlet import api
|
||||
from eventlet import wsgi
|
||||
from eventlet import processes
|
||||
from eventlet import util
|
||||
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
@@ -43,7 +40,7 @@ def hello_world(env, start_response):
|
||||
if env['PATH_INFO'] == 'notexist':
|
||||
start_response('404 Not Found', [('Content-type', 'text/plain')])
|
||||
return ["not found"]
|
||||
|
||||
|
||||
start_response('200 OK', [('Content-type', 'text/plain')])
|
||||
return ["hello world"]
|
||||
|
||||
@@ -123,7 +120,7 @@ class TestHttpd(tests.TestCase):
|
||||
def test_001_server(self):
|
||||
sock = api.connect_tcp(
|
||||
('127.0.0.1', 12346))
|
||||
|
||||
|
||||
fd = sock.makeGreenFile()
|
||||
fd.write('GET / HTTP/1.0\r\nHost: localhost\r\n\r\n')
|
||||
result = fd.read()
|
||||
@@ -135,7 +132,7 @@ class TestHttpd(tests.TestCase):
|
||||
def test_002_keepalive(self):
|
||||
sock = api.connect_tcp(
|
||||
('127.0.0.1', 12346))
|
||||
|
||||
|
||||
fd = sock.makeGreenFile()
|
||||
fd.write('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n')
|
||||
read_http(sock)
|
||||
@@ -147,7 +144,7 @@ class TestHttpd(tests.TestCase):
|
||||
# This should go in greenio_test
|
||||
sock = api.connect_tcp(
|
||||
('127.0.0.1', 12346))
|
||||
|
||||
|
||||
fd = sock.makeGreenFile()
|
||||
fd.write('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n')
|
||||
cancel = api.exc_after(1, RuntimeError)
|
||||
@@ -189,7 +186,7 @@ class TestHttpd(tests.TestCase):
|
||||
status = result.split(' ')[1]
|
||||
self.assertEqual(status, '414')
|
||||
fd.close()
|
||||
|
||||
|
||||
def test_007_get_arg(self):
|
||||
# define a new handler that does a get_arg as well as a read_body
|
||||
def new_app(env, start_response):
|
||||
@@ -201,24 +198,24 @@ class TestHttpd(tests.TestCase):
|
||||
sock = api.connect_tcp(
|
||||
('127.0.0.1', 12346))
|
||||
request = '\r\n'.join((
|
||||
'POST / HTTP/1.0',
|
||||
'Host: localhost',
|
||||
'Content-Length: 3',
|
||||
'POST / HTTP/1.0',
|
||||
'Host: localhost',
|
||||
'Content-Length: 3',
|
||||
'',
|
||||
'a=a'))
|
||||
fd = sock.makeGreenFile()
|
||||
fd.write(request)
|
||||
|
||||
|
||||
# send some junk after the actual request
|
||||
fd.write('01234567890123456789')
|
||||
reqline, headers, body = read_http(sock)
|
||||
self.assertEqual(body, 'a is a, body is a=a')
|
||||
fd.close()
|
||||
|
||||
|
||||
def test_008_correctresponse(self):
|
||||
sock = api.connect_tcp(
|
||||
('127.0.0.1', 12346))
|
||||
|
||||
|
||||
fd = sock.makeGreenFile()
|
||||
fd.write('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n')
|
||||
response_line_200,_,_ = read_http(sock)
|
||||
@@ -233,7 +230,7 @@ class TestHttpd(tests.TestCase):
|
||||
self.site.application = chunked_app
|
||||
sock = api.connect_tcp(
|
||||
('127.0.0.1', 12346))
|
||||
|
||||
|
||||
fd = sock.makeGreenFile()
|
||||
fd.write('GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n')
|
||||
self.assert_('Transfer-Encoding: chunked' in fd.read())
|
||||
@@ -242,7 +239,7 @@ class TestHttpd(tests.TestCase):
|
||||
self.site.application = chunked_app
|
||||
sock = api.connect_tcp(
|
||||
('127.0.0.1', 12346))
|
||||
|
||||
|
||||
fd = sock.makeGreenFile()
|
||||
fd.write('GET / HTTP/1.0\r\nHost: localhost\r\nConnection: close\r\n\r\n')
|
||||
self.assert_('Transfer-Encoding: chunked' not in fd.read())
|
||||
@@ -251,7 +248,7 @@ class TestHttpd(tests.TestCase):
|
||||
self.site.application = big_chunks
|
||||
sock = api.connect_tcp(
|
||||
('127.0.0.1', 12346))
|
||||
|
||||
|
||||
fd = sock.makeGreenFile()
|
||||
fd.write('GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n')
|
||||
headers = fd.readuntil('\r\n\r\n')
|
||||
@@ -273,9 +270,9 @@ class TestHttpd(tests.TestCase):
|
||||
|
||||
certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt')
|
||||
private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key')
|
||||
|
||||
|
||||
sock = api.ssl_listener(('', 4201), certificate_file, private_key_file)
|
||||
|
||||
|
||||
api.spawn(wsgi.server, sock, wsgi_app)
|
||||
|
||||
result = httpc.post("https://localhost:4201/foo", "abc")
|
||||
@@ -295,6 +292,20 @@ class TestHttpd(tests.TestCase):
|
||||
res = httpc.get("https://localhost:4202/foo")
|
||||
self.assertEquals(res, '')
|
||||
|
||||
def test_013_empty_return(self):
|
||||
from eventlet import httpc
|
||||
def wsgi_app(environ, start_response):
|
||||
start_response("200 OK", [])
|
||||
return [""]
|
||||
|
||||
certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt')
|
||||
private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key')
|
||||
sock = api.ssl_listener(('', 4202), certificate_file, private_key_file)
|
||||
api.spawn(wsgi.server, sock, wsgi_app)
|
||||
|
||||
res = httpc.get("https://localhost:4202/foo")
|
||||
self.assertEquals(res, '')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
tests.main()
|
||||
|
Reference in New Issue
Block a user