3
Z_ð]›  ã               @   sh   d dl mZ d dlZd dlmZ d dlmZ ddgZG dd„ deƒZ	G dd	„ d	eƒZ
G d
d„ de	ƒZdS )é    )Úprint_functionN)Úcontextmanager)ÚqueueÚPoolÚ	TokenPoolc               @   sV   e Zd ZdZddd„Zdd	„ Zed
d„ ƒZdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ ZdS )r   a  
    Pool class implements resource limitation and construction.

    There are two ways of using Pool: passing a `create` argument or
    subclassing. In either case you must provide a way to create
    the resource.

    When using `create` argument, pass a function with no arguments::

        http_pool = pools.Pool(create=httplib2.Http)

    If you need to pass arguments, build a nullary function with either
    `lambda` expression::

        http_pool = pools.Pool(create=lambda: httplib2.Http(timeout=90))

    or :func:`functools.partial`::

        from functools import partial
        http_pool = pools.Pool(create=partial(httplib2.Http, timeout=90))

    When subclassing, define only the :meth:`create` method
    to implement the desired resource::

        class MyPool(pools.Pool):
            def create(self):
                return MyObject()

    If using 2.5 or greater, the :meth:`item` method acts as a context manager;
    that's the best way to use it::

        with mypool.item() as thing:
            thing.dostuff()

    The maximum size of the pool can be modified at runtime via
    the :meth:`resize` method.

    Specifying a non-zero *min-size* argument pre-populates the pool with
    *min_size* items.  *max-size* sets a hard limit to the size of the pool --
    it cannot contain any more items than *max_size*, and if there are already
    *max_size* items 'checked out' of the pool, the pool will cause any
    greenthread calling :meth:`get` to cooperatively yield until an item
    is :meth:`put` in.
    r   é   FNc             C   sp   || _ || _|| _d| _tjdƒ| _tjƒ | _	|dk	r<|| _
x.t|ƒD ]"}|  jd7  _| j	j| j
ƒ ƒ qFW dS )a§  *order_as_stack* governs the ordering of the items in the free pool.
        If ``False`` (the default), the free items collection (of items that
        were created and were put back in the pool) acts as a round-robin,
        giving each item approximately equal utilization.  If ``True``, the
        free pool acts as a FILO stack, which preferentially re-uses items that
        have most recently been used.
        r   Né   )Úmin_sizeÚmax_sizeÚorder_as_stackÚcurrent_sizer   Z
LightQueueÚchannelÚcollectionsÚdequeÚ
free_itemsÚcreateÚrangeÚappend)Úselfr	   r
   r   r   Úx© r   ú2/tmp/pip-build-yz_zf6az/eventlet/eventlet/pools.pyÚ__init__:   s    
zPool.__init__c          	   C   sp   | j r| j jƒ S |  jd7  _| j| jkrXy| jƒ }W n   |  jd8  _‚ Y nX |S |  jd8  _| jjƒ S )zwReturn an item from the pool, when one is available.  This may
        cause the calling greenthread to block.
        r   )r   Úpopleftr   r
   r   r   Úget)r   Úcreatedr   r   r   r   O   s    
zPool.getc             c   s$   | j ƒ }z
|V  W d| j|ƒ X dS )a$   Get an object out of the pool, for use with with statement.

        >>> from eventlet import pools
        >>> pool = pools.TokenPool(max_size=4)
        >>> with pool.item() as obj:
        ...     print("got token")
        ...
        got token
        >>> pool.free()
        4
        N)r   Úput)r   Úobjr   r   r   Úitem`   s    
z	Pool.itemc             C   sv   | j | jkr|  j d8  _ dS | jƒ rRy| jj|dd� dS  tjk
rP   Y nX | jrf| jj	|ƒ n| jj
|ƒ dS )zmPut an item back into the pool, when done.  This may
        cause the putting greenthread to block.
        r   NF)Úblock)r   r
   Úwaitingr   r   r   ÚFullr   r   Ú
appendleftr   )r   r   r   r   r   r   s   s    zPool.putc             C   s
   || _ dS )ay  Resize the pool to *new_size*.

        Adjusting this number does not affect existing items checked out of
        the pool, nor on any greenthreads who are waiting for an item to free
        up.  Some indeterminate number of :meth:`get`/:meth:`put`
        cycles will be necessary before the new maximum size truly matches
        the actual operation of the pool.
        N)r
   )r   Znew_sizer   r   r   Úresize‡   s    	zPool.resizec             C   s   t | jƒ| j | j S )zŒReturn the number of free items in the pool.  This corresponds
        to the number of :meth:`get` calls needed to empty the pool.
        )Úlenr   r
   r   )r   r   r   r   Úfree’   s    z	Pool.freec             C   s   t d| jjƒ | jjƒ  ƒS )z?Return the number of routines waiting for a pool item.
        r   )Úmaxr   ZgettingZputting)r   r   r   r   r    ˜   s    zPool.waitingc             C   s   t dƒ‚dS )a%  Generate a new pool item.  In order for the pool to
        function, either this method must be overriden in a subclass
        or the pool must be constructed with the `create` argument.
        It accepts no arguments and returns a single instance of
        whatever thing the pool is supposed to contain.

        In general, :meth:`create` is called whenever the pool exceeds its
        previous high-water mark of concurrently-checked-out-items.  In other
        words, in a new pool with *min_size* of 0, the very first call
        to :meth:`get` will result in a call to :meth:`create`.  If the first
        caller calls :meth:`put` before some other caller calls :meth:`get`,
        then the first item will be returned, and :meth:`create` will not be
        called a second time.
        zImplement in subclassN)ÚNotImplementedError)r   r   r   r   r   �   s    zPool.create)r   r   FN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r#   r%   r    r   r   r   r   r   r      s   ,
c               @   s   e Zd ZdS )ÚTokenN)r(   r)   r*   r   r   r   r   r,   ¯   s   r,   c               @   s   e Zd ZdZdd„ ZdS )r   z©A pool which gives out tokens (opaque unique objects), which indicate
    that the coroutine which holds the token has a right to consume some
    limited resource.
    c             C   s   t ƒ S )N)r,   )r   r   r   r   r   ¹   s    zTokenPool.createN)r(   r)   r*   r+   r   r   r   r   r   r   ³   s   )Ú
__future__r   r   Ú
contextlibr   Zeventletr   Ú__all__Úobjectr   r,   r   r   r   r   r   Ú<module>   s    $