Repository source: docs/plans/application_capacity_study/read_driver.py.txt
from pathlib import Path
import sys,subprocess,time,urllib.request,urllib.error,hashlib,re,socket
import collector as c
n=int(sys.argv[1]);sock=socket.socket();sock.bind(('127.0.0.1',0));port=sock.getsockname()[1];sock.close()
serverlog=open(c.ROOT/f'http-{n}-server.log','wb')
p=subprocess.Popen(['php','-S',f'127.0.0.1:{port}','-t',str(c.APP/'public'),str(c.ROOT/'router.php')],cwd=c.APP,env=c.ENV,stdout=serverlog,stderr=serverlog)
try:
for _ in range(100):
try:
s=socket.create_connection(('127.0.0.1',port),.1);s.close();break
except OSError:time.sleep(.05)
routes=['/','/latest','/top','/search?search=qqqq','/400000','/api/get_post?post_id=thread-20261030000000-qdb-400000','/activity']
if n==1:routes=['/400000','/api/get_post?post_id=thread-20261030000000-qdb-400000']
for route in routes:
previous=None
for repeat in range(3):
started=time.monotonic()
try:
with urllib.request.urlopen(f'http://127.0.0.1:{port}'+route,timeout=30) as response:body=response.read();status=response.status
except urllib.error.HTTPError as e:body=e.read();status=e.code
elapsed=time.monotonic()-started
ids=list(dict.fromkeys(re.findall(rb'thread-20261030000000-qdb-\d+',body)))
key=hashlib.sha256(b'\n'.join(ids)).hexdigest()
stable=previous is None or previous==key;previous=key
print(f'Sample: read-{n}-{route}-{repeat}\nStatus: {status}\nElapsed seconds: {elapsed:.6f}\nResponse bytes: {len(body)}\nDistinct synthetic IDs: {len(ids)}\nOrdered ID hash: {key}\nIDs stable: {stable}\nBody SHA256: {hashlib.sha256(body).hexdigest()}\n',flush=True)
(c.ROOT/f'response-{n}-{routes.index(route)}-{repeat}.txt').write_bytes(body)
if status!=200 or not stable or (route in ('/latest','/top','/search?search=qqqq') and len(ids)!=25):raise RuntimeError('semantic/status mismatch; halt this route campaign')
finally:
p.terminate();p.wait(timeout=5);serverlog.close()