class_docstr: A controller/agent that populates a Launch RunQueue from a hyperparameter sweep.
class_docstr_tok: ["A","controller\/agent","that","populates","a","Launch","RunQueue","from","a","hyperparameter","sweep","."]
docstr: Main run function.
docstr_tok: ["Main","run","function","."]
code: def run(self) -> None:
      """Main run function."""
      wandb.termlog(f"{LOG_PREFIX}Scheduler running")
      self.state = SchedulerState.RUNNING
      try:
          while True:
              self._update_scheduler_run_state()
              if not self.is_alive:
                  break
  
              wandb.termlog(
                  f"{LOG_PREFIX}Polling for new runs to launch"
              )
  
              self._update_run_states()
              self._poll()
              if self.state == SchedulerState.FLUSH_RUNS:
                  if self.num_active_runs == 0:
                      wandb.termlog(
                          f"{LOG_PREFIX}Done polling on runs, exiting"
                      )
                      break
                  time.sleep(self._polling_sleep)
                  continue
  
              for worker_id in self.available_workers:
                  if self.at_runcap:
                      wandb.termlog(
                          f"{LOG_PREFIX}Sweep at run_cap ({self._num_runs_launched})"
                      )
                      self.state = SchedulerState.FLUSH_RUNS
                      break
  
                  try:
                      run: Optional[
                          SweepRun
                      ] = self._get_next_sweep_run(worker_id)
                      if not run:
                          break
                  except SchedulerError as e:
                      raise SchedulerError(e)
                  except Exception as e:
                      wandb.termerror(
                          f"{LOG_PREFIX}Failed to get next sweep run: {e}"
                      )
                      self.state = SchedulerState.FAILED
                      break
  
                  if self._add_to_launch_queue(run):
                      self._num_runs_launched += 1
  
              time.sleep(self._polling_sleep)
      except KeyboardInterrupt:
          wandb.termwarn(
              f"{LOG_PREFIX}Scheduler received KeyboardInterrupt. Exiting"
          )
          self.state = SchedulerState.STOPPED
          self.exit()
          return
      except Exception as e:
          wandb.termlog(
              f"{LOG_PREFIX}Scheduler failed with exception {e}"
          )
          self.state = SchedulerState.FAILED
          self.exit()
          raise e
      else:
          # scheduler succeeds if at runcap
          if self.state == SchedulerState.FLUSH_RUNS and self.at_runcap:
              self.state = SchedulerState.COMPLETED
          self.exit()
  
imports: import asyncio
  import base64
  import logging
  import os
  import socket
  import threading
  import time
  import traceback
  from abc import ABC, abstractmethod
  from dataclasses import dataclass
  from enum import Enum
  from typing import TYPE_CHECKING, Any, Dict, Iterator, List, Optional, Tuple, Union
  import click
  import yaml
  import wandb
  from wandb.errors import CommError
  from wandb.sdk.launch._launch_add import launch_add
  from wandb.sdk.launch.errors import LaunchError
  from wandb.sdk.launch.sweeps import SchedulerError
  from wandb.sdk.launch.sweeps.utils import create_sweep_command_args, make_launch_sweep_entrypoint
  from wandb.sdk.launch.utils import event_loop_thread_exec
  from wandb.sdk.lib.runid import generate_id
label_desc: Use image node_id 18 for calling the Scheduler obj's underlying member method code with example usage: obj.run() without return types