Files
hse-2026/materials/07-naming-lookup/seminar/consul/app.py
T
2026-10-21 23:03:28 +03:00

57 lines
2.0 KiB
Python

"""A small real HTTP service which registers its reachable address in Consul."""
import json
import os
import socket
import threading
import time
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from urllib.request import Request, urlopen
INSTANCE = os.environ["INSTANCE_ID"]
CONSUL = os.environ.get("CONSUL_URL", "http://consul:8500")
ADDRESS = socket.gethostbyname(socket.gethostname())
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path not in ("/", "/health"):
self.send_error(404)
return
body = json.dumps({"instance": INSTANCE, "address": ADDRESS, "port": 8080}).encode()
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def log_message(self, *_):
pass
def register():
payload = {
"ID": INSTANCE, "Name": "orders", "Address": ADDRESS, "Port": 8080,
"Check": {"HTTP": f"http://{ADDRESS}:8080/health", "Interval": "2s", "Timeout": "1s"},
}
# No automatic deregistration: the failed service stays in the catalog for comparison.
for attempt in range(30):
try:
request = Request(CONSUL + "/v1/agent/service/register",
data=json.dumps(payload).encode(), method="PUT",
headers={"Content-Type": "application/json"})
with urlopen(request, timeout=2) as response:
response.read()
print(f"REGISTERED orders / {INSTANCE} -> {ADDRESS}:8080", flush=True)
return
except OSError:
time.sleep(1)
raise RuntimeError("Consul registration failed after 30 attempts")
if __name__ == "__main__":
server = ThreadingHTTPServer(("0.0.0.0", 8080), Handler)
thread = threading.Thread(target=server.serve_forever, daemon=True)
thread.start()
register()
thread.join()