108 lines
3.1 KiB
Python
108 lines
3.1 KiB
Python
import multiprocessing
|
|
import os
|
|
import git
|
|
import src.banner as banner
|
|
|
|
|
|
def get_git_commit():
|
|
"""Get first 6 characters of current git commit hash"""
|
|
try:
|
|
repo = git.Repo(search_parent_directories=True)
|
|
return repo.head.commit.hexsha[:6]
|
|
except Exception:
|
|
return "unknown"
|
|
|
|
|
|
# Server socket
|
|
bind = "127.0.0.1:7433" # nginx will proxy to this
|
|
backlog = 2048
|
|
|
|
# Worker processes
|
|
workers = multiprocessing.cpu_count() * 2 + 1 # Recommended formula
|
|
worker_class = "uvicorn.workers.UvicornWorker" # Async worker for FastAPI
|
|
worker_connections = 1000
|
|
max_requests = 1000 # Restart workers after this many requests
|
|
max_requests_jitter = 50 # Add randomness to prevent all workers restarting at once
|
|
|
|
# Timeouts
|
|
timeout = 30 # Workers silent for more than this are killed
|
|
keepalive = 2 # Wait this long for requests on Keep-Alive connections
|
|
|
|
# Logging
|
|
accesslog = "./logs/webhook_access.log"
|
|
errorlog = "./logs/webhook_error.log"
|
|
loglevel = "info"
|
|
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(D)s'
|
|
|
|
# Process naming
|
|
proc_name = "studspider"
|
|
|
|
# Server mechanics
|
|
daemon = False # Run in foreground (systemd will handle daemonization)
|
|
pidfile = "./logs/studspider.pid"
|
|
umask = 0
|
|
user = None # Run as current user (systemd will set user)
|
|
group = None
|
|
tmp_upload_dir = None
|
|
|
|
# SSL (not needed with nginx, but here for reference)
|
|
# keyfile = None
|
|
# certfile = None
|
|
|
|
# Security
|
|
limit_request_line = 4096
|
|
limit_request_fields = 100
|
|
limit_request_field_size = 8190
|
|
|
|
# Debugging (disable in production)
|
|
reload = os.getenv("GUNICORN_RELOAD", "false").lower() == "true"
|
|
reload_engine = "auto"
|
|
|
|
|
|
# Hooks
|
|
def on_starting(server):
|
|
"""Called just before the master process is initialized."""
|
|
print("Studspider WEB starting...")
|
|
|
|
# Verify .env file exists (workers will load it via get_sq_env.py)
|
|
from pathlib import Path
|
|
|
|
env_path = Path(__file__).parent.parent / ".env"
|
|
print(f"[@DEBUG] Looking for .env at: {env_path.absolute()}")
|
|
if env_path.exists():
|
|
print(f"✓ .env file found (workers will load via get_sq_env.py)")
|
|
else:
|
|
print(f"⚠ No .env file found at {env_path.absolute()}")
|
|
|
|
|
|
def on_reload(server):
|
|
"""Called to recycle workers during a reload via SIGHUP."""
|
|
print("🔄 Reloading workers...")
|
|
|
|
|
|
def when_ready(server):
|
|
commit_hash = get_git_commit()
|
|
banner_text = banner.generate("studspider v0.3.0")
|
|
|
|
# Add commit hash to the last line of banner
|
|
banner_lines = banner_text.rstrip("\n").split("\n")
|
|
if banner_lines:
|
|
banner_lines[-1] += f" {commit_hash}"
|
|
|
|
print("\n".join(banner_lines))
|
|
print("Built for PLAY-WELL TEKNOLOGIES by contact@studspider.sh\n\n")
|
|
print(f"HOST:\t{bind}")
|
|
print(f"WORKERS:\t{workers}")
|
|
print(f"WORKER TYPE:\t{worker_class}")
|
|
print(f"{'=' * 60}\n")
|
|
|
|
|
|
def worker_int(worker):
|
|
"""Called just after a worker exited on SIGINT or SIGQUIT."""
|
|
print(f"⚠️ Worker {worker.pid} received INT or QUIT signal")
|
|
|
|
|
|
def worker_abort(worker):
|
|
"""Called when a worker received the SIGABRT signal."""
|
|
print(f"❌ Worker {worker.pid} aborted")
|