minimart-benchmark-2017/echo-client.rkt

152 lines
5.2 KiB
Racket
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#lang racket/base
(require racket/match)
(require racket/tcp)
(require racket/cmdline)
(require logbook)
(define server-entry-name (standard-logbook-entry-name))
(define server-entry-type #f)
(define server-hostname "localhost")
(define server-port 5999)
(define max-waypoint 1000)
(command-line #:program "echo-client.rkt"
#:once-each
["--max-waypoint" n
"set maximum waypoint for this run"
(set! max-waypoint (string->number n))]
["--host" name
"set hostname of server to contact"
(set! server-hostname name)]
["--port" number
"set TCP port of server to contact"
(set! server-port (string->number number))]
["--logbook-entry-name" name
"set logbook entry name to use when recording run statistics"
(set! server-entry-name name)]
["--logbook-entry-type" type
"set logbook entry type to use"
(set! server-entry-type type)])
(when (not server-entry-type)
(error 'echo-client "Please supply the --logbook-entry-type command-line argument."))
(define L (default-logbook))
(define E (logbook-entry L "minimart" server-entry-name server-entry-type))
(when (not (logbook-machine-info-recorded? E))
(logbook-record-machine-info! E))
(define Tgrowth (logbook-table E "client-grow-times" #:column-spec '(initial-count
secs/connection
connections/sec
elapsed-sec
final-count)))
(define Tping (logbook-table E "client-ping-times" #:column-spec '(connection-count
secs/roundtrip
roundtrips/sec
roundtrip-count
run-duration-sec)))
(define Tsummary (logbook-table E "client-summary" #:column-spec #f))
;; We work our way through these waypoints: start with one connection,
;; then 10, then 20, etc etc until we reach the end.
(define waypoints
(list 1 10 20 30 40 50 60 70 80 90 100 120
150 200 210 220 230 240 250 260 270 280 290 300 400
500 600 700 800 900
;; Here on up, increase by ~1.2× each time
1000 1200 1440 1728 2073
2488 2985 3583 4299 5159
6191 7430 8916 10699 12839
15407 18488 22186 26623 31947))
;; We exchange pings with the server for this many milliseconds before
;; moving up to the next waypoint.
(define ping-time 5000)
;; The ports representing a single connection.
(struct c (in out) #:transparent)
(define next-connection-id 0)
(define connections (hash))
;; Current number of open connections.
(define (connection-count)
(hash-count connections))
;; Ping a connection.
(define (ping-connection n)
(match-define (c in out) (hash-ref connections n))
(display "ping\n" out)
(flush-output out)
(define reply (read-line in 'any))
(when (not (equal? reply "ping"))
(error 'ping-connection "Bogus reply ~v from connection ~a" reply n)))
;; Choose a connection at random, and ping it.
(define (ping-one-at-random)
(ping-connection (random (connection-count))))
;; Start one connection.
(define (start-connection)
(define i next-connection-id)
(set! next-connection-id (+ i 1))
(define-values (in out) (tcp-connect server-hostname server-port))
(set! connections (hash-set connections i (c in out))))
;; Ping random connections for ping-time milliseconds.
(define (ping-randomly [record-results? #t])
(define start-time (current-inexact-milliseconds))
(let loop ((count 0))
(ping-one-at-random)
(define now (current-inexact-milliseconds))
(if (< now (+ start-time ping-time))
(loop (+ count 1))
(let* ((elapsed-sec (/ (- now start-time) 1000.0))
(roundtrip-latency (/ elapsed-sec count)))
(when record-results?
(write-logbook-datum! Tping (list (connection-count)
roundtrip-latency
(/ 1.0 roundtrip-latency)
count
elapsed-sec)))))))
;; Add connections until we hit the given waypoint.
(define (grow-to-waypoint waypoint)
(define old-count (connection-count))
(define start-time (current-inexact-milliseconds))
(let loop ()
(when (< (connection-count) waypoint)
(start-connection)
(loop)))
(ping-connection (- waypoint 1)) ;; make sure the newest connection is really live.
(define grow-complete-time (current-inexact-milliseconds))
(define elapsed-sec (/ (- grow-complete-time start-time) 1000.0))
(write-logbook-datum! Tgrowth (list old-count
(/ elapsed-sec (- waypoint old-count))
(/ (- waypoint old-count) elapsed-sec)
elapsed-sec
waypoint)))
(let loop ((remaining-waypoints waypoints))
(match remaining-waypoints
['() (void)]
[(cons next-waypoint rest)
(when (<= next-waypoint max-waypoint)
(grow-to-waypoint next-waypoint)
(log-info "At waypoint ~a" next-waypoint)
(when (equal? remaining-waypoints waypoints) ;; First ever waypoint. Do some warmup.
(log-info "Warming up.")
(ping-randomly #f)
(log-info "Warmup complete. Proceeding with real measurements."))
(ping-randomly)
(loop rest))]))
(let ()
(write-logbook-datum! Tsummary #:label "server-hostname" server-hostname)
(write-logbook-datum! Tsummary #:label "server-port" server-port)
(write-logbook-datum! Tsummary #:label "ping-time" ping-time)
(write-logbook-datum! Tsummary #:label "max-waypoint" max-waypoint)
(write-logbook-datum! Tsummary #:label "waypoints" waypoints)
(void))