3
O6b[              
   @   s   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ ed	d
dddddged ZejejfZG dd deZejejejejejejejejejejiZdd Zdd Zdd Z dd Z!dd Z"dd Z#dS ) z*Represent a deployment of MongoDB servers.    )
namedtuple)common)ConfigurationError)ReadPreference)ServerDescription)	Selection)SERVER_TYPEZTopologyTypeSingleReplicaSetNoPrimaryReplicaSetWithPrimaryShardedUnknownLoadBalanced   c               @   s   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	e
dd Ze
dd Ze
dd Ze
dd Ze
dd Ze
dd Ze
dd Ze
dd Ze
dd  Ze
d!d" Ze
d#d$ Zd.d&d'Zejfd(d)Zd*d+ Zd,d- Zd%S )/TopologyDescriptionc             C   s   || _ || _|| _|| _|| _|| _d| _| j tjkr>| j	  | j
}|sPd| _n.tdd |D rjd| _ntdd |D | _dS )a  Representation of a deployment of MongoDB servers.

        :Parameters:
          - `topology_type`: initial type
          - `server_descriptions`: dict of (address, ServerDescription) for
            all seeds
          - `replica_set_name`: replica set name or None
          - `max_set_version`: greatest setVersion seen from a primary, or None
          - `max_election_id`: greatest electionId seen from a primary, or None
          - `topology_settings`: a TopologySettings
        Nc             s   s   | ]}|j d kV  qd S )N)logical_session_timeout_minutes).0s r   [/var/www/html/sandeepIITI/myenv/lib/python3.6/site-packages/pymongo/topology_description.py	<genexpr>O   s   z/TopologyDescription.__init__.<locals>.<genexpr>c             s   s   | ]}|j V  qd S )N)r   )r   r   r   r   r   r   S   s   )_topology_type_replica_set_name_server_descriptions_max_set_version_max_election_id_topology_settings_incompatible_errTOPOLOGY_TYPEr   _init_incompatible_errreadable_servers_ls_timeout_minutesanymin)selftopology_typeserver_descriptionsreplica_set_namemax_set_versionmax_election_idZtopology_settingsr    r   r   r   __init__%   s"    	
zTopologyDescription.__init__c             C   s   x| j j D ]}|jsq|jdk	o,|jtjk}|jdk	oB|jtjk }|rld|jd |jd |jtjf | _	q|rd|jd |jd |jtjtj
f | _	P qW dS )z>Internal compatibility check for non-load balanced topologies.Nz]Server at %s:%d requires wire version %d, but this version of PyMongo only supports up to %d.r      zgServer at %s:%d reports wire version %d, but this version of PyMongo requires at least %d (MongoDB %s).)r   valuesis_server_type_knownmin_wire_versionr   ZMAX_SUPPORTED_WIRE_VERSIONmax_wire_versionZMIN_SUPPORTED_WIRE_VERSIONaddressr   ZMIN_SUPPORTED_SERVER_VERSION)r$   r   Zserver_too_newZserver_too_oldr   r   r   r   V   s$    

z*TopologyDescription._init_incompatible_errc             C   s   | j rt| j dS )zRaise ConfigurationError if any server is incompatible.

        A server is incompatible if its wire protocol version range does not
        overlap with PyMongo's.
        N)r   r   )r$   r   r   r   check_compatiblez   s    z$TopologyDescription.check_compatiblec             C   s
   || j kS )N)r   )r$   r0   r   r   r   
has_server   s    zTopologyDescription.has_serverc             C   s   | j | j }t| |S )z;A copy of this description, with one server marked Unknown.)r   
to_unknownupdated_topology_description)r$   r0   Z
unknown_sdr   r   r   reset_server   s    z TopologyDescription.reset_serverc             C   sH   | j tjkrtj}n| j }tdd | jD }t||| j| j| j	| j
S )z<A copy of this description, with all servers marked Unknown.c             s   s   | ]}|t |fV  qd S )N)r   )r   r0   r   r   r   r      s   z,TopologyDescription.reset.<locals>.<genexpr>)r   r   r   r
   dictr   r   r   r   r   r   )r$   r%   sdsr   r   r   reset   s    zTopologyDescription.resetc             C   s
   | j j S )zRDict of (address,
        :class:`~pymongo.server_description.ServerDescription`).)r   copy)r$   r   r   r   r&      s    z'TopologyDescription.server_descriptionsc             C   s   | j S )zThe type of this topology.)r   )r$   r   r   r   r%      s    z!TopologyDescription.topology_typec             C   s   t j| j S )zUThe topology type as a human readable string.

        .. versionadded:: 3.4
        )r   _fieldsr   )r$   r   r   r   topology_type_name   s    z&TopologyDescription.topology_type_namec             C   s   | j S )zThe replica set name.)r   )r$   r   r   r   r'      s    z$TopologyDescription.replica_set_namec             C   s   | j S )z1Greatest setVersion seen from a primary, or None.)r   )r$   r   r   r   r(      s    z#TopologyDescription.max_set_versionc             C   s   | j S )z1Greatest electionId seen from a primary, or None.)r   )r$   r   r   r   r)      s    z#TopologyDescription.max_election_idc             C   s   | j S )z)Minimum logical session timeout, or None.)r!   )r$   r   r   r   r      s    z3TopologyDescription.logical_session_timeout_minutesc             C   s   dd | j j D S )z)List of Servers of types besides Unknown.c             S   s   g | ]}|j r|qS r   )r-   )r   r   r   r   r   
