;;; rpc-chain-bench.lsp — time N sequential RPC calls to a given port.
;;;
;;; Used to benchmark multi-hop S-expression relays. The same .lsp runs
;;; in all three impls, so the *client* is also portable — any impl
;;; can drive any chain.
;;;
;;; Override *target-port* / *n-requests* / *request* before load.
;;; Default: hit :9080 with (ping) 200 times.

(define *host* "127.0.0.1")
(define *target-port* 9080)
(define *n-requests* 200)
(define *request* "(ping)")

(define (one-call)
  (let ((s (tcp-connect *host* *target-port*)))
    (tcp-send s *request*)
    (let ((r (tcp-recv s 8192)))
      (tcp-close s)
      (if (and r (> (string-length r) 0)) 1 0))))

(define (call-loop n ok snap)
  (if (= n 0) ok
      (let ((got (one-call)))
        (heap-restore snap)
        (call-loop (- n 1) (+ ok got) snap))))

(define t0 (current-time-ms))
(define ok (call-loop *n-requests* 0 (heap-snapshot)))
(define t1 (current-time-ms))
(define elapsed (- t1 t0))

(display "port     : ") (display *target-port*) (newline)
(display "requests : ") (display *n-requests*) (newline)
(display "ok       : ") (display ok) (newline)
(display "elapsed  : ") (display elapsed) (display " ms") (newline)
(display "rps      : ")
(display (if (> elapsed 0) (quotient (* *n-requests* 1000) elapsed) 0))
(newline)
