text: import os
  from pathlib import Path
  import json
  import logging
  from multiprocessing import Lock
  
  
  class ConfigHandler(object):
      __instance = None
  
      @staticmethod
      def get_instance() -> 'ConfigHandler':
          if ConfigHandler.__instance is None:
              ConfigHandler()
  
          return ConfigHandler.__instance
  
      def __init__(self):
  
          # Verify that this is not being
          if ConfigHandler.__instance is not None:
              raise Exception("Config handler is a singleton, use the get_instance() method to retrieve the global "
                              "config handler.")
          else:
              ConfigHandler.__instance = self
  
          # Flag to indicate that the config file has been setup correctly
          self._ok = False
          self._lock = Lock()  # Mutex lock so the config can be edited by multiple threads at the same time
          self._cfg = {}
  
          # Check if there is a rotor directory defined
          self._rotor_dir = Path()
          if "ROTOR_DIR" in os.environ:
              self._rotor_dir = os.getenv("ROTOR_DIR")
          else:
              raise Exception("The environmental variable ROTOR_DIR must be set to point to the directory containing "
                              "cfg.json")
  
          self._cfg_filepath = self._rotor_dir / Path('cfg.json')
          logging.info(f"Using configuration file {self._cfg_filepath}")
  
          self._load_config()
  
      def _load_config(self):
          # Try to read the initial configuration from the config file
          try:
              with open(self._cfg_filepath) as in_file:
                  with self._lock:
                      self._cfg = json.load(in_file)
              self._ok = True
  
          except FileNotFoundError as e:
  
              # File is not there, make a new one
              self._update_config()
              self._ok = True
  
          except json.JSONDecodeError as e:
  
              # We couldn't parse the information in the file, log the error, then override
              logging.error("Unable to parse config file, no configurations will be written")
  
      def _update_config(self):
          try:
              with open(self._cfg_filepath, 'w') as config_file:
                  with self._lock:
                      json.dump(self._cfg, config_file, indent=4)
  
          except Exception as e:
              logging.error(e)
  
      def set_config_value(self, key, value):
          with self._lock:
              self._cfg[key] = value
  
          if self._ok:
              self._update_config()
  
      def get_config_value_or(self, key, default):
          with self._lock:
              if key in self._cfg:
                  return self._cfg[key]
              else:
                  return default
  
      def rotor_dir(self):
          return self._rotor_dir
  