<listcomp>   s    z5TopologyDescription.known_servers.<locals>.<listcomp>)r   r,   )r$   r   r   r   known_servers   s    z!TopologyDescription.known_serversc             C   s   t dd | jj D S )z7Whether there are any Servers of types besides Unknown.c             s   s   | ]}|j r|V  qd S )N)r-   )r   r   r   r   r   r      s    z8TopologyDescription.has_known_servers.<locals>.<genexpr>)r"   r   r,   )r$   r   r   r   has_known_servers   s    z%TopologyDescription.has_known_serversc             C   s   dd | j j D S )zList of readable Servers.c             S   s   g | ]}|j r|qS r   )Zis_readable)r   r   r   r   r   r<      s    z8TopologyDescription.readable_servers.<locals>.<listcomp>)r   r,   )r$   r   r   r   r       s    z$TopologyDescription.readable_serversc             C   s"   | j }|rtdd | j D S dS )z3Minimum of all servers' max wire versions, or None.c             s   s   | ]}|j V  qd S )N)r/   )r   r   r   r   r   r      s    z:TopologyDescription.common_wire_version.<locals>.<genexpr>N)r=   r#   )r$   serversr   r   r   common_wire_version   s    z'TopologyDescription.common_wire_versionc             C   s   | j jS )N)r   heartbeat_frequency)r$   r   r   r   rA      s    z'TopologyDescription.heartbeat_frequencyNc                s    fdd}t |ddr@ j}|r@||jk r@td||j|f  jtjtjfkrX jS |rx j	 j
|}|rt|gS g S  jtjkrtj }n|tj }|d k	r|r|j||j	}||S )Nc                sB   | sg S j }tdd | jD  |jd  fdd| jD S )Nc             s   s   | ]}|j V  qd S )N)round_trip_time)r   r   r   r   r   r      s    zTTopologyDescription.apply_selector.<locals>.apply_local_threshold.<locals>.<genexpr>g     @@c                s   g | ]}|j   kr|qS r   )rB   )r   r   )fastest	thresholdr   r   r<      s    zUTopologyDescription.apply_selector.<locals>.apply_local_threshold.<locals>.<listcomp>)r   r#   r&   Zlocal_threshold_ms)	selectionsettings)r$   )rC   rD   r   apply_local_threshold   s    
zATopologyDescription.apply_selector.<locals>.apply_local_thresholdr.   r   zF%s requires min wire version %d, but topology's min wire version is %d)getattrr@   r.   r   r%   r   r	   r   r=   r&   getr   r   Zfrom_topology_descriptionZwith_server_descriptions)r$   selectorr0   Zcustom_selectorrG   Z	common_wvdescriptionrE   r   )r$   r   apply_selector   s,    

z"TopologyDescription.apply_selectorc             C   s   t jd| t| j|dS )a  Does this topology have any readable servers available matching the
        given read preference?

        :Parameters:
          - `read_preference`: an instance of a read preference from
            :mod:`~pymongo.read_preferences`. Defaults to
            :attr:`~pymongo.read_preferences.ReadPreference.PRIMARY`.

        .. note:: When connected directly to a single server this method
          always returns ``True``.

        .. versionadded:: 3.4
        read_preferenceN)r   Zvalidate_read_preferencer"   rL   )r$   rM   r   r   r   has_readable_server  s    z'TopologyDescription.has_readable_serverc             C   s   | j tjS )zDoes this topology have a writable server available?

        .. note:: When connected directly to a single server this method
          always returns ``True``.

        .. versionadded:: 3.4
        )rN   r   PRIMARY)r$   r   r   r   has_writable_server  s    z'TopologyDescription.has_writable_serverc             C   s0   t | jj dd d}d| jj| jj| j|f S )Nc             S   s   | j S )N)r0   )sdr   r   r   <lambda>,  s    z.TopologyDescription.__repr__.<locals>.<lambda>)keyz+<%s id: %s, topology_type: %s, servers: %r>)sortedr   r,   	__class____name__r   Z_topology_idr;   )r$   r?   r   r   r   __repr__)  s
    
zTopologyDescription.__repr__)N)rV   
__module____qualname__r*   r   r1   r2   r5   r8   r&   propertyr%   r;   r'   r(   r)   r   r=   r>   r    r@   rA   rL   r   rO   rN   rP   rW   r   r   r   r   r   $   s,   1$		
,
r   c       
      C   s  |j }| j}| j}| j}| j}|j}| j }|||< |tjkr|dk	rr||jkrrt	d||jf }	|j
