code: def node_stats_to_dict(message):
      decode_keys = {
          "actorId",
          "jobId",
          "taskId",
          "parentTaskId",
          "sourceActorId",
          "callerId",
          "rayletId",
          "workerId",
          "placementGroupId",
      }
      core_workers_stats = message.core_workers_stats
      message.ClearField("core_workers_stats")
      try:
          result = dashboard_utils.message_to_dict(message, decode_keys)
          result["coreWorkersStats"] = [
              dashboard_utils.message_to_dict(
                  m, decode_keys, including_default_value_fields=True
              )
              for m in core_workers_stats
          ]
          return result
      finally:
          message.core_workers_stats.extend(core_workers_stats)
  
imports: import asyncio
  import json
  import logging
  import time
  import grpc
  from itertools import chain
  import aiohttp.web
  import ray._private.utils
  from ray.dashboard.consts import GCS_RPC_TIMEOUT_SECONDS
  from ray.autoscaler._private.util import LoadMetricsSummary, get_per_node_breakdown_as_dict, parse_usage
  import ray.dashboard.consts
  import ray.dashboard.optional_utils
  import ray.dashboard.utils
  from ray._private import ray_constants
  from ray.core.generated import gcs_service_pb2, gcs_service_pb2_grpc, node_manager_pb2, node_manager_pb2_grpc
  from ray.dashboard.datacenter import DataOrganizer, DataSource
  from ray.dashboard.modules.node import node_consts
  from ray.dashboard.modules.node.node_consts import FREQUENTY_UPDATE_NODES_INTERVAL_SECONDS, FREQUENT_UPDATE_TIMEOUT_SECONDS
  from ray._private.ray_constants import DEBUG_AUTOSCALING_ERROR, DEBUG_AUTOSCALING_STATUS
  from ray.dashboard.utils import async_loop_forever
label_desc: Use image node_id 3 for calling a global function with example usage: node_stats_to_dict(message) and returns: result