job
===

.. py:module:: job


Submodules
----------

.. toctree::
   :maxdepth: 1

   /autoapi/job/scheduler/index
   /autoapi/job/walk/index


Attributes
----------

.. autoapisummary::

   job.NotifyEndType
   job.logger


Classes
-------

.. autoapisummary::

   job.JobTimingInfo
   job.Job
   job.EmptyJob
   job.ProcessJob


Package Contents
----------------

.. py:data:: NotifyEndType

.. py:data:: logger

.. py:class:: JobTimingInfo

   Bases: :py:obj:`tuple`


   .. py:attribute:: start_time


   .. py:attribute:: stop_time


   .. py:attribute:: duration


.. py:class:: Job(uid: str, data: Any, notify_end: NotifyEndType)

   Handle a single Job.

   :ivar slot: number associated with the job during its execution. At a
       given time only one job have a given slot number.
   :vartype slot: int
   :ivar start_time: time at which job execution started or None if never
       started
   :vartype start_time: datetime.datetime
   :ivar stop_time: time at which job execution ended or None if either
       the job was never run or if the job is still running
   :vartype stop_time: datetime.datetime
   :ivar should_skip: indicator for the scheduler that the job should not
       be executed
   :vartype: bool
   :ivar interrupted: if True it means that job has been interrupted. Can
       be consequence of timeout or Ctrl-C pressed
   :vartype: bool
   :ivar queue_name: name of the queue in which the job has been placed
   :vartype: str
   :ivar tokens: number of tokens (i.e: resources) consumed during the job
       execution
   :vartype: int
   :ivar index: global index indicating the order in which jobs have been
       created. The index is used to implement the default ordering function
       needed to sort Jobs. In the context of ``e3.job.scheduler.Scheduler``
       this means that by default jobs that are created first will have a
       higher priority.
   :vartype: int


   .. py:attribute:: lock


   .. py:attribute:: index_counter
      :value: 0



   .. py:attribute:: uid


   .. py:attribute:: data


   .. py:attribute:: notify_end


   .. py:attribute:: slot
      :value: 1



   .. py:attribute:: handle
      :type:  threading.Thread | None
      :value: None



   .. py:attribute:: thread
      :value: None



   .. py:attribute:: __start_time
      :type:  datetime.datetime | None
      :value: None



   .. py:attribute:: __stop_time
      :type:  datetime.datetime | None
      :value: None



   .. py:attribute:: should_skip
      :value: False



   .. py:attribute:: interrupted
      :value: False



   .. py:attribute:: queue_name
      :value: 'default'



   .. py:attribute:: tokens
      :value: 1



   .. py:property:: priority
      :type: int


      Return job priority.

      This is used in ``e3.job.scheduler.Scheduler``.



   .. py:method:: record_start_time() -> None

      Log the starting time of a job.



   .. py:method:: record_stop_time() -> None

      Log the stopping time of a job.



   .. py:property:: timing_info
      :type: JobTimingInfo


      Retrieve some job's timing information.

      :return: a JobTimingInfo object



   .. py:method:: start(slot: int) -> None

      Launch the job.

      :param slot: slot number



   .. py:method:: run() -> None
      :abstractmethod:


      Job activity.



   .. py:property:: status
      :type: e3.anod.status.ReturnValue


      Return he job's status.

      This is made a property because users of this class should not
      be allowed to set or change it value. The job's status is ...
      a property of the job!



   .. py:method:: interrupt() -> bool

      Interrupt current job.

      :return: True if interrupted, False if already interrupted



   .. py:method:: on_start(scheduler: e3.job.scheduler.Scheduler) -> None

      Call whenever a job is started.

      This allow the user to do some logging on job startup



   .. py:method:: on_finish(scheduler: e3.job.scheduler.Scheduler) -> None

      Call whenever a job is finished.

      This allow the user to do some logging on job termination



.. py:class:: EmptyJob(uid: str, data: Any, notify_end: collections.abc.Callable[[str], None], status: e3.anod.status.ReturnValue)

   Bases: :py:obj:`Job`


   A job which does nothing.


   .. py:attribute:: should_skip
      :value: True



   .. py:attribute:: __status


   .. py:method:: run() -> None

      Job activity.



   .. py:property:: status
      :type: e3.anod.status.ReturnValue


      See Job.status' description.



.. py:class:: ProcessJob(uid: str, data: Any, notify_end: collections.abc.Callable[[str], None])

   Bases: :py:obj:`Job`


   Specialized version of Job that spawn processes.

   :ivar proc_handle: None when an object of this class is initialized.
       An e3.os.process.Run object after the "run" method is called.
   :vartype proc_handle: e3.os.process.Run | None


   .. py:attribute:: proc_handle
      :type:  e3.os.process.Run | None
      :value: None



   .. py:attribute:: __spawn_error
      :value: False



   .. py:method:: run() -> None

      Run the job.



   .. py:property:: status
      :type: e3.anod.status.ReturnValue


      See Job.status' description.



   .. py:method:: cmdline() -> list[str]
      :abstractmethod:


      Return the command line of the process to be spawned.

      :return: the command line



   .. py:property:: cmd_options
      :type: dict


      Process options.

      Important note: don't use PIPE for output or error parameters this can
      cause locking error in case the process is interrupted. The default
      redirect output and error to the console.

      The pipe behavior can easily be emulated by writing to a file and
      modifying the run method to read the file content when the process
      finish.

      :return: options for e3.os.process.Run as a dict



   .. py:method:: interrupt() -> bool

      Kill running process tree.