|	d||< ttj||||| jS |tjkr|tjtjfkrt| jjdkrtj}q|j| n|tjtjfkrt| }|tjkr|tjtjfkr|j| n|tjkr|tjtjfkr2|j| nL|tjkrXt|||||\}}}}n&|tjtjtjfkrt|||\}}n|tjkr|tjtjfkr|j| t |}nR|tjkrt|||||\}}}}n,|tjtjtjfkrt!|||}nt |}t|||||| jS )a}  Return an updated copy of a TopologyDescription.

    :Parameters:
      - `topology_description`: the current TopologyDescription
      - `server_description`: a new ServerDescription that resulted from
        a hello call

    Called after attempting (successfully or not) to call hello on the
    server at server_description.address. Does not modify topology_description.
    Nzeclient is configured to connect to a replica set named '%s' but this node belongs to a set named '%s')errorr+   )"r0   r%   r'   r(   r)   server_typer&   r   r	   r   r3   r   r   r   r   Z
StandaloneZLoadBalancerlenZseedspopZRSGhost_SERVER_TYPE_TO_TOPOLOGY_TYPEr   Mongosr
   	RSPrimary_update_rs_from_primaryRSSecondary	RSArbiterRSOther!_update_rs_no_primary_from_memberr   _check_has_primary#_update_rs_with_primary_from_member)
topology_descriptionserver_descriptionr0   r%   set_namer(   r)   r\   r7   r[   r   r   r   r4   >  s    




r4   c             C   s   | j  }t|j t|kr | S x |D ]}||kr&t|||< q&W x&t|j D ]}||krP|j| qPW t| j|| j| j	| j
| jS )zReturn an updated copy of a TopologyDescription.

    :Parameters:
      - `topology_description`: the current TopologyDescription
      - `seedlist`: a list of new seeds new ServerDescription that resulted from
        a hello call
    )r&   setkeysr   listr^   r   r%   r'   r(   r)   r   )ri   Zseedlistr7   r0   r   r   r   )_updated_topology_description_srv_polling  s     	
ro   c       	      C   s2  |dkr|j }n&||j kr6| j|j t| |||fS ||f}d|jkr~d|krx||jkrx|j | |j< t| |||fS |j}|jdk	r|dks|j|kr|j}x8| j D ],}|j	t
jkr|j|jkr|j | |j< P qW x"|jD ]}|| krt|| |< qW x"t| |j D ]}| j| qW t| |||fS )ag  Update topology description from a primary's hello response.

    Pass in a dict of ServerDescriptions, current replica set name, the
    ServerDescription we are processing, and the TopologyDescription's
    max_set_version and max_election_id if any.

    Returns (new topology type, new replica_set_name, new max_set_version,
    new max_election_id).
    N)r'   r^   r0   rg   Zelection_tupler3   Zelection_idZset_versionr,   r\   r   ra   	all_hostsr   rl   )	r7   r'   rj   r(   r)   Zmax_election_tupleserverZnew_addressaddrr   r   r   rb     sH    




rb   c             C   sJ   |dk	st ||jkr$| j|j n|jrB|j|jkrB| j|j t| S )zRS with known primary. Process a response from a non-primary.

    Pass in a dict of ServerDescriptions, current replica set name, and the
    ServerDescription we are processing.

    Returns new topology type.
    N)AssertionErrorr'   r^   r0   merg   )r7   r'   rj   r   r   r   rh     s    
rh   c             C   s~   t j}|dkr|j}n||jkr4| j|j ||fS x"|jD ]}|| kr<t|| |< q<W |jrv|j|jkrv| j|j ||fS )zRS without known primary. Update from a non-primary's response.

    Pass in a dict of ServerDescriptions, current replica set name, and the
    ServerDescription we are processing.

    Returns (new topology type, new replica_set_name).
    N)r   r
   r'   r^   r0   rp   r   rt   )r7   r'   rj   r%   r0   r   r   r   rf   5  s    
rf   c             C   s.   x(| j  D ]}|jtjkr
tjS q
W tjS dS )zCurrent topology type is ReplicaSetWithPrimary. Is primary still known?

    Pass in a dict of ServerDescriptions.

    Returns new topology type.
    N)r,   r\   r   ra   r   r   r
   )r7   r   r   r   r   rg   U  s    
rg   N)$__doc__collectionsr   Zpymongor   Zpymongo.errorsr   Zpymongo.read_preferencesr   Zpymongo.server_descriptionr   Zpymongo.server_selectorsr   Zpymongo.server_typer   ranger   r   r   ZSRV_POLLING_TOPOLOGIESobjectr   r`   ra   r   rc   r
   rd   re   r_   r4   ro   rb   rh   rf   rg   r   r   r   r   <module>   s2     s"K 