U
    Z+d<                     @   s  d Z ddlZddlZddlZddlmZ ddlZddlmZ ddl	m
Z
 ddlmZmZmZ ddlmZmZ ddlmZmZmZ dd	lmZ dd
lmZ dZdZdd Zdd Zdd Zdd ZG dd dZ G dd de Z!ej"eddddej#edd Z$dS )a  Start multiple worker instances from the command-line.

.. program:: celery multi

Examples
========

.. code-block:: console

    $ # Single worker with explicit name and events enabled.
    $ celery multi start Leslie -E

    $ # Pidfiles and logfiles are stored in the current directory
    $ # by default.  Use --pidfile and --logfile argument to change
    $ # this.  The abbreviation %n will be expanded to the current
    $ # node name.
    $ celery multi start Leslie -E --pidfile=/var/run/celery/%n.pid
                                   --logfile=/var/log/celery/%n%I.log


    $ # You need to add the same arguments when you restart,
    $ # as these aren't persisted anywhere.
    $ celery multi restart Leslie -E --pidfile=/var/run/celery/%n.pid
                                     --logfile=/var/log/celery/%n%I.log

    $ # To stop the node, you need to specify the same pidfile.
    $ celery multi stop Leslie --pidfile=/var/run/celery/%n.pid

    $ # 3 workers, with 3 processes each
    $ celery multi start 3 -c 3
    celery worker -n celery1@myhost -c 3
    celery worker -n celery2@myhost -c 3
    celery worker -n celery3@myhost -c 3

    $ # override name prefix when using range
    $ celery multi start 3 --range-prefix=worker -c 3
    celery worker -n worker1@myhost -c 3
    celery worker -n worker2@myhost -c 3
    celery worker -n worker3@myhost -c 3

    $ # start 3 named workers
    $ celery multi start image video data -c 3
    celery worker -n image@myhost -c 3
    celery worker -n video@myhost -c 3
    celery worker -n data@myhost -c 3

    $ # specify custom hostname
    $ celery multi start 2 --hostname=worker.example.com -c 3
    celery worker -n celery1@worker.example.com -c 3
    celery worker -n celery2@worker.example.com -c 3

    $ # specify fully qualified nodenames
    $ celery multi start foo@worker.example.com bar@worker.example.com -c 3

    $ # fully qualified nodenames but using the current hostname
    $ celery multi start foo@%h bar@%h

    $ # Advanced example starting 10 workers in the background:
    $ #   * Three of the workers processes the images and video queue
    $ #   * Two of the workers processes the data queue with loglevel DEBUG
    $ #   * the rest processes the default' queue.
    $ celery multi start 10 -l INFO -Q:1-3 images,video -Q:4,5 data
        -Q default -L:4,5 DEBUG

    $ # You can show the commands necessary to start the workers with
    $ # the 'show' command:
    $ celery multi show 10 -l INFO -Q:1-3 images,video -Q:4,5 data
        -Q default -L:4,5 DEBUG

    $ # Additional options are added to each celery worker's command,
    $ # but you can also modify the options for ranges of, or specific workers

    $ # 3 workers: Two with 3 processes, and one with 10 processes.
    $ celery multi start 3 -c 3 -c:1 10
    celery worker -n celery1@myhost -c 10
    celery worker -n celery2@myhost -c 3
    celery worker -n celery3@myhost -c 3

    $ # can also specify options for named workers
    $ celery multi start image video data -c 3 -c:image 10
    celery worker -n image@myhost -c 10
    celery worker -n video@myhost -c 3
    celery worker -n data@myhost -c 3

    $ # ranges and lists of workers in options is also allowed:
    $ # (-c:1-3 can also be written as -c:1,2,3)
    $ celery multi start 5 -c 3  -c:1-3 10
    celery worker -n celery1@myhost -c 10
    celery worker -n celery2@myhost -c 10
    celery worker -n celery3@myhost -c 10
    celery worker -n celery4@myhost -c 3
    celery worker -n celery5@myhost -c 3

    $ # lists also works with named workers
    $ celery multi start foo bar baz xuzzy -c 3 -c:foo,bar,baz 10
    celery worker -n foo@myhost -c 10
    celery worker -n bar@myhost -c 10
    celery worker -n baz@myhost -c 10
    celery worker -n xuzzy@myhost -c 3
    Nwraps)cached_property)VERSION_BANNER)ClusterMultiParserNamespacedOptionParser)CeleryCommandhandle_preload_options)
