from __future__ import annotations
import argparse
import json
import os
import socket
import sys
from http.server import BaseHTTPRequestHandler, HTTPServer
from typing import Optional
def fibonacci(n: int) -> int:
if n <= 0:
return 0
if n == 1:
return 1
a, b = 0, 1
for _ in range(2, n + 1):
a, b = b, a + b
return b
def get_local_ip() -> str:
try:
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.connect(("8.8.8.8", 80))
return s.getsockname()[0]
except Exception:
pass
try:
return socket.gethostbyname(socket.gethostname())
except Exception:
return "127.0.0.1"
class FibonacciHandler(BaseHTTPRequestHandler):
def do_POST(self):
if self.path.rstrip("/") != "/execute":
self.send_response(404)
self.end_headers()
return
content_length = int(self.headers.get("Content-Length", 0))
body = self.rfile.read(content_length) if content_length else b"{}"
try:
data = json.loads(body.decode("utf-8"))
n = int(data.get("n", 4))
sleep_secs = data.get("sleep")
if sleep_secs is not None:
sleep_secs = max(0, min(float(sleep_secs), 300)) else:
sleep_secs = 0
except (ValueError, TypeError):
n = 4
sleep_secs = 0
if sleep_secs > 0:
import time
time.sleep(sleep_secs)
n = max(0, min(n, 50)) result = fibonacci(n)
payload = {
"result": result,
"n": n,
"pid": os.getpid(),
"ip": get_local_ip(),
}
if sleep_secs > 0:
payload["sleep_secs"] = sleep_secs
raw = json.dumps(payload).encode("utf-8")
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(raw)))
self.send_header("X-Zakuro-Pid", str(payload["pid"]))
self.send_header("X-Zakuro-IP", str(payload["ip"]))
self.end_headers()
self.wfile.write(raw)
def log_message(self, format: str, *args) -> None:
pass
def main() -> None:
ap = argparse.ArgumentParser(description="Fibonacci worker for Zakuro benchmarks")
ap.add_argument("--port", "-p", type=int, default=3960, help="Port (0 = pick any)")
ap.add_argument("--bind", "-b", default="0.0.0.0", help="Bind address")
args = ap.parse_args()
server = HTTPServer((args.bind, args.port), FibonacciHandler)
port = server.server_port
print(f"Fibonacci worker listening on {args.bind}:{port} pid={os.getpid()} ip={get_local_ip()}", flush=True)
try:
server.serve_forever()
except KeyboardInterrupt:
pass
server.server_close()
if __name__ == "__main__":
main()