ping-client.scm 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. ;;; Simple ping client implementation
  2. ;; Copyright (C) 2012 Free Software Foundation, Inc.
  3. ;; This library is free software; you can redistribute it and/or
  4. ;; modify it under the terms of the GNU Lesser General Public
  5. ;; License as published by the Free Software Foundation; either
  6. ;; version 3 of the License, or (at your option) any later version.
  7. ;;
  8. ;; This library is distributed in the hope that it will be useful,
  9. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. ;; Lesser General Public License for more details.
  12. ;;
  13. ;; You should have received a copy of the GNU Lesser General Public
  14. ;; License along with this library; if not, write to the Free Software
  15. ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  16. ;; 02110-1301 USA
  17. (use-modules (rnrs bytevectors)
  18. (fibers)
  19. (fibers channels)
  20. (ice-9 binary-ports)
  21. (ice-9 textual-ports)
  22. (ice-9 rdelim)
  23. (ice-9 match))
  24. (define (connect-to-server addrinfo)
  25. (let ((port (socket (addrinfo:fam addrinfo)
  26. (addrinfo:socktype addrinfo)
  27. (addrinfo:protocol addrinfo))))
  28. ;; Disable Nagle's algorithm. We buffer ourselves.
  29. (setsockopt port IPPROTO_TCP TCP_NODELAY 1)
  30. (fcntl port F_SETFL (logior O_NONBLOCK (fcntl port F_GETFL)))
  31. (setvbuf port 'block 1024)
  32. (connect port (addrinfo:addr addrinfo))
  33. port))
  34. (define (client-loop addrinfo n num-connections)
  35. (let ((port (connect-to-server addrinfo))
  36. (test (string-append "test-" (number->string n))))
  37. (let lp ((m 0))
  38. (when (< m num-connections)
  39. (put-string port test)
  40. (put-char port #\newline)
  41. (force-output port)
  42. (let ((response (read-line port)))
  43. (unless (equal? test response)
  44. (close-port port)
  45. (error "Bad response: ~A (expected ~A)" response test))
  46. (lp (1+ m)))))
  47. (close-port port)))
  48. (define (run-ping-test num-clients num-connections)
  49. ;; The getaddrinfo call blocks, unfortunately. Call it once before
  50. ;; spawning clients.
  51. (let ((addrinfo (car (getaddrinfo "localhost" (number->string 11211)))))
  52. (map get-message
  53. (map (lambda (n)
  54. (let ((ch (make-channel)))
  55. (spawn-fiber
  56. (lambda ()
  57. (client-loop addrinfo n num-connections)
  58. (put-message ch 'done))
  59. #:parallel? #t)
  60. ch))
  61. (iota num-clients)))))
  62. (run-fibers
  63. (lambda ()
  64. (apply run-ping-test (map string->number (cdr (program-arguments))))))