class_docstr: Abstract subclass of NodeProvider meant for use with external cluster managers.
  
  Batches reads of cluster state into a single method, get_node_data, called at the
  start of an autoscaling update.
  
  Batches modifications to cluster state into a single method, submit_scale_request,
  called at the end of an autoscaling update.
  
  Implementing a concrete subclass of BatchingNodeProvider only requires overriding
  get_node_data() and submit_scale_request().
  
  See the method docstrings for more information.
  
  Note that an autoscaling update may be conditionally
  cancelled using the optional method safe_to_scale()
  of the root NodeProvider.
docstr: Tells the cluster manager which nodes to delete and how many nodes of
  each node type to maintain.
  
  Consistency requirement:
  If a node id was present in ScaleRequest.workers_to_delete of a previously
  submitted scale request, it should no longer be present as key in get_node_data.
  (Node termination must be registered immediately when submit_scale_request
  returns.)
docstr_tok: ["Tells","the","cluster","manager","which","nodes","to","delete","and","how","many","nodes","of","each","node","type","to","maintain",".","Consistency","requirement",":","If","a","node","id","was","present","in","ScaleRequest.workers_to_delete","of","a","previously","submitted","scale","request",",","it","should","no","longer","be","present","as","key","in","get_node_data",".","(","Node","termination","must","be","registered","immediately","when","submit_scale_request","returns",".",")"]
code: def submit_scale_request(self, scale_request: ScaleRequest) -> None:
      """Tells the cluster manager which nodes to delete and how many nodes of
      each node type to maintain.
  
      Consistency requirement:
      If a node id was present in ScaleRequest.workers_to_delete of a previously
      submitted scale request, it should no longer be present as key in get_node_data.
      (Node termination must be registered immediately when submit_scale_request
      returns.)
      """
      raise NotImplementedError
  
imports: import logging
  from collections import defaultdict
  from dataclasses import dataclass, field
  from typing import Any, Dict, List, Optional, Set
  from ray.autoscaler._private.constants import DISABLE_LAUNCH_CONFIG_CHECK_KEY, DISABLE_NODE_UPDATERS_KEY, FOREGROUND_NODE_LAUNCH_KEY
  from ray.autoscaler._private.util import NodeID, NodeIP, NodeKind, NodeStatus, NodeType
  from ray.autoscaler.node_provider import NodeProvider
  from ray.autoscaler.tags import NODE_KIND_HEAD, TAG_RAY_NODE_KIND, TAG_RAY_NODE_STATUS, TAG_RAY_USER_NODE_TYPE
label_desc: Use image node_id 3 for calling the BatchingNodeProvider obj's underlying member method code with example usage: obj.submit_scale_request(scale_request) without return types