From e16efaf6603c4da33b74b499e0e1214c46ddf72d Mon Sep 17 00:00:00 2001
From: Adam Chlipala <adam@chlipala.net>
Date: Wed, 17 Jul 2019 14:28:46 -0400
Subject: New JavaScript FFI function 'listen'

---
 doc/manual.tex | 1 +
 1 file changed, 1 insertion(+)

(limited to 'doc/manual.tex')

diff --git a/doc/manual.tex b/doc/manual.tex
index ba53f5d8..62b322ae 100644
--- a/doc/manual.tex
+++ b/doc/manual.tex
@@ -2573,6 +2573,7 @@ It is possible to write JavaScript FFI code that interacts with the functional-r
   \item \cd{sr(v)} and \cd{sb(s, f)}, the ``return'' and ``bind'' monad operators, respectively
   \item \cd{ss(s)}, to produce the signal corresponding to source \cd{s}
   \item \cd{scur(s)}, to get the current value of signal \cd{s}
+  \item \cd{listen(s, f)}, to ask that function \cd{f} be called with the current value of \cd{s}, every time it changes, including immediately upon establishing this listener
   \end{itemize}
 
 \item The behavior of the \cd{<dyn>} pseudo-tag may be mimicked by following the right convention in a piece of HTML source code with a type like $\mt{xbody}$.  Such a piece of source code may be encoded with a JavaScript string.  To insert a dynamic section, include a \cd{<script>} tag whose content is just a call \cd{dyn(pnode, s)}.  The argument \cd{pnode} specifies what the relevant enclosing parent tag is.  Use value \cd{"tr"} when the immediate parent is \cd{<tr>}, use \cd{"table"} when the immediate parent is \cd{<table>}, and use \cd{"span"} otherwise.  The argument \cd{s} is a string-valued signal giving the HTML code to be inserted at this point.  As with the usual \cd{<dyn>} tag, that HTML subtree is automatically updated as the value of \cd{s} changes.
-- 
cgit v1.2.3


From f54687e989372470c2848890e9499feb9fd70352 Mon Sep 17 00:00:00 2001
From: Adam Chlipala <adam@chlipala.net>
Date: Fri, 30 Aug 2019 17:15:48 -0400
Subject: urweb daemon restart

---
 doc/manual.tex     |  4 ++++
 src/main.mlton.sml | 15 ++++++++++-----
 2 files changed, 14 insertions(+), 5 deletions(-)

(limited to 'doc/manual.tex')

diff --git a/doc/manual.tex b/doc/manual.tex
index 62b322ae..64fe0f24 100644
--- a/doc/manual.tex
+++ b/doc/manual.tex
@@ -238,6 +238,10 @@ Further \cd{urweb} invocations in the same working directory will send requests
 \begin{verbatim}
 urweb daemon stop
 \end{verbatim}
+To restart a running (or crashed) daemon, run
+\begin{verbatim}
+urweb daemon restart
+\end{verbatim}
 Communication happens via a UNIX domain socket in file \cd{.urweb\_daemon} in the working directory.
 
 \medskip
diff --git a/src/main.mlton.sml b/src/main.mlton.sml
index e9317d46..a6eaa7ea 100644
--- a/src/main.mlton.sml
+++ b/src/main.mlton.sml
@@ -107,6 +107,8 @@ fun usage flag_info =
 
 (* Encapsulate main invocation handler in a function, possibly to be called multiple times within a daemon. *)
 
+exception DaemonExit
+
 fun oneRun args =
     let
         val timing = ref false
@@ -256,7 +258,7 @@ fun oneRun args =
 
         val () = case args of
                      ["daemon", "stop"] => (OS.FileSys.remove socket handle OS.SysErr _ => ();
-                                            OS.Process.exit OS.Process.success)
+                                            raise DaemonExit)
                    | _ => ()
 
         val sources = parse_flags (flag_info ()) args
@@ -360,7 +362,7 @@ fun startDaemon () =
                                                    OS.Process.exit OS.Process.success)
                                                 | _ =>
                                                   let
-                                                      val success = (oneRun (rev args))
+                                                      val success = (oneRun (rev args) handle DaemonExit => OS.Process.exit OS.Process.success)
                                                                     handle ex => (print "unhandled exception:\n";
                                                                                   print (General.exnMessage ex ^ "\n");
                                                                                   OS.Process.failure)
@@ -445,9 +447,12 @@ fun oneCommandLine args =
         else
             (OS.FileSys.remove socket;
              raise OS.SysErr ("", NONE))
-    end handle OS.SysErr _ => oneRun args
+    end handle OS.SysErr _ => oneRun args handle DaemonExit => OS.Process.success
             
 val () = (Globals.setResetTime ();
           case CommandLine.arguments () of
-             ["daemon", "start"] => startDaemon ()
-           | args => OS.Process.exit (oneCommandLine args))
+              ["daemon", "start"] => startDaemon ()
+            | ["daemon", "restart"] =>
+              (ignore (oneCommandLine ["daemon", "stop"]);
+               startDaemon ())
+            | args => OS.Process.exit (oneCommandLine args))
-- 
cgit v1.2.3

