Simplify null pyworker code and docs
Pass over all three files to drop verbose expository commentary that duplicated either the code or the README. Net: -284 lines. README now reads top-to-bottom in roughly the order someone would need the info: use case → how it works → endpoint params → API → healthcheck → deploy → demo. Endpoint params table uses the values actually tested on alpha (min_load=0, target_util=1, max_queue_time=1, target_queue_time=0.5, inactivity_timeout=10). Dropped the "known autoscaler quirk" section now that alpha addresses it; kept the --session-cost flag as a debugging knob. worker.py and client.py keep the same behavior but trim long block comments and multi-line docstrings the code didn't need. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+28
-80
@@ -16,37 +16,21 @@ from vastai import (
|
||||
|
||||
log = logging.getLogger(__file__)
|
||||
|
||||
# Performance value pinned in the benchmark cache; sent to autoscaler as
|
||||
# max_perf. Standardized at 100 — the conventional default the rest of the
|
||||
# serverless system expects.
|
||||
TARGET_PERF = 100.0
|
||||
|
||||
# Marker the benchmark path sets so the fallback /ping path returns
|
||||
# immediately during the framework's startup benchmark.
|
||||
BENCHMARK_SENTINEL = "__null_worker_benchmark__"
|
||||
|
||||
# Internal control server. Hosts:
|
||||
# * POST /release — releases the active reservation by closing the
|
||||
# singleton session on this worker. Called by the user's queue
|
||||
# consumer when its work is done.
|
||||
# * GET /health — only when BACKEND_HEALTH_URL is unset; gives the
|
||||
# framework's healthcheck loop something live to talk to.
|
||||
# Bound to 127.0.0.1 so only processes on the instance can reach it.
|
||||
INTERNAL_HOST = "127.0.0.1"
|
||||
INTERNAL_PORT = int(os.environ.get("NULL_CONTROL_PORT", 18999))
|
||||
STUB_HEALTH_PATH = "/health"
|
||||
|
||||
BACKEND_HEALTH_URL = os.environ.get("BACKEND_HEALTH_URL", "").strip()
|
||||
|
||||
if BACKEND_HEALTH_URL:
|
||||
_parsed = urlsplit(BACKEND_HEALTH_URL)
|
||||
if not _parsed.scheme or not _parsed.hostname:
|
||||
raise ValueError(
|
||||
f"BACKEND_HEALTH_URL must be an absolute URL, got: {BACKEND_HEALTH_URL!r}"
|
||||
)
|
||||
HEALTH_BASE_URL = f"{_parsed.scheme}://{_parsed.hostname}"
|
||||
HEALTH_PORT = _parsed.port or (443 if _parsed.scheme == "https" else 80)
|
||||
HEALTH_PATH = _parsed.path or "/"
|
||||
_p = urlsplit(BACKEND_HEALTH_URL)
|
||||
if not _p.scheme or not _p.hostname:
|
||||
raise ValueError(f"BACKEND_HEALTH_URL must be absolute, got: {BACKEND_HEALTH_URL!r}")
|
||||
HEALTH_BASE_URL = f"{_p.scheme}://{_p.hostname}"
|
||||
HEALTH_PORT = _p.port or (443 if _p.scheme == "https" else 80)
|
||||
HEALTH_PATH = _p.path or "/"
|
||||
USE_STUB_HEALTH = False
|
||||
else:
|
||||
HEALTH_BASE_URL = f"http://{INTERNAL_HOST}"
|
||||
@@ -55,9 +39,6 @@ else:
|
||||
USE_STUB_HEALTH = True
|
||||
|
||||
|
||||
# Stashed after Worker(...) is constructed so /release can reach the
|
||||
# framework's session machinery. Dict so the lifecycle closure picks up
|
||||
# the assignment that happens before .run().
|
||||
_backend_ref: dict = {"backend": None}
|
||||
|
||||
|
||||
@@ -65,30 +46,16 @@ def _build_internal_app() -> web.Application:
|
||||
app = web.Application()
|
||||
|
||||
async def release_handler(_request: web.Request) -> web.Response:
|
||||
"""End the active reservation (the singleton session on this worker).
|
||||
|
||||
max_sessions=1 means at most one session is active here. We call
|
||||
the framework's internal __close_session via name-mangling to
|
||||
bypass the session_auth check that /session/end normally requires.
|
||||
That's intentional: this endpoint is localhost-only so trust is
|
||||
assumed, and the user's consumer can release without having to
|
||||
plumb session_auth through their queue.
|
||||
|
||||
__close_session reports the session metrics as a success, fires
|
||||
on_close_route if configured, and pops the session from the dict.
|
||||
"""
|
||||
# Closes the singleton session. Uses name-mangled __close_session
|
||||
# to bypass the session_auth check — safe because this server is
|
||||
# bound to 127.0.0.1, and it spares the consumer from threading
|
||||
# session_auth through its queue.
|
||||
backend = _backend_ref.get("backend")
|
||||
if backend is None:
|
||||
return web.json_response(
|
||||
{"released": False, "reason": "backend not ready"},
|
||||
status=503,
|
||||
)
|
||||
return web.json_response({"released": False, "reason": "backend not ready"}, status=503)
|
||||
sids = list(backend.sessions.keys())
|
||||
if not sids:
|
||||
return web.json_response(
|
||||
{"released": False, "reason": "no active session"},
|
||||
status=200,
|
||||
)
|
||||
return web.json_response({"released": False, "reason": "no active session"}, status=200)
|
||||
closed = []
|
||||
for sid in sids:
|
||||
try:
|
||||
@@ -96,17 +63,13 @@ def _build_internal_app() -> web.Application:
|
||||
closed.append(sid)
|
||||
except Exception as e:
|
||||
log.warning(f"Error closing session {sid}: {e}")
|
||||
return web.json_response(
|
||||
{"released": bool(closed), "session_ids": closed},
|
||||
status=200,
|
||||
)
|
||||
return web.json_response({"released": bool(closed), "session_ids": closed}, status=200)
|
||||
|
||||
app.router.add_post("/release", release_handler)
|
||||
|
||||
if USE_STUB_HEALTH:
|
||||
async def stub_health(_request: web.Request) -> web.Response:
|
||||
return web.Response(status=200, text="ok")
|
||||
|
||||
app.router.add_get(STUB_HEALTH_PATH, stub_health)
|
||||
|
||||
return app
|
||||
@@ -114,37 +77,26 @@ def _build_internal_app() -> web.Application:
|
||||
|
||||
@asynccontextmanager
|
||||
async def null_lifecycle():
|
||||
# Pin max_throughput to exactly TARGET_PERF by pre-populating the
|
||||
# framework's benchmark cache file. __run_benchmark short-circuits to
|
||||
# float(file_contents) when this file exists.
|
||||
# Pin max_throughput to TARGET_PERF exactly — the framework's
|
||||
# __run_benchmark short-circuits to float(file_contents) if this exists.
|
||||
try:
|
||||
with open(".has_benchmark", "w") as fh:
|
||||
fh.write(str(int(TARGET_PERF)))
|
||||
except OSError as e:
|
||||
log.warning(f"Could not pin benchmark cache: {e}")
|
||||
|
||||
app = _build_internal_app()
|
||||
runner = web.AppRunner(app)
|
||||
runner = web.AppRunner(_build_internal_app())
|
||||
await runner.setup()
|
||||
site = web.TCPSite(runner, INTERNAL_HOST, INTERNAL_PORT)
|
||||
await site.start()
|
||||
await web.TCPSite(runner, INTERNAL_HOST, INTERNAL_PORT).start()
|
||||
|
||||
lines = [
|
||||
f"Null pyworker internal control server: http://{INTERNAL_HOST}:{INTERNAL_PORT}",
|
||||
f" POST /release - end the active reservation (call from your queue consumer)",
|
||||
]
|
||||
if USE_STUB_HEALTH:
|
||||
lines.append(
|
||||
f" GET {STUB_HEALTH_PATH} - stub healthcheck (override with BACKEND_HEALTH_URL)"
|
||||
)
|
||||
else:
|
||||
lines.append(f"Framework healthcheck pointed at: {BACKEND_HEALTH_URL}")
|
||||
lines.append(
|
||||
"Reservations use the framework session model. Clients POST to "
|
||||
"/session/create via the SDK to acquire a worker; max_sessions=1 "
|
||||
"so each worker holds at most one reservation."
|
||||
log.info(
|
||||
"Null pyworker control server: http://%s:%d (POST /release%s)",
|
||||
INTERNAL_HOST,
|
||||
INTERNAL_PORT,
|
||||
f", GET {STUB_HEALTH_PATH}" if USE_STUB_HEALTH else "",
|
||||
)
|
||||
log.info("\n".join(lines))
|
||||
if not USE_STUB_HEALTH:
|
||||
log.info("Framework healthcheck → %s", BACKEND_HEALTH_URL)
|
||||
|
||||
try:
|
||||
yield
|
||||
@@ -153,15 +105,11 @@ async def null_lifecycle():
|
||||
|
||||
|
||||
async def ping(**params: object) -> dict:
|
||||
"""Trivial handler. Exists to satisfy the framework's requirement that
|
||||
at least one HandlerConfig has a BenchmarkConfig, and to give clients
|
||||
a route they can hit with session_id to extend their session TTL.
|
||||
"""
|
||||
# Exists only to satisfy the framework's "at least one handler with a
|
||||
# BenchmarkConfig" requirement. Sleep 1s on the benchmark path as a
|
||||
# fallback in case the .has_benchmark cache pin failed; otherwise the
|
||||
# benchmark cache short-circuits and this never runs.
|
||||
if params.get(BENCHMARK_SENTINEL):
|
||||
# Fallback only — the lifecycle pre-pins .has_benchmark so
|
||||
# __run_benchmark normally short-circuits and this never runs. If
|
||||
# the cache write failed, sleep ~1s so the time-based throughput
|
||||
# math lands near TARGET_PERF.
|
||||
await asyncio.sleep(1.0)
|
||||
return {"ok": True, "benchmark": True}
|
||||
return {"ok": True}
|
||||
|
||||
Reference in New Issue
Block a user