#!/usr/bin/env python3 """Views that compute, beside writes (docs/design/018 stage 3, research 119). pure-serve (THREADS connection threads, store in RAM, cores 0-2) holds graph.aup with a random graph of NODES nodes and EDGES edges (seed 119); a second one like it (apart) shares the cores. In turns, for SECONDS each, ROUNDS rounds: writes benchmarks/http/load posts points (16 connections, keep-alive, core 3): the owner applies them both the same, while ASKERS connections ask the distance view (its body a breadth first search) without pause, random arguments apart the same, the askers asking the second host: the cores shared, not the host events the same, the askers posting the search as events (route): on the owner one, many the askers alone, 1 and ASKERS of them Every view answer is checked against a model, made before any run is timed: the askers start from 64 nodes picked beforehand (a model made while asking would time Python, not the host). views.py PURE_SERVE AUP NODES EDGES THREADS ASKERS SECONDS ROUNDS [WAYS] a JSON line per run, then medians (WAYS: the ways to run, by commas; all by default) """ import http.client import json import random import shutil import statistics import struct import subprocess import sys import tempfile import threading import time from pathlib import Path HERE = Path(__file__).resolve().parent LOAD = HERE.parents[2] / 'benchmarks' / 'http' / 'load' def main(): serve, aup = Path(sys.argv[1]).resolve(), Path(sys.argv[2]).resolve() nodes, edges_wanted, threads, askers, seconds, rounds = (int(a) for a in sys.argv[3:9]) chosen = sys.argv[9].split(',') if len(sys.argv) > 9 else ['writes', 'both', 'apart', 'events', 'one', 'many'] rng = random.Random(119) pairs = set() while len(pairs) < edges_wanted: a, b = rng.randrange(nodes), rng.randrange(nodes) if a != b: pairs.add((a, b)) edges = sorted(pairs) out = [[] for _ in range(nodes)] for a, b in edges: out[a].append(b) model = {} def far(a, b): if a not in model: depth, frontier = {a: 0}, [a] for v in frontier: for t in out[v]: if t not in depth: depth[t] = depth[v] + 1 frontier.append(t) model[a] = depth return model[a].get(b, -1) work = Path(tempfile.mkdtemp(prefix='pure-034-', dir='/dev/shm')) try: subprocess.run([str(aup), 'build', str(HERE / 'graph.aup'), '-o', str(work / 'graph.pmod')], check=True) host = subprocess.Popen(['taskset', '-c', '0-2', str(serve), '--module', str(work / 'graph.pmod'), '--store', str(work / 'store'), '--port', '0', '--threads', str(threads)], stdout=subprocess.PIPE, stderr=subprocess.PIPE) port = json.loads(host.stdout.readline())['port'] apart = subprocess.Popen(['taskset', '-c', '0-2', str(serve), '--module', str(work / 'graph.pmod'), '--store', str(work / 'apart'), '--port', '0', '--threads', str(threads)], stdout=subprocess.PIPE, stderr=subprocess.PIPE) apart_port = json.loads(apart.stdout.readline())['port'] for target in (port, apart_port): setup = http.client.HTTPConnection('127.0.0.1', target, timeout=600) def post(path, body=b''): setup.request('POST', path, body, {'Content-Length': str(len(body))}) answer = setup.getresponse() assert answer.status == 200 and answer.read() is not None, path post(f'/inputs/size?nodes={nodes}') for k in range(0, len(edges), 80000): post('/inputs/load', b''.join(struct.pack('