Skip to content
Permalink
Browse files

Remove connect-local-workers. Use connect-workers instead.

Pick server ports dynamically in the test code.
  • Loading branch information...
brown committed Apr 28, 2014
1 parent 553be43 commit 5da521a5f2b28205c78b50c0b3f0ac44bc39cc26
Showing with 33 additions and 44 deletions.
  1. +1 −3 README
  2. +0 −11 master.lisp
  3. +0 −1 package.lisp
  4. +1 −1 swank-crew.asd
  5. +31 −28 swank-crew_test.lisp
4 README
@@ -16,10 +16,8 @@ using your existing Slime connection to the master.
The Swank Crew API
==================

connect-local-workers Create a worker pool containing a set of worker
Lisps running on localhost.
connect-workers Create a worker pool containing a set of worker
Lisps running on remote hosts.
Lisps.
disconnect-workers Disconnect all the workers in a worker pool.
eval-form-all-workers Evaluate a form on all the workers in a worker pool.
eval-form-repeatedly Evaluate a form repeatedly on the workers in a pool
@@ -189,17 +189,6 @@ that it is invoked when the connection closes."))
(defmethod connect-worker ((connect-info connect-info) close-handler)
(swank-client:slime-connect (host-name connect-info) (port connect-info) close-handler))

(defun connect-local-workers (base-port worker-count)
"Makes Swank connections to WORKER-COUNT workers on \"localhost\" and returns
a WORKER-POOL containing them. The Swank servers for the workers must be
listening on WORKER-COUNT consecutively numbered ports, starting from
BASE-PORT."
(let ((connect-infos
(loop repeat worker-count
for port from base-port
collect (make-instance 'connect-info :host-name "localhost" :port port))))
(make-worker-pool connect-infos #'connect-worker)))

(defun connect-workers (host/port-alist)
"Makes Swank connections to all the workers in HOST/PORT-ALIST and returns a
WORKER-POOL containing them. HOST/PORT-ALIST is a list of (host-name . port)
@@ -37,7 +37,6 @@
#:com.google.flag)
;; master.lisp
(:export #:*rex-port*
#:connect-local-workers
#:connect-workers
#:disconnect-workers
#:eval-form-all-workers
@@ -35,7 +35,7 @@
"Swank Crew is a framework for developing distributed master/worker
applications. It uses Slime's Swank protocol to transport data between
machines, making the debugging of distributed applications easier."
:version "1.1"
:version "1.3"
:author "Robert Brown"
:license "New BSD license. See the copyright messages in individual files."
:depends-on (bordeaux-threads
@@ -133,49 +133,52 @@

;;; Code to create a locally running Swank master and several Swank workers.

(defconst +master-port+ 12345)
(defvar *server-port* 10000)

(defun unused-port ()
#+google3 (port-picker:unused-port)
#-google3 (incf *server-port*))

(defvar *master-server* nil)

(defun ensure-master-server (port)
(defun master-server ()
(unless *master-server*
(let ((swank::*loopback-interface* (osicat-posix:gethostname)))
(swank:create-server :port port :dont-close t))
(setf *master-server* t)))

(defconst +worker-base-port+ 12346)

(defun create-workers (base-port worker-count)
"Creates WORKER-COUNT workers, each running in a thread and listening on a
separate port number starting with BASE-PORT."
(let ((swank::*loopback-interface* (osicat-posix:gethostname)) ; XXXXXXXXXXXXXXXXXXXX
(port (unused-port)))
(is port)
(swank:create-server :port port :dont-close t)
(setf *master-server* port)))
*master-server*)

(defun create-workers (worker-count)
"Creates WORKER-COUNT worker threads, each running a Swank server. Returns a
list of the ports the Swank servers are listening on."
(loop repeat worker-count
for port from base-port
do (let ((port port)
;; Make thread-local copies of the global state required for each worker, so
;; multiple workers can run happily in the same Lisp.
(swank-crew::*replay-forms-counts-lock* (bordeaux-threads:make-lock))
(swank-crew::*replay-forms-counts* (make-hash-table)))
(bordeaux-threads:make-thread (lambda () (swank:create-server :port port))
:name (format nil "local worker ~D" port)))))
collect (let ((swank-port (unused-port))
;; Make thread-local copies of the global state required for each worker, so
;; multiple workers can run happily in the same Lisp.
(swank-crew::*replay-forms-counts-lock* (bordeaux-threads:make-lock))
(swank-crew::*replay-forms-counts* (make-hash-table)))
(bordeaux-threads:make-thread (lambda () (swank:create-server :port swank-port))
:name (format nil "local worker ~D" swank-port))
(cons "localhost" swank-port))))

(defmacro with-local-workers ((pool worker-count) &body body)
"Wraps BODY in a LET form where POOL is bound to a newly created worker pool
containing WORKER-COUNT workers, each running in a thread. Arranges for the
workers to be disconnected when control exits BODY."
`(let ((*rex-port* +master-port+))
(ensure-master-server +master-port+)
(create-workers +worker-base-port+ ,worker-count)
(let ((,pool (connect-local-workers +worker-base-port+ ,worker-count)))
(unwind-protect
(progn ,@body)
(when ,pool
(disconnect-workers ,pool))))))
`(let* ((*rex-port* (master-server))
(,pool (connect-workers (create-workers ,worker-count))))
(unwind-protect
(progn ,@body)
(when ,pool
(disconnect-workers ,pool)))))

;;; Tests that use a local worker pool, where each worker runs in a thread.

(deftest test-connect-to-master ()
(with-local-workers (pool 3)
(swank-client:with-slime-connection (master (osicat-posix:gethostname) +master-port+)
(swank-client:with-slime-connection (master (osicat-posix:gethostname) (master-server))
(is (= (swank-client:slime-eval '(+ 1 1) master) 2)))
(is (= (worker-count pool) 3))))

0 comments on commit 5da521a

Please sign in to comment.
You can’t perform that action at this time.