[Small-cl-src] prefork-client.lisp

Thomas F. Burdick tfb at OCF.Berkeley.EDU
Fri Jun 4 22:33:20 UTC 2004


;;;; prefork-client.lisp
;;;;
;;;; A very simple SBCL network client for use in testing the servers in
;;;; prefork-example-simple.lisp and prefork-example-realistic.lisp.

;;;; Copyright (C) 2004, Thomas F. Burdick
;;;; 
;;;; Permission is hereby granted, free of charge, to any person obtaining a
;;;; copy of this software and associated documentation files (the "Software"),
;;;; to deal in the Software without restriction, including without limitation
;;;; the rights to use, copy, modify, merge, publish, distribute, sublicense,
;;;; and/or sell copies of the Software, and to permit persons to whom the
;;;; Software is furnished to do so, subject to the following conditions:
;;;; 
;;;; The above copyright notice and this permission notice shall be included in 
;;;; all copies or substantial portions of the Software.
;;;; 
;;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
;;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
;;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
;;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
;;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
;;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
;;;; IN THE SOFTWARE.

(in-package :cl-user)

(eval-when (:load-toplevel :compile-toplevel :execute)
  (require :sb-posix)
  (require :sb-bsd-sockets)
  (use-package :sb-bsd-sockets))

;;; The client is broken across many functions in order to make it easier to
;;; poke at the server.
;;;
;;; We send a line identifying ourselves, then an s-expression.  The server
;;; identifies itself, then sends our s-expression back to us.

(defvar *socket* nil)
(defvar *stream* nil)

(defun client (&optional object)
  "Return the echo from the server as multiple values."
  (client-connect)
  (client-herald)
  (client-write (with-output-to-string (s) (print object s)))
  (multiple-value-prog1 (client-results)
    (socket-close *socket*)))

;;;
;;; Easily hang server processes
;;; 

(defvar *hung* (queue))

(defun hang (&optional (n 1))
  "Send N partial requests to the server, causing the processes to hang."
  (dotimes (i n)
    (let (*socket* *stream*)
      (client-connect)
      (client-herald)
      (client-write "(:hang ")
      (queue-add (cons *socket* *stream*) *hung*))))

(defun release (&optional (n 1))
  "Send the rest of a proper request to N hung servers."
  (loop repeat n
        for pair = (queue-pop *hung*)
        when pair collect (destructuring-bind (*socket* . *stream*) pair
			    (client-write ":release) ")
			    (client-results))))

;;;
;;; The guts
;;; 

(defun client-connect ()
  (setf *socket* (make-instance 'inet-socket :type :stream :protocol :tcp))
  (socket-connect *socket* (make-inet-address "127.0.0.1") 1978)
  (setf *stream* (socket-make-stream *socket* :input t :output t)))
  
(defun client-herald ()
  (format *stream* "PID ~D~%" (sb-posix:getpid))
  (finish-output *stream*))
      
(defun client-write (string)
  "Send STRING to the server.  If this is an incomplete sexp, it can be used to
hang the server."
  (write-string string *stream*)
  (finish-output *stream*))

(defun client-results ()
  (values (read-line *stream*)
	  (read *stream*)))

;;;
;;; Misc utils
;;; 

(defstruct (queue (:constructor %make-queue (list tail)))
  (list nil :type list)
  (tail nil :type list))

(defun queue (&rest elements)
  (make-queue elements))

(defun make-queue (&optional list)
  (%make-queue list (last list)))

(defun queue-add (item queue)
  (if (null (queue-tail queue))
      (setf (queue-list queue) (list item)
	    (queue-tail queue) (queue-list queue))
      (setf (cdr (queue-tail queue)) (list item)
	    (queue-tail queue) (cdr (queue-tail queue))))
  queue)

(defun queue-pop (queue)
  (prog1
      (pop (queue-list queue))
    (when (null (queue-list queue))
      (setf (queue-tail queue) nil))))




More information about the Small-cl-src mailing list