code: def wait_for_job_update(self, job_id, timeout=None):
          
          # internally, we register an Event object for each entry in this function.
          # when self.notify_of_job_update() is called, we call Event.set() on all events
          # registered for that job, thereby releasing any threads waiting for that specific job.
  
          event = JOB_EVENT_MAPPING[job_id]
          event.clear()
          result = event.wait(timeout=timeout)
          job = self.get_job(job_id)
  
          if result:
              return job
          else:
              raise TimeoutError("Job {} has not received any updates.".format(job_id))
docs: Blocks until a job given by job_id has updated its state (canceled, completed, progress updated, etc.)
          if timeout is not None, then this function raises iceqube.exceptions.TimeoutError.
  
          :param job_id: the job's job_id to monitor for changes.
          :param timeout: if None, wait forever for a job update. If given, wait until timeout seconds, and then raise
          iceqube.exceptions.TimeoutError.
          :return: the Job object corresponding to job_id.