class_docstr: A rendezvous implementation that uses `etcd <https://etcd.io/>`__ as the backend store.
class_docstr_tok: ["A","rendezvous","implementation","that","uses","`","etcd","<","https",":","\/\/etcd.io\/",">","`","__","as","the","backend","store","."]
docstr: Helper method for the join phase.
docstr_tok: ["Helper","method","for","the","join","phase","."]
code: def join_rendezvous(self, expected_version):
      """Helper method for the join phase."""
      # Use compare-and-swap to add self to rendezvous state:
      while True:
          cas_delay()
          active_version, state = self.get_rdzv_state()
  
          if state["status"] != "joinable":
              raise EtcdRendezvousRetryableFailure(
                  "Rendezvous state became non-joinable before we could join. "
                  "Must join next one."
              )
  
          if state["version"] != expected_version:
              raise EtcdRendezvousRetryImmediately(
                  "Rendezvous version changed. Must try join the new one."
              )
  
          assert (
              len(state["participants"]) < self._num_max_workers
          ), "Logic error: joinable rendezvous should always have space left"
  
          this_rank = len(state["participants"])
          state["participants"].append(this_rank)
  
          # When reaching min workers, or changing state to frozen, we'll set
          # the active_version node to be ephemeral.
          set_ttl: Optional[int] = None
          if len(state["participants"]) == self._num_max_workers:
              state["status"] = "frozen"
              state["keep_alives"] = []
              set_ttl = CONST_ETCD_FROZEN_TTL
          elif len(state["participants"]) >= self._num_min_workers:
              set_ttl = CONST_ETCD_JOINABLE_EPHEMERAL_TTL
  
          try:
              # Compare-and-swap.
              active_version = self.client.test_and_set(
                  key=self.get_path("/rdzv/active_version"),
                  value=json.dumps(state),
                  prev_value=active_version.value,
                  ttl=set_ttl,
              )
              # We succeeded joining.
              return active_version, this_rank
  
          except etcd.EtcdCompareFailed:
              log.info("Join rendezvous CAS unsuccessful, retrying")
  
imports: import json
  import logging
  import sys
  import threading
  import time
  from typing import Optional
  import etcd
  from torch.distributed.elastic.rendezvous import RendezvousClosedError, RendezvousError, RendezvousHandler, RendezvousParameters, RendezvousTimeoutError
  from .utils import parse_rendezvous_endpoint
  from .etcd_store import EtcdStore, cas_delay
label_desc: Use image node_id 9 for calling the EtcdRendezvous obj's underlying member method code with example usage: obj.join_rendezvous(expected_version) and returns: active_version,  this_rank