o
    ªZh  ã                   @   s6   d dl mZ d dlmZ d dlmZ G dd„ dƒZdS )é    )ÚProducer)Úparse_spec_config)Úreport_collection_diffc                   @   sp   e Zd ZdZddd„Zedd„ ƒZedd„ ƒZed	d
„ ƒZdd„ Z	dd„ Z
ddd„Zdd„ Zdd„ Zdd„ ZdS )ÚEachSchedulinga"  Implement scheduling of test items on all nodes

    If a node gets added after the test run is started then it is
    assumed to replace a node which got removed before it finished
    its collection.  In this case it will only be used if a node
    with the same spec got removed earlier.

    Any nodes added after the run is started will only get items
    assigned if a node with a matching spec was removed before it
    finished all its pending items.  The new node will then be
    assigned the remaining items from the removed node.
    Nc                 C   sR   || _ tt|ƒƒ| _i | _i | _g | _i | _|d u r tdƒ| _	n|j
| _	d| _d S )NÚ	eachschedF)ÚconfigÚlenr   ÚnumnodesÚnode2collectionÚnode2pendingÚ_startedÚ_removed2pendingr   Úlogr   Úcollection_is_completed)Úselfr   r   © r   úK/var/www/html/lang_env/lib/python3.10/site-packages/xdist/scheduler/each.pyÚ__init__   s   
zEachScheduling.__init__c                 C   s   t | j ¡ ƒS )z%A list of all nodes in the scheduler.)Úlistr   Úkeys)r   r   r   r   Únodes!   s   zEachScheduling.nodesc                 C   s:   | j sdS | jr
dS | j ¡ D ]}t|ƒdkr dS qdS )NFé   T)r   r   r   Úvaluesr   ©r   Úpendingr   r   r   Útests_finished&   s   ÿzEachScheduling.tests_finishedc                 C   s   | j  ¡ D ]}|r dS qdS )zÜReturn True if there are pending test items

        This indicates that collection has finished and nodes are
        still processing test items, so this can be thought of as
        "the scheduler is active".
        TF)r   r   r   r   r   r   Úhas_pending1   s
   ÿzEachScheduling.has_pendingc                 C   s   || j vsJ ‚g | j |< d S ©N)r   )r   Únoder   r   r   Úadd_node>   s   zEachScheduling.add_nodec                 C   sÈ   || j v sJ ‚| js%t|ƒ| j|< g | j |< t| jƒ| jkr#d| _dS dS | jr`| jD ]6}|jj|jjkr_| j| }||krQt	|||jj
|jj
ƒ}|  |¡  dS | j |¡}|| j |<  dS q+dS dS )aò  Add the collected test items from a node

        Collection is complete once all nodes have submitted their
        collection.  In this case its pending list is set to an empty
        list.  When the collection is already completed this
        submission is from a node which was restarted to replace a
        dead node.  In this case we already assign the pending items
        here.  In either case ``.schedule()`` will instruct the
        node to start running the required tests.
        TN)r   r   r   r
   r   r	   r   ZgatewayÚspecr   Úidr   Úpop)r   r   Ú
collectionZdeadnodeZdead_collectionÚmsgr   r   r   r   Úadd_node_collectionB   s4   

ÿ

ü

óþz"EachScheduling.add_node_collectionr   c                 C   s   | j |  |¡ d S r   )r   Úremove)r   r   Z
item_indexÚdurationr   r   r   Úmark_test_completed   s   z!EachScheduling.mark_test_completec                 C   s0   | j  d| j |¡¡ | jD ]}|  |¡ qd S ©Nr   )r   Úinsertr#   Úindexr   Zcheck_schedule)r   Úitemr   r   r   r   Úmark_test_pendingg   s   
þ
ÿz EachScheduling.mark_test_pendingc                 C   s:   | j  |¡}|s
d S | j| | d¡ }|r|| j|< |S r)   )r   r"   r
   r   )r   r   r   Z	crashitemr   r   r   Úremove_nodeo   s   
zEachScheduling.remove_nodec                 C   st   | j sJ ‚| j ¡ D ]-\}}|| jv rq
|s,tt| j| ƒƒ|dd…< | ¡  | ¡  n| 	|¡ | j 
|¡ q
dS )a1  Schedule the test items on the nodes

        If the node's pending list is empty it is a new node which
        needs to run all the tests.  If the pending list is already
        populated (by ``.add_node_collection()``) then it replaces a
        dead node and we only need to run those tests.
        N)r   r   Úitemsr   Úranger   r
   Zsend_runtest_allÚshutdownZsend_runtest_someÚappend)r   r   r   r   r   r   Úscheduley   s   



÷zEachScheduling.scheduler   )r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úpropertyr   r   r   r   r%   r(   r-   r.   r3   r   r   r   r   r      s    





"
r   N)Zxdist.remoter   Zxdist.workermanager   Zxdist.reportr   r   r   r   r   r   Ú<module>   s    