class_docstr: Simulator for a backend deployment with concurrent dispatch and a queue.
class_docstr_tok: ["Simulator","for","a","backend","deployment","with","concurrent","dispatch","and","a","queue","."]
docstr: Run a simulated trial.
  
  Args:
      trial_index: The index of the trial (usually the Ax trial index)
      runtime: The runtime of the simulation. Typically sampled from the
          runtime model of a simulation model.
  
  Internally, the runtime is scaled by the `time_scaling` factor, so that
  the simulation can run arbitrarily faster than the underlying evaluation.
docstr_tok: ["Run","a","simulated","trial",".","Args",":","trial_index",":","The","index","of","the","trial","(","usually","the","Ax","trial","index",")","runtime",":","The","runtime","of","the","simulation",".","Typically","sampled","from","the","runtime","model","of","a","simulation","model",".","Internally",",","the","runtime","is","scaled","by","the","`","time_scaling","`","factor",",","so","that","the","simulation","can","run","arbitrarily","faster","than","the","underlying","evaluation","."]
code: def run_trial(self, trial_index: int, runtime: float) -> None:
      """Run a simulated trial.
  
      Args:
          trial_index: The index of the trial (usually the Ax trial index)
          runtime: The runtime of the simulation. Typically sampled from the
              runtime model of a simulation model.
  
      Internally, the runtime is scaled by the `time_scaling` factor, so that
      the simulation can run arbitrarily faster than the underlying evaluation.
      """
      # scale runtime to simulation
      sim_runtime = runtime / self.time_scaling
  
      # flip a coin to see if the trial fails (for now fail instantly)
      # TODO: Allow failure behavior based on a survival rate
      if self.failure_rate > 0:
          if random.random() < self.failure_rate:
              self._failed.append(
                  SimTrial(
                      trial_index=trial_index,
                      sim_runtime=sim_runtime,
                      sim_start_time=self.time,
                  )
              )
              return
  
      if self.num_running < self.max_concurrency:
          # note that though these are running for simulation purposes,
          # the trial status does not yet get updated (this is also how it
          # works in the real world, this requires updating the trial status manually)
          curr_time = self.time
          new_trial = SimTrial(
              trial_index=trial_index,
              sim_runtime=sim_runtime,
              sim_start_time=curr_time,
              sim_queued_time=curr_time,
          )
          self.new_trial(trial=new_trial, status=TrialStatus.RUNNING)
      else:
          new_trial = SimTrial(
              trial_index=trial_index,
              sim_runtime=sim_runtime,
              sim_queued_time=self.time,
          )
          self.new_trial(trial=new_trial, status=TrialStatus.STAGED)
  
imports: import logging
  import random
  import time
  from dataclasses import dataclass
  from logging import Logger
  from typing import Dict, List, Optional
  from ax.core.base_trial import TrialStatus
  from ax.utils.common.logger import get_logger
label_desc: Use image node_id 13 for calling the BackendSimulator obj's underlying member method code with example usage: obj.run_trial(trial_index, runtime) without return types