EX_FAILUREEX_OKsignals)term)	pluralize)	MultiToola  usage: {prog_name} start <node1 node2 nodeN|range> [worker options]
       {prog_name} stop <n1 n2 nN|range> [-SIG (default: -TERM)]
       {prog_name} restart <n1 n2 nN|range> [-SIG] [worker options]
       {prog_name} kill <n1 n2 nN|range>

       {prog_name} show <n1 n2 nN|range> [worker options]
       {prog_name} get hostname <n1 n2 nN|range> [-qv] [worker options]
       {prog_name} names <n1 n2 nN|range>
       {prog_name} expand template <n1 n2 nN|range>
       {prog_name} help

additional options (must appear after command name):

    * --nosplash:   Don't display program info.
    * --quiet:      Don't show as much output.
    * --verbose:    Show more output.
    * --no-color:   Don't display colors.
c                   C   s   t t t j d S N)sysexitr   execute_from_commandlineargv r   r   4/tmp/pip-unpacked-wheel-ucduq0nd/celery/bin/multi.pymain   s    r   c                    s   t   fdd}|S )Nc                    s   |     | f||S r   )splash)selfargskwargsfunr   r   _inner   s    zsplash.<locals>._innerr   r   r   r   r   r   r      s    r   c                    s   t   fdd}|S )Nc                    s    | |  |f|S r   )cluster_from_argv)r   r   r   r   r   r   r      s    zusing_cluster.<locals>._innerr   r    r   r   r   using_cluster   s    r"   c                    s   t   fdd}|S )Nc                    s(   |  |\}}| |} | ||f|S r   )_cluster_from_argv_find_sig_argument)r   r   r   pclustersigr   r   r   r      s    
z%using_cluster_and_sig.<locals>._innerr   r    r   r   r   using_cluster_and_sig   s    r(   c                   @   s   e Zd ZdZdeiZdZdddZdd	d
ZdddZ	dddZ
dddZd ddZd!ddZedd Zdd Zedd ZdS )"
TermLoggerzcelery multi v{version}versionr   Fc                 K   s4   |pt j| _|pt j| _|| _|| _|| _|| _d S r   )r   stdoutstderrnosplashquietverboseno_color)r   r+   r,   r-   r.   r/   r0   r   r   r   r   setup_terminal   s    zTermLogger.setup_terminalTNc                 C   s   | j |||d tS )N)newlinefile)sayr   r   mr2   r3   r   r   r   ok   s    zTermLogger.okc                 C   s    t ||p| j|rdndd d S )N
 )r3   end)printr+   r5   r   r   r   r4      s    zTermLogger.sayc                 C   s   |  |||p| jS r   )r4   r,   r5   r   r   r   carp   s    zTermLogger.carpc                 C   s   |r|  | |   tS r   )r<   usager   )r   msgr   r   r   error   s    
zTermLogger.errorc                 C   s   | j r| j||d d S Nr2   )r/   noter   r>   r2   r   r   r   info   s    zTermLogger.infoc                 C   s   | j s| jt||d d S r@   )r.   r4   strrC   r   r   r   rB      s    zTermLogger.notec                 C   s   |  tj| jd d S )N)	prog_name)r4   USAGEformatrF   r   r   r   r   r=      s    zTermLogger.usagec                 C   s(   | j s$| | j| jjf | j d S r   )r-   rB   coloredZcyansplash_textrH   splash_contextrI   r   r   r   r      s    
zTermLogger.splashc                 C   s   t j| j dS )N)Zenabled)r   rJ   r0   rI   r   r   r   rJ      s    zTermLogger.colored)FFFF)TN)TN)TN)N)T)T)__name__
__module____qualname__rK   r   rL   retcoder1   r7   r4   r<   r?   rD   rB   r   r=   r   rJ   r   r   r   r   r)      s&         








