3
ñ\ð]²  ã               @   sV   d dl Z d dlZyd dlZW n ek
r4   dZY nX ddlmZ G dd„ deƒZdS )é    Né   )ÚPubSubManagerc                   sj   e Zd ZdZdZd‡ fdd„	Z‡ fd	d
„Zdd„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Z‡  ZS )ÚKombuManagera  Client manager that uses kombu for inter-process messaging.

    This class implements a client manager backend for event sharing across
    multiple processes, using RabbitMQ, Redis or any other messaging mechanism
    supported by `kombu <http://kombu.readthedocs.org/en/latest/>`_.

    To use a kombu backend, initialize the :class:`Server` instance as
    follows::

        url = 'amqp://user:password@hostname:port//'
        server = socketio.Server(client_manager=socketio.KombuManager(url))

    :param url: The connection URL for the backend messaging queue. Example
                connection URLs are ``'amqp://guest:guest@localhost:5672//'``
                and ``'redis://localhost:6379/'`` for RabbitMQ and Redis
                respectively. Consult the `kombu documentation
                <http://kombu.readthedocs.org/en/latest/userguide                /connections.html#urls>`_ for more on how to construct
                connection URLs.
    :param channel: The channel name on which the server sends and receives
                    notifications. Must be the same in all the servers.
    :param write_only: If set ot ``True``, only initialize to emit events. The
                       default of ``False`` initializes the class for emitting
                       and receiving.
    :param connection_options: additional keyword arguments to be passed to
                               ``kombu.Connection()``.
    :param exchange_options: additional keyword arguments to be passed to
                             ``kombu.Exchange()``.
    :param queue_options: additional keyword arguments to be passed to
                          ``kombu.Queue()``.
    :param producer_options: additional keyword arguments to be passed to
                             ``kombu.Producer()``.
    Úkombuú#amqp://guest:guest@localhost:5672//ÚsocketioFNc	       	         sb   t d krtdƒ‚tt| ƒj|||d� || _|p2i | _|p<i | _|pFi | _|pPi | _	| j
ƒ | _d S )NzLKombu package is not installed (Run "pip install kombu" in your virtualenv).)ÚchannelÚ
write_onlyÚlogger)r   ÚRuntimeErrorÚsuperr   Ú__init__ÚurlÚconnection_optionsÚexchange_optionsÚqueue_optionsÚproducer_optionsÚ	_producerÚproducer)	Úselfr   r   r	   r
   r   r   r   r   )Ú	__class__© úA/tmp/pip-build-mqc4i71p/python-socketio/socketio/kombu_manager.pyr   0   s    



zKombuManager.__init__c                sl   t t| ƒjƒ  d}| jjdkr4ddlm} |dƒ}n d| jjkrTddlm} |dƒ}|sht	d| jj ƒ‚d S )	NTZeventletr   )Úis_monkey_patchedÚsocketZgevent)Úis_module_patchedz<Kombu requires a monkey patched socket library to work with )
r   r   Ú
initializeÚserverZ
async_modeZeventlet.patcherr   Zgevent.monkeyr   r   )r   Zmonkey_patchedr   r   )r   r   r   r   B   s    
zKombuManager.initializec             C   s   t j| jf| jŽS )N)r   Ú
Connectionr   r   )r   r   r   r   Ú_connectionQ   s    zKombuManager._connectionc             C   s&   dddœ}|j | jƒ tj| jf|ŽS )NZfanoutF)ÚtypeÚdurable)Úupdater   r   ZExchanger   )r   Úoptionsr   r   r   Ú	_exchangeT   s    
zKombuManager._exchangec             C   s>   dt tjƒ ƒ }dddidœ}|j| jƒ tj|| jƒ f|ŽS )Nzflask-socketio.Fz	x-expiresià“ )r!   Zqueue_arguments)ÚstrÚuuidÚuuid4r"   r   r   ÚQueuer$   )r   Z
queue_namer#   r   r   r   Ú_queueY   s    zKombuManager._queuec             C   s   | j ƒ jf d| jƒ i| j—ŽS )NZexchange)r   ZProducerr$   r   )r   r   r   r   r   _   s    zKombuManager._producerc             C   s   | j ƒ jdj|ƒƒ d S )NzSleeping {}s)Ú_get_loggerÚ	exceptionÚformat)r   r+   Úintervalr   r   r   Z__error_callbackc   s    zKombuManager.__error_callbackc             C   s2   | j ƒ }|j| j| jj| jd�}|tj|ƒƒ d S )N)Úerrback)r   Zensurer   ÚpublishÚ_KombuManager__error_callbackÚpickleÚdumps)r   ÚdataÚ
connectionr/   r   r   r   Ú_publishf   s    
zKombuManager._publishc             c   s†   | j ƒ }xx| jƒ j| jd�}y<|j|ƒ�(}x |jdd�}|jƒ  |jV  q,W W d Q R X W q
 |jk
r|   | j	ƒ j
dƒ Y q
X q
W d S )N)r.   T)Úblockz)Connection error while reading from queue)r)   r   Zensure_connectionr0   ZSimpleQueueÚgetZackÚpayloadZconnection_errorsr*   r+   )r   Zreader_queuer4   ÚqueueÚmessager   r   r   Ú_listenl   s    
zKombuManager._listen)r   r   FNNNNN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Únamer   r   r   r$   r)   r   r0   r5   r;   Ú__classcell__r   r   )r   r   r      s   !   r   )r1   r&   r   ÚImportErrorZpubsub_managerr   r   r   r   r   r   Ú<module>   s   
