class_docstr: Interface for service job manager.
  
  Service jobs are long-running jobs associated with a node or a pipeline that
  persist across executions (eg: worker pools, Tensorboard, etc). Service jobs
  should be started before the nodes that depend on them can be run.
class_docstr_tok: ["Interface","for","service","job","manager",".","Service","jobs","are","long-running","jobs","associated","with","a","node","or","a","pipeline","that","persist","across","executions","(","eg",":","worker","pools",",","Tensorboard",",","etc",")",".","Service","jobs","should","be","started","before","the","nodes","that","depend","on","them","can","be","run","."]
docstr: Ensures necessary service jobs are started and healthy for the node.
  
  `ensure_node_services` will be called in the orchestration loop periodically
  and is expected to:
  
  * Start any service jobs required by the pipeline node.
  * Probe job health, handle failure and return appropriate status.
  
  Note that this method will only be called if either `is_pure_service_node`
  or `is_mixed_service_node` return `True` for the node.
  
  Args:
    pipeline_state: A `PipelineState` object for an active pipeline.
    node_id: Id of the node to ensure services.
    backfill_token: Backfill token, if applicable. Should only be non-empty if
      `is_pure_service_node` return `True` for the node.
  
  Returns:
    Status of the service job(s) for the node.
docstr_tok: ["Ensures","necessary","service","jobs","are","started","and","healthy","for","the","node",".","`","ensure_node_services","`","will","be","called","in","the","orchestration","loop","periodically","and","is","expected","to",":","*","Start","any","service","jobs","required","by","the","pipeline","node",".","*","Probe","job","health",",","handle","failure","and","return","appropriate","status",".","Note","that","this","method","will","only","be","called","if","either","`","is_pure_service_node","`","or","`","is_mixed_service_node","`","return","`","True","`","for","the","node",".","Args",":","pipeline_state",":","A","`","PipelineState","`","object","for","an","active","pipeline",".","node_id",":","Id","of","the","node","to","ensure","services",".","backfill_token",":","Backfill","token",",","if","applicable",".","Should","only","be","non-empty","if","`","is_pure_service_node","`","return","`","True","`","for","the","node",".","Returns",":","Status","of","the","service","job","(","s",")","for","the","node","."]
code: def ensure_node_services(
      self,
      pipeline_state: pstate.PipelineState,
      node_id: str,
      backfill_token: str = "",
  ) -> ServiceStatus:
      """Ensures necessary service jobs are started and healthy for the node.
  
      `ensure_node_services` will be called in the orchestration loop periodically
      and is expected to:
  
      * Start any service jobs required by the pipeline node.
      * Probe job health, handle failure and return appropriate status.
  
      Note that this method will only be called if either `is_pure_service_node`
      or `is_mixed_service_node` return `True` for the node.
  
      Args:
        pipeline_state: A `PipelineState` object for an active pipeline.
        node_id: Id of the node to ensure services.
        backfill_token: Backfill token, if applicable. Should only be non-empty if
          `is_pure_service_node` return `True` for the node.
  
      Returns:
        Status of the service job(s) for the node.
      """
  
imports: import abc
  import dataclasses
  import enum
  from typing import Optional
  from absl import logging
  from tfx.orchestration.experimental.core import pipeline_state
label_desc: Use image node_id 1 for calling the ServiceJobManager obj's underlying member method code with example usage: obj.ensure_node_services(pipeline_state, node_id, backfill_token) without return types