r)   c                   @   s  e Zd ZdZeZeZdddddgZdTdd	ZdUd
dZ	dd Z
dd Zdd Zeedd Zeedd Zeedd ZeZeedd Zedd Zdd Zedd Zeed d! Zd"d# Zd$d% Zejfd&d'ZdVd(d)ZdWd*d+ZdXd,d-Z dYd.d/Z!d0d1 Z"d2d3 Z#d4d5 Z$d6d7 Z%d8d9 Z&d:d; Z'd<d= Z(d>d? Z)d@dA Z*dBdC Z+dDdE Z,dFdG Z-dHdI Z.dJdK Z/dLdM Z0e1dNdO Z2e1dPdQ Z3e1dRdS Z4dS )Zr   zThe ``celery multi`` program.)z
--nosplashr-   )z--quietr.   )z-qr.   )z	--verboser/   )z
--no-colorr0   Nc                 K   sf   || _ || _| j|p||f| | j| _d| _| j| j| j| j	| j	| j
| j| j| j| j| jd| _d S )Nzcelery multi)startshowstopstopwaitstop_verifyrestartkillnamesexpandgethelp)envcmdr1   r+   fhrF   rQ   rR   rS   rT   rV   rW   rX   rY   rZ   r[   commands)r   r\   r]   r^   r+   r,   r   r   r   r   __init__   s"    zMultiTool.__init__c                 C   s\   |  |}|d k	r|n| j| _tj|d| _| |sD|  S | 	|d |dd  S )Nr      )
_handle_reserved_optionsr]   ospathbasenamepoprF   validate_argumentsr?   call_command)r   r   r]   r   r   r   r     s    

z"MultiTool.execute_from_commandlinec                 C   s   |o|d d dkS )Nr   -r   r   r   r   r   r   rg     s    zMultiTool.validate_argumentsc                 C   s>   z| j | | ptW S  tk
r8   | d|  Y S X d S )NzInvalid command: )r_   r   KeyErrorr?   )r   commandr   r   r   r   rh     s    zMultiTool.call_commandc              
   C   s@   t |}| jD ],\}}||krt| |t||| q|S r   )listreserved_optionssetattrboolrf   index)r   r   argattrr   r   r   rb     s
    z"MultiTool._handle_reserved_optionsc                 C   s   |  d tt| S )Nz> Starting nodes...)rB   intanyrQ   r   r&   r   r   r   rQ   !  s    
zMultiTool.startc                 K   s   |j f d|i|S Nr'   )rS   r   r&   r'   r   r   r   r   rS   '  s    zMultiTool.stopc                 K   s   |j f d|i|S rw   )rT   rx   r   r   r   rT   ,  s    zMultiTool.stopwaitc                 K   s   t t|jf d|i|S rw   )rt   ru   rV   rx   r   r   r   rV   2  s    zMultiTool.restartc                 C   s   |  ddd |D  d S )Nr8   c                 s   s   | ]}|j V  qd S r   )name).0nr   r   r   	<genexpr>9  s     z"MultiTool.names.<locals>.<genexpr>)r4   joinrv   r   r   r   rX   7  s    zMultiTool.namesc                 G   sD   z|  ||}W n tk
r,   t Y S X | d|jS d S )N )r!   findrk   r   r7   r}   r   )r   wantedr   noder   r   r   rZ   ;  s
    
zMultiTool.getc                 C   s   |  ddd |D S )Nr8   c                 s   s   | ]}d  |jV  qdS )r~   N)r}   Zargv_with_executablerz   r   r   r   r   r|   E  s   z!MultiTool.show.<locals>.<genexpr>)r7   r}   rv   r   r   r   rR   C  s    zMultiTool.showc                 C   s   |  S r   )rW   rv   r   r   r   rW   J  s    zMultiTool.killc                    s$   |  d fdd| |D S )Nr8   c                 3   s   | ]}|  V  qd S r   )Zexpanderr   templater   r   r|   P  s   z#MultiTool.expand.<locals>.<genexpr>)r7   r}   r!   )r   r   r   r   r   r   rY   O  s    zMultiTool.expandc                 G   s   |  t d S r   )r4   __doc__rj   r   r   r   r[   U  s    zMultiTool.helpc              
   C   s   |j t|jd  }t|D ]}t|dkr`|d dkr`zt|d W   S  tk
