class_docstr: A loop gets jobs from a queue and processes them.
  
  Once initialized, the loop can be started with the `run` method and will run until an uncaught exception
  is raised.
  
  Args:
      job_runner_factory (`JobRunnerFactory`):
          The job runner factory that will create a job runner for each job. Must be able to process the jobs of the
            queue.
      worker_config (`WorkerConfig`):
          Worker configuration.
      state_file_path (`str`):
          The path of the file where the state of the loop will be saved.
class_docstr_tok: ["A","loop","gets","jobs","from","a","queue","and","processes","them",".","Once","initialized",",","the","loop","can","be","started","with","the","`","run","`","method","and","will","run","until","an","uncaught","exception","is","raised",".","Args",":","job_runner_factory","(","`","JobRunnerFactory","`",")",":","The","job","runner","factory","that","will","create","a","job","runner","for","each","job",".","Must","be","able","to","process","the","jobs","of","the","queue",".","worker_config","(","`","WorkerConfig","`",")",":","Worker","configuration",".","state_file_path","(","`","str","`",")",":","The","path","of","the","file","where","the","state","of","the","loop","will","be","saved","."]
code: def set_worker_state(
      self, current_job_info: Optional[JobInfo]
  ) -> None:
      worker_state: WorkerState = {
          "current_job_info": current_job_info,
          "last_updated": get_datetime(),
      }
      with FileLock(f"{self.state_file_path}.lock"):
          with open(self.state_file_path, "wb") as worker_state_f:
              worker_state_f.write(orjson.dumps(worker_state))
  
imports: import logging
  import random
  import time
  from dataclasses import dataclass
  from datetime import datetime
  from typing import Optional, TypedDict
  import orjson
  from filelock import FileLock
  from libcommon.prometheus import StepProfiler
  from libcommon.queue import AlreadyStartedJobError, EmptyQueueError, LockTimeoutError, NoWaitingJobError, Queue
  from libcommon.utils import JobInfo, get_datetime
  from psutil import cpu_count, getloadavg, swap_memory, virtual_memory
  from worker.config import AppConfig
  from worker.job_manager import JobManager
  from worker.job_runner_factory import BaseJobRunnerFactory
label_desc: Use image node_id 8 for calling the Loop obj's underlying member method code with example usage: obj.set_worker_state(current_job_info) without return types