How to Build a Thread‑Safe Singleton Config Service in Python
Learn how to create a lightweight, thread‑safe Python configuration manager that reads from and writes to a JSON file, ensures a single global Config instance across multiple threads, and persists changes on program exit using the atexit hook.
Background
Develop a multithreaded backend service with Python 3.12.0a6 that shares a single configuration across all threads, allows dynamic updates via an HTTP interface, and persists the configuration on shutdown.
Requirement 1: Simple Configuration Items
Support basic configuration fields such as name and port. The core implementation fits in fewer than 50 lines of Python.
"""实例配置管理"""
from dataclasses import dataclass
@dataclass
class Config(object):
name: str = "mysql"
port: int = 3306Requirement 2: Global Singleton Config Object
Ensure that only one Config instance exists so that all threads operate on the same configuration.
"""实例配置管理"""
from dataclasses import dataclass
@dataclass
class Config(object):
name: str = "mysql"
port: int = 3306
_instance = None
# Singleton pattern
def __new__(cls, *args, **kw):
if cls._instance is None:
cls._instance = object.__new__(cls, *args, **kw)
return cls._instanceInteractive demonstration shows that id(a) and id(b) are identical, confirming the singleton behavior.
Requirement 3: Initialise Config from a JSON File
Read /tmp/config.json at creation time and override default values. If the file is missing or an error occurs, keep defaults.
import json
import logging
from pathlib import Path
from dataclasses import dataclass
@dataclass
class Config(object):
name: str = "mysql"
port: int = 3306
_instance = None
def __new__(cls, *args, **kw):
if cls._instance is None:
cls._instance = object.__new__(cls, *args, **kw)
return cls._instance
def __post_init__(self):
"""If the config file exists, load its values and overwrite defaults.
On any exception keep the defaults.
"""
if (config_file := Path("/tmp/config.json")) and config_file.exists():
try:
with open(config_file) as f:
json_data = json.loads(f.read())
self.__dict__.update(json_data)
except Exception as err:
pass
else:
logging.warn("config file '{}' not exists. well using defautl values .".format(config_file))Example config.json:
{
"name": "trump",
"port": 8848
}Running the class now yields Config(name='trump', port=8848), confirming the values were loaded.
Requirement 4: Persist Config on Program Exit
Register an atexit hook that writes the current configuration back to /tmp/config.json when the interpreter terminates.
import json
import atexit
import logging
from pathlib import Path
from dataclasses import dataclass, asdict
@dataclass
class Config(object):
name: str = "mysql"
port: int = 3306
_instance = None
def __new__(cls, *args, **kw):
if cls._instance is None:
cls._instance = object.__new__(cls, *args, **kw)
return cls._instance
def __post_init__(self):
"""Load values from the config file if it exists; otherwise keep defaults.
Register a shutdown hook to save the current config.
"""
if (config_file := Path("/tmp/config.json")) and config_file.exists():
try:
with open(config_file) as f:
json_data = json.loads(f.read())
self.__dict__.update(json_data)
except Exception as err:
pass
else:
logging.warn("config file '{}' not exists. well using defautl values .".format(config_file))
# Save config on exit
def sync_to_disk():
json_str = json.dumps(asdict(self), indent=4)
with open(config_file, 'w') as f:
logging.warning("save configs to '{}' ".format(config_file))
f.write(json_str)
atexit.register(sync_to_disk)Interactive test shows that after modifying a.name = "hello-world" and exiting, the JSON file contains the updated values:
{
"name": "hello-world",
"port": 8848
}This demonstrates a complete, thread‑safe, singleton configuration manager that reads from and writes to disk automatically.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