r^   Y nX |d dkrzt|dd  W   S  tt	fk
r   Y qX q|S )N   r   ri   ra   )
r   lenvaluesreversedrt   
ValueErrorr   signumAttributeError	TypeError)r   r%   defaultr   rr   r   r   r   r$   X  s    zMultiTool._find_sig_argumentc                 C   s:   |d k	r|n| j }| |}|  || j|d|fS N)r]   )r]   OptionParserparser   )r   r   r]   r%   r   r   r   _nodes_from_argvg  s    
zMultiTool._nodes_from_argvc                 C   s   | j ||d\}}|S r   )r#   )r   r   r]   _r&   r   r   r   r!   m  s    zMultiTool.cluster_from_argvc                 C   s(   | j ||d\}}|| jt||dfS r   )r   r   rm   )r   r   r]   r%   nodesr   r   r   r#   q  s    zMultiTool._cluster_from_argvc                 C   sL   t ||| j| j| j| j| j| j| j| j| j	| j
| j| j| j| j| j| jdS )N)r]   r\   on_stopping_preambleon_send_signalon_still_waiting_foron_still_waiting_progresson_still_waiting_endon_node_starton_node_restarton_node_shutdown_okon_node_statuson_node_signal_deadon_node_signalon_node_downon_child_spawnon_child_signalledon_child_failure)r   r\   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r]   r   r   r   r   u  s(    zMultiTool.Clusterc                 C   s   |  | jd d S )Nz> Stopping nodes...)rB   rJ   bluer   r   r   r   r   r     s    zMultiTool.on_stopping_preamblec                 C   s   |  d|| d S )Nz	> {0.name}: {1} -> {0.pid}rB   rH   r   r   r'   r   r   r   r     s    zMultiTool.on_send_signalc                 C   sF   t |}|rB| j| jd|t|dddd |D dd d S )Nz> Waiting for {} {} -> {}...r   z, c                 s   s   | ]}t |jV  qd S r   )rE   pidr   r   r   r   r|     s     z1MultiTool.on_still_waiting_for.<locals>.<genexpr>FrA   )r   rB   rJ   r   rH   r   r}   )r   r   Znum_leftr   r   r   r     s    
 zMultiTool.on_still_waiting_forc                 C   s   | j ddd d S )N.FrA   rB   r   r   r   r   r     s    z#MultiTool.on_still_waiting_progressc                 C   s   |  d d S )Nr9   r   rI   r   r   r   r     s    zMultiTool.on_still_waiting_endc                 C   s   |  d| d S )Nz4Could not signal {0.name} ({0.pid}): No such processr   r   r   r   r   r   r     s
    zMultiTool.on_node_signal_deadc                 C   s   | j d|j ddd d S )Nz	> : FrA   )rB   ry   r   r   r   r   r     s    zMultiTool.on_node_startc                 C   s$   | j | jd|j ddd d S )Nz> Restarting node r   FrA   )rB   rJ   r   ry   r   r   r   r   r     s
    
zMultiTool.on_node_restartc                 C   s   |  d|j d| j  d S )Nz> r   )rB   ry   DOWNr   r   r   r   r     s    zMultiTool.on_node_downc                 C   s   |  d|j d| j  d S )Nz
	> r   )rB   ry   OKr   r   r   r   r     s    zMultiTool.on_node_shutdown_okc                 C   s   |  |r| jp| j d S r   )rB   FAILEDr   )r   r   retvalr   r   r   r     s    zMultiTool.on_node_statusc                 C   s   |  dj||d d S )Nz(Sending {sig} to node {0.name} ({0.pid}))r'   r   r   r   r   r   r     s     zMultiTool.on_node_signalc                 C   s   |  d|  d S )Nz  )rD   )r   r   Zargstrr\   r   r   r   r     s    zMultiTool.on_child_spawnc                 C   s   |  d|  d S )Nz!* Child was terminated by signal r   )r   r   r   r   r   r   r     s    zMultiTool.on_child_signalledc                 C   s   |  d|  d S )Nz"* Child terminated with exit code r   )r   r   rP   r   r   r   r     s    zMultiTool.on_child_failurec                 C   s   t | jdS )Nr   )rE   rJ   ZgreenrI   r   r   r   r     s    zMultiTool.OKc                 C   s   t | jdS )Nr   )rE   rJ   ZredrI   r   r   r   r     s    zMultiTool.FAILEDc                 C   s   t | jdS )Nr   )rE   rJ   ZmagentarI   r   r   r   r     s    zMultiTool.DOWN)NNNNN)N)N)N)N)N)5rM   rN   rO   r   r   r   r   rn   r`   r   rg   rh   rb   r   r"   rQ   r(   rS   rT   rU   rV   rX   rZ   rR   rW   rY   r[   signalSIGTERMr$   r   r!   r#   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r      s         







	

r   T)Zallow_extra_argsZignore_unknown_options)clsZcontext_settingsc                 C   sP   t | jj| jjd}tjdd }||dd |d|d  }||S )z Start multiple worker instances.)r.   r0   ra   Nmulti)r   objr.   r0   r   r   rq   r   )ctxr]   r   r   r   r   r     s    $r   )%r   rc   r   r   	functoolsr   ZclickZkombu.utils.objectsr   Zceleryr   Zcelery.apps.multir   r   r   Zcelery.bin.baser	   r
   Zcelery.platformsr   r   r   Zcelery.utilsr   Zcelery.utils.textr   __all__rG   r   r   r"   r(   r)   r   rl   Zpass_contextr   r   r   r   r   <module>   s<   d	
8 n