class_docstr: Server allows you to host "experts" - pytorch subnetworks that can be accessed remotely by peers.
  After creation, a server should be started: see Server.run or Server.run_in_background.
  
  A working server does two things:
   - processes incoming forward/backward requests via Runtime (created by the server)
   - publishes updates to expert status every :update_period: seconds
  
  :type dht: an instance of hivemind.DHT. Server will use DHT for all network interactions.
  :param module_backends: dict{expert uid (str) : ModuleBackend} for all expert hosted by this server.
  :param num_connection_handlers: maximum number of simultaneous requests. Please note that the default value of 1
      if too small for normal functioning, we recommend 4 handlers per expert backend.
  :param update_period: how often will server attempt to publish its state (i.e. experts) to the DHT;
      if dht is None, this parameter is ignored.
  :param expiration: when server declares its experts to the DHT, these entries will expire after this many seconds
  :param start: if True, the server will immediately start as a background thread and returns control after server
      is ready (see .ready below)
class_docstr_tok: ["Server","allows","you","to","host","``","experts","''","-","pytorch","subnetworks","that","can","be","accessed","remotely","by","peers",".","After","creation",",","a","server","should","be","started",":","see","Server.run","or","Server.run_in_background",".","A","working","server","does","two","things",":","-","processes","incoming","forward\/backward","requests","via","Runtime","(","created","by","the","server",")","-","publishes","updates","to","expert","status","every",":","update_period",":","seconds",":","type","dht",":","an","instance","of","hivemind.DHT",".","Server","will","use","DHT","for","all","network","interactions",".",":","param","module_backends",":","dict","{","expert","uid","(","str",")",":","ModuleBackend","}","for","all","expert","hosted","by","this","server",".",":","param","num_connection_handlers",":","maximum","number","of","simultaneous","requests",".","Please","note","that","the","default","value","of","1","if","too","small","for","normal","functioning",",","we","recommend","4","handlers","per","expert","backend",".",":","param","update_period",":","how","often","will","server","attempt","to","publish","its","state","(","i.e",".","experts",")","to","the","DHT",";","if","dht","is","None",",","this","parameter","is","ignored",".",":","param","expiration",":","when","server","declares","its","experts","to","the","DHT",",","these","entries","will","expire","after","this","many","seconds",":","param","start",":","if","True",",","the","server","will","immediately","start","as","a","background","thread","and","returns","control","after","server","is","ready","(","see",".ready","below",")"]
docstr: Gracefully terminate the server, process-safe.
  Please note that terminating server otherwise (e.g. by killing processes) may result in zombie processes.
  If you did already cause a zombie outbreak, your only option is to kill them with -9 (SIGKILL).
docstr_tok: ["Gracefully","terminate","the","server",",","process-safe",".","Please","note","that","terminating","server","otherwise","(","e.g",".","by","killing","processes",")","may","result","in","zombie","processes",".","If","you","did","already","cause","a","zombie","outbreak",",","your","only","option","is","to","kill","them","with","-9","(","SIGKILL",")","."]
code: def shutdown(self):
      """
      Gracefully terminate the server, process-safe.
      Please note that terminating server otherwise (e.g. by killing processes) may result in zombie processes.
      If you did already cause a zombie outbreak, your only option is to kill them with -9 (SIGKILL).
      """
      self.ready.clear()
  
      for handler in self.conn_handlers:
          handler.shutdown()
      logger.debug("Connection handlers terminated")
  
      if self.module_backends:
          self.dht_handler_thread.stop.set()
          self.dht_handler_thread.join()
  
      if self.checkpoint_saver is not None:
          self.checkpoint_saver.stop.set()
          self.checkpoint_saver.join()
  
      self.dht.shutdown()
  
      logger.debug(f"Shutting down runtime")
      self.runtime.shutdown()
  
      logger.info("Server shutdown successfully")
  
imports: from __future__ import annotations
  import multiprocessing
  import random
  import threading
  from contextlib import contextmanager
  from functools import partial
  from pathlib import Path
  from typing import Dict, List, Optional
  import torch
  from hivemind.dht import DHT
  from hivemind.moe.expert_uid import UID_DELIMITER
  from hivemind.moe.server.checkpoints import CheckpointSaver, is_directory, load_experts
  from hivemind.moe.server.connection_handler import ConnectionHandler
  from hivemind.moe.server.dht_handler import DHTHandlerThread, get_experts
  from hivemind.moe.server.layers import add_custom_models_from_file, name_to_block, name_to_input, schedule_name_to_scheduler
  from hivemind.moe.server.layers.optim import ClippingWrapper
  from hivemind.moe.server.module_backend import ModuleBackend
  from hivemind.moe.server.runtime import Runtime
  from hivemind.p2p import PeerInfo
  from hivemind.proto.runtime_pb2 import CompressionType
  from hivemind.utils.logging import get_logger
  from hivemind.utils.tensor_descr import DUMMY_BATCH_SIZE, BatchTensorDescriptor
label_desc: Use image node_id 6 for calling the Server obj's underlying member method code with example usage: obj.shutdown() without return types