summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS6
-rw-r--r--doc/api-dist.texi12
-rw-r--r--modules/ssh/dist/node.scm30
3 files changed, 39 insertions, 9 deletions
diff --git a/NEWS b/NEWS
index f48dffb..1f2da02 100644
--- a/NEWS
+++ b/NEWS
@@ -31,12 +31,14 @@ Copyright (C) Artyom V. Poptsov <poptsov.artyom@gmail.com>
'with-ssh' now returns a vector of values if an expression was evaluated to
multiple values. 'distribute' and 'dist-map' only take the 1st value if
multiple values were returned by an expression.
-** Nodes are now capable of starting a remote REPL (RREPL)
- The new behaviour is controlled by 'start-repl-server?' keyed option.
+** Nodes are now capable of starting and stopping a remote REPL (RREPL)
+ The new behaviour is controlled by 'start-repl-server?' and
+ 'stop-repl-server?' keyed options of 'make-node'.
** Channels now can be created as input, output or bi-drectional ports
** New procedures
*** New procedure 'node-server-running?' in (ssh dist node)
*** New procedure 'node-run-server' in (ssh dist node)
+*** New procedure 'node-stop-server' in (ssh dist node)
*** New procedure 'session-parse-config!' in (ssh session)
** New modules
*** (ssh popen)
diff --git a/doc/api-dist.texi b/doc/api-dist.texi
index c6dcc8f..6561c26 100644
--- a/doc/api-dist.texi
+++ b/doc/api-dist.texi
@@ -23,13 +23,19 @@ instead of @code{#<unspecified>}.
Node management procedures:
-@deffn {Scheme Procedure} make-node session [repl-port=37146] [#:start-repl-server?=#t]
+@deffn {Scheme Procedure} make-node session [repl-port=37146] [#:start-repl-server?=#t] [#:stop-repl-server?=#f]
Make a new node that uses an SSH @var{session} to connect to a @var{repl-port}
number on the remote side. Return a new node.
If @var{start-repl-server?} is set to @code{#t} (which is by default) then
start a REPL server on a remote host automatically in case when it is not
started yet.
+
+If @var{stop-repl-server?} is set to #t then a REPL server will be stopped as
+soon as an evaluation is done. Alternatively you could use
+@code{node-stop-server} procedure from @code{(ssh dist node)} to stop the
+server when it is not needed anymore.
+
@end deffn
@deffn {Scheme Procedure} node? x
@@ -161,6 +167,10 @@ Open a remote REPL (RREPL). Return a new RREPL channel.
Run a REPL server on a @var{node}.
@end deffn
+@deffn {Scheme Procedure} node-stop-server node
+Stop a RREPL server on a @var{node}.
+@end deffn
+
@deffn {Scheme Procedure} node-guile-version node
Get Guile version installed on a @var{node}, return the version string.
Return @code{#f} if Guile is not installed.
diff --git a/modules/ssh/dist/node.scm b/modules/ssh/dist/node.scm
index d90cfef..2be88d8 100644
--- a/modules/ssh/dist/node.scm
+++ b/modules/ssh/dist/node.scm
@@ -68,6 +68,7 @@
node-eval-1
node-guile-version
node-run-server
+ node-stop-server
node-server-running?
node-open-rrepl
@@ -95,11 +96,12 @@
;;; Node type
(define-record-type <node>
- (%make-node tunnel repl-port start-repl-server?)
+ (%make-node tunnel repl-port start-repl-server? stop-repl-server?)
node?
(tunnel node-tunnel) ; <tunnel>
(repl-port node-repl-port) ; number
- (start-repl-server? node-start-repl-server?)) ; boolean
+ (start-repl-server? node-start-repl-server?) ; boolean
+ (stop-repl-server? node-stop-repl-server?)) ; boolean
(define (node-session node)
"Get node session."
@@ -118,15 +120,17 @@
(define* (make-node session #:optional (repl-port 37146)
- #:key (start-repl-server? #t))
+ #:key (start-repl-server? #t)
+ (stop-repl-server? #f))
"Make a new distributed computing node. If START-REPL-SERVER? is set to
#t (which is by default) then start a REPL server on a remote host
-automatically in case when it is not started yet."
+automatically in case when it is not started yet. If STOP-REPL-SERVER? is set
+to #t then a REPL server will be stopped as soon as an evaluation is done."
(let ((tunnel (make-tunnel session
#:port 0 ;Won't be used
#:host "localhost"
#:host-port repl-port)))
- (%make-node tunnel repl-port start-repl-server?)))
+ (%make-node tunnel repl-port start-repl-server? stop-repl-server?)))
;;; Remote REPL (RREPL)
@@ -268,6 +272,7 @@ listens on an expected port, return #f otherwise."
(and (not (eof-object? line))
(string-match "^GNU Guile .*" line))))))))
+
(define (node-run-server node)
"Run a RREPL server on a NODE."
(open-remote-input-pipe (node-session node)
@@ -276,6 +281,15 @@ listens on an expected port, return #f otherwise."
(while (not (node-server-running? node))
(usleep 100)))
+(define (node-stop-server node)
+ "Stop a RREPL server on a NODE."
+ (close (open-remote-input-pipe (node-session node)
+ (format #f "pkill --full 'guile --listen=~a'"
+ (node-repl-port node))))
+ (while (node-server-running? node)
+ (sleep 1)))
+
+
(define (node-open-rrepl node)
"Open a RREPL. Return a new RREPL channel."
(and (node-start-repl-server? node)
@@ -288,7 +302,11 @@ listens on an expected port, return #f otherwise."
"Evaluate QUOTED-EXP on the node and return the evaluated result."
(let ((repl-channel (node-open-rrepl node)))
(rrepl-skip-to-prompt repl-channel)
- (rrepl-eval repl-channel quoted-exp)))
+ (call-with-values (lambda () (rrepl-eval repl-channel quoted-exp))
+ (lambda vals
+ (and (node-stop-repl-server? node)
+ (node-stop-server node))
+ (apply values vals)))))
(define (node-eval-1 node quoted-exp)
"Evaluate QUOTED-EXP on the node and return the evaluated result. The