<s> '''<STR_LIT>''' <EOL> from collections import deque <EOL> class ChannelPool ( object ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , connection , size = None ) : <EOL> '''<STR_LIT>''' <EOL> self . _connection = connection <EOL> self . _free_channels = set ( ) <EOL> self . _size = size <EOL> self . _queue = deque ( ) <EOL> self . _channels = <NUM_LIT:0> <EOL> def publish ( self , * args , ** kwargs ) : <EOL> '''<STR_LIT>''' <EOL> user_cb = kwargs . pop ( '<STR_LIT>' , None ) <EOL> channel = self . _get_channel ( ) <EOL> if channel and not channel . active : <EOL> inactive_channels = set ( ) <EOL> while channel and not channel . active : <EOL> inactive_channels . add ( channel ) <EOL> channel = self . _get_channel ( ) <EOL> self . _free_channels . update ( inactive_channels ) <EOL> def committed ( ) : <EOL> self . _free_channels . add ( channel ) <EOL> if channel . active and not channel . closed : <EOL> self . _process_queue ( ) <EOL> if user_cb is not None : <EOL> user_cb ( ) <EOL> if channel : <EOL> channel . publish_synchronous ( * args , cb = committed , ** kwargs ) <EOL> else : <EOL> kwargs [ '<STR_LIT>' ] = user_cb <EOL> self . _queue . append ( ( args , kwargs ) ) <EOL> def _process_queue ( self ) : <EOL> '''<STR_LIT>''' <EOL> if len ( self . _queue ) : <EOL> args , kwargs = self . _queue . popleft ( ) <EOL> self . publish ( * args , ** kwargs ) <EOL> def _get_channel ( self ) : <EOL> '''<STR_LIT>''' <EOL> while len ( self . _free_channels ) : <EOL> rval = self . _free_channels . pop ( ) <EOL> if not rval . closed : <EOL> return rval <EOL> if not self . _size or self . _channels < self . _size : <EOL> rval = self . _connection . channel ( ) <EOL> self . _channels += <NUM_LIT:1> <EOL> rval . add_close_listener ( self . _channel_closed_cb ) <EOL> return rval <EOL> def _channel_closed_cb ( self , channel ) : <EOL> '''<STR_LIT>''' <EOL> self . _channels -= <NUM_LIT:1> <EOL> self . _process_queue ( ) </s>
