Source code for swiftly.concurrency

"""
Concurrency API for Swiftly.

Copyright 2011-2013 Gregory Holt

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.
"""

__all__ = ['Concurrency']

import sys
import Queue

try:
    from eventlet import GreenPool, Timeout
except ImportError:
    GreenPool = None
    Timeout = None


[docs]class Concurrency(object): """ Convenience class to support concurrency, if Eventlet is available; otherwise it just performs at single concurrency. :param concurrency: The level of concurrency desired. Default: 10 """ def __init__(self, concurrency=10): self.concurrency = concurrency if self.concurrency and GreenPool: self._pool = GreenPool(self.concurrency) else: self._pool = None self._queue = Queue.Queue() self._results = {} def _spawner(self, ident, func, *args, **kwargs): exc_type = exc_value = exc_tb = result = None try: result = func(*args, **kwargs) except (Exception, Timeout): exc_type, exc_value, exc_tb = sys.exc_info() self._queue.put((ident, (exc_type, exc_value, exc_tb, result)))
[docs] def spawn(self, ident, func, *args, **kwargs): """ Returns immediately to the caller and begins executing the func in the background. Use get_results and the ident given to retrieve the results of the func. If the func causes an exception, this exception will be caught and the sys.exc_info() will be returned via get_results. :param ident: An identifier to find the results of the func from get_results. This identifier can be anything unique to the Concurrency instance. :param func: The function to execute concurrently. :param args: The args to give the func. :param kwargs: The keyword args to the give the func. :returns: None """ if self._pool: self._pool.spawn_n(self._spawner, ident, func, *args, **kwargs) else: self._spawner(ident, func, *args, **kwargs)
[docs] def get_results(self): """ Returns a dict of the results currently available. The keys are the ident values given with the calls to spawn. The values are tuples of (exc_type, exc_value, exc_tb, result) where: ========= ============================================ exc_type The type of any exception raised. exc_value The actual exception if any was raised. exc_tb The traceback if any exception was raised. result If no exception was raised, this will be the return value of the called function. ========= ============================================ """ try: while True: ident, value = self._queue.get(block=False) self._results[ident] = value except Queue.Empty: pass return self._results
[docs] def join(self): """ Blocks until all currently pending functions have finished. """ if self._pool: self._pool.waitall()