class_docstr: A high-level interface to a hivemind DHT that runs a single DHT node in a background process.
  * hivemind servers periodically announce their experts via declare_experts (dht_handler.py)
  * trainers find most suitable experts via RemoteMixtureOfExperts (beam_search.py)
  
  :param initial_peers: multiaddrs of one or more active DHT peers (if you want to join an existing DHT)
  :param start: if True, automatically starts the background process on creation. Otherwise await manual start
  :param daemon: if True, the background process is marked as daemon and automatically terminated after main process
  :param num_workers: declare_experts and get_experts will use up to this many parallel workers
    (but no more than one per key)
  :param expiration: experts declared from this node expire after this many seconds (default = 5 minutes)
  :param record_validators: instances of RecordValidatorBase used for signing and validating stored records.
    The validators will be combined using the CompositeValidator class. It merges them when possible
    (according to their `.merge_with()` policies) and orders them according to the `.priority` properties.
  :param shutdown_timeout: when calling .shutdown, wait for up to this many seconds before terminating
  :param await_ready: if True, the constructor waits until the DHT process is ready to process incoming requests
  :param kwargs: any other params will be forwarded to DHTNode and hivemind.p2p.P2P upon creation
class_docstr_tok: ["A","high-level","interface","to","a","hivemind","DHT","that","runs","a","single","DHT","node","in","a","background","process",".","*","hivemind","servers","periodically","announce","their","experts","via","declare_experts","(","dht_handler.py",")","*","trainers","find","most","suitable","experts","via","RemoteMixtureOfExperts","(","beam_search.py",")",":","param","initial_peers",":","multiaddrs","of","one","or","more","active","DHT","peers","(","if","you","want","to","join","an","existing","DHT",")",":","param","start",":","if","True",",","automatically","starts","the","background","process","on","creation",".","Otherwise","await","manual","start",":","param","daemon",":","if","True",",","the","background","process","is","marked","as","daemon","and","automatically","terminated","after","main","process",":","param","num_workers",":","declare_experts","and","get_experts","will","use","up","to","this","many","parallel","workers","(","but","no","more","than","one","per","key",")",":","param","expiration",":","experts","declared","from","this","node","expire","after","this","many","seconds","(","default","=","5","minutes",")",":","param","record_validators",":","instances","of","RecordValidatorBase","used","for","signing","and","validating","stored","records",".","The","validators","will","be","combined","using","the","CompositeValidator","class",".","It","merges","them","when","possible","(","according","to","their","`",".merge_with","(",")","`","policies",")","and","orders","them","according","to","the","`",".priority","`","properties",".",":","param","shutdown_timeout",":","when","calling",".shutdown",",","wait","for","up","to","this","many","seconds","before","terminating",":","param","await_ready",":","if","True",",","the","constructor","waits","until","the","DHT","process","is","ready","to","process","incoming","requests",":","param","kwargs",":","any","other","params","will","be","forwarded","to","DHTNode","and","hivemind.p2p.P2P","upon","creation"]
code: def peer_id(self) -> PeerID:
      if self._peer_id is None:
          if os.getpid() == self.pid:
              self._peer_id = self._node.peer_id
          else:
              # note: we cannot run_coroutine from the same pid because it would deadlock the event loop
              self._peer_id = self.run_coroutine(DHT._get_peer_id)
      return self._peer_id
  
imports: from __future__ import annotations
  import asyncio
  import multiprocessing
  import os
  import signal
  from functools import partial
  from typing import Awaitable, Callable, Iterable, List, Optional, Sequence, TypeVar, Union
  from multiaddr import Multiaddr
  from hivemind.dht.node import DEFAULT_NUM_WORKERS, DHTNode
  from hivemind.dht.routing import DHTKey, DHTValue, Subkey
  from hivemind.dht.validation import CompositeValidator, RecordValidatorBase
  from hivemind.p2p import P2P, PeerID
  from hivemind.utils import MPFuture, get_logger, switch_to_uvloop
  from hivemind.utils.timed_storage import DHTExpiration, ValueWithExpiration
label_desc: Use image node_id 10 for calling the DHT obj's underlying member method code with example usage: obj.peer_id() and returns: self