mirror of
https://github.com/frappe/gunicorn.git
synced 2026-07-04 03:31:29 +08:00
feat(companion): Add states and CompanionConfig with config hash
This commit is contained in:
parent
3f479157d7
commit
2241dd4031
@ -664,8 +664,8 @@ No per-companion logic in Arbiter.
|
||||
|
||||
## 20. Implementation Tasks
|
||||
|
||||
- [ ] Add companion config settings in `gunicorn/config.py`.
|
||||
- [ ] Add config validation for `companion_workers`.
|
||||
- [x] Add companion config settings in `gunicorn/config.py`.
|
||||
- [x] Add config validation for `companion_workers`.
|
||||
- [ ] Add `CompanionConfig` and config hash generation.
|
||||
- [ ] Add public process states.
|
||||
- [ ] Add `CompanionProcess` runtime state.
|
||||
|
||||
10
gunicorn/companion/__init__.py
Normal file
10
gunicorn/companion/__init__.py
Normal file
@ -0,0 +1,10 @@
|
||||
#
|
||||
# This file is part of gunicorn released under the MIT license.
|
||||
# See the NOTICE for more information.
|
||||
|
||||
"""Companion process manager.
|
||||
|
||||
Gunicorn manages one extra child, the Companion Manager, which manages all
|
||||
configured non-HTTP companion processes (RQ workers, scheduler, socket.io,
|
||||
custom daemons). See ``docs/design/companion-process-manager.md``.
|
||||
"""
|
||||
85
gunicorn/companion/process.py
Normal file
85
gunicorn/companion/process.py
Normal file
@ -0,0 +1,85 @@
|
||||
#
|
||||
# This file is part of gunicorn released under the MIT license.
|
||||
# See the NOTICE for more information.
|
||||
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
|
||||
# Public states, mimicking ``supervisorctl status``. The manager never
|
||||
# exposes EXITED/FATAL/UNKNOWN; an exited companion is either STOPPED (manual)
|
||||
# or BACKOFF (waiting to restart).
|
||||
STOPPED = "STOPPED"
|
||||
STARTING = "STARTING"
|
||||
RUNNING = "RUNNING"
|
||||
BACKOFF = "BACKOFF"
|
||||
STOPPING = "STOPPING"
|
||||
|
||||
PUBLIC_STATES = (STOPPED, STARTING, RUNNING, BACKOFF, STOPPING)
|
||||
|
||||
|
||||
class CompanionConfig:
|
||||
"""Validated, normalized config for a single companion.
|
||||
|
||||
Built from one entry of ``companion_workers`` with global defaults already
|
||||
applied. ``config_hash`` is a stable digest of every field; the manager
|
||||
restarts a companion whenever its hash changes on reread.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
target,
|
||||
cwd=None,
|
||||
env=None,
|
||||
stop_signal="SIGTERM",
|
||||
stop_timeout=60,
|
||||
reload_timeout=60,
|
||||
stdout=None,
|
||||
stderr=None,
|
||||
startsecs=1,
|
||||
):
|
||||
self.name = name
|
||||
self.target = target
|
||||
self.cwd = cwd
|
||||
self.env = dict(env or {})
|
||||
self.stop_signal = stop_signal
|
||||
self.stop_timeout = stop_timeout
|
||||
self.reload_timeout = reload_timeout
|
||||
self.stdout = stdout
|
||||
self.stderr = stderr
|
||||
self.startsecs = startsecs
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"name": self.name,
|
||||
"target": self.target,
|
||||
"cwd": self.cwd,
|
||||
"env": self.env,
|
||||
"stop_signal": self.stop_signal,
|
||||
"stop_timeout": self.stop_timeout,
|
||||
"reload_timeout": self.reload_timeout,
|
||||
"stdout": self.stdout,
|
||||
"stderr": self.stderr,
|
||||
"startsecs": self.startsecs,
|
||||
}
|
||||
|
||||
@property
|
||||
def config_hash(self):
|
||||
# Sort keys so dict ordering never changes the digest. A callable
|
||||
# target has no stable repr across runs, so use its qualified name.
|
||||
data = self.to_dict()
|
||||
data["target"] = self._target_key(self.target)
|
||||
blob = json.dumps(data, sort_keys=True, default=str)
|
||||
return hashlib.sha256(blob.encode("utf-8")).hexdigest()
|
||||
|
||||
@staticmethod
|
||||
def _target_key(target):
|
||||
if callable(target):
|
||||
mod = getattr(target, "__module__", "")
|
||||
qual = getattr(target, "__qualname__", repr(target))
|
||||
return "%s:%s" % (mod, qual)
|
||||
return str(target)
|
||||
|
||||
def __repr__(self):
|
||||
return "<CompanionConfig %s>" % self.name
|
||||
Loading…
x
Reference in New Issue
Block a user