changeset 1447:17393c5e2b90

Send newly created sources with messages to clients
author Adam Chlipala <adam@chlipala.net>
date Sat, 09 Apr 2011 20:00:52 -0400
parents 36f7d1debb37
children 37599e85bba8
files lib/js/urweb.js src/c/http.c src/c/urweb.c tests/ms.ur tests/ms.urp tests/ms.urs
diffstat 6 files changed, 87 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/lib/js/urweb.js	Sat Apr 09 14:36:47 2011 -0400
+++ b/lib/js/urweb.js	Sat Apr 09 20:00:52 2011 -0400
@@ -817,7 +817,7 @@
             } catch (e) { }
 
             if (isok) {
-                var text = xhr.responseText
+                var text = xhr.responseText;
                 if (text == "")
                     return;
                 var lines = text.split("\n");
@@ -827,36 +827,47 @@
                     return;
                 }
 
-                for (var i = 0; i+1 < lines.length; i += 2) {
-                    var chn = lines[i];
-                    var msg = lines[i+1];
+                var messageReader = function(i) {
+                    if (i+1 >= lines.length) {
+                        xhrFinished(xhr);
+                        connect();
+                    }
+                    else {
+                        var chn = lines[i];
+                        var msg = lines[i+1];
 
-                    if (chn < 0)
-                        whine("Out-of-bounds channel in message from remote server");
+                        if (chn == "E") {
+                            eval(msg);
+                            window.setTimeout(function() { messageReader(i+2); }, 0);
+                        } else {
+                            if (chn < 0)
+                                whine("Out-of-bounds channel in message from remote server");
 
-                    var ch;
+                            var ch;
 
-                    if (chn >= channels.length || channels[chn] == null) {
-                        ch = newChannel();
-                        channels[chn] = ch;
-                    } else
-                        ch = channels[chn];
+                            if (chn >= channels.length || channels[chn] == null) {
+                                ch = newChannel();
+                                channels[chn] = ch;
+                            } else
+                                ch = channels[chn];
 
-                    var listener = dequeue(ch.listeners);
-                    if (listener == null) {
-                        enqueue(ch.msgs, msg);
-                    } else {
-                        try {
-                            listener(msg);
-                        } catch (v) {
-                            doExn(v);
+                            var listener = dequeue(ch.listeners);
+                            if (listener == null) {
+                                enqueue(ch.msgs, msg);
+                            } else {
+                                try {
+                                    listener(msg);
+                                } catch (v) {
+                                    doExn(v);
+                                }
+                            }
+
+                            messageReader(i+2);
                         }
                     }
                 }
 
-                xhrFinished(xhr);
-
-                connect();
+                messageReader(0);
             }
             else {
                 try {
--- a/src/c/http.c	Sat Apr 09 14:36:47 2011 -0400
+++ b/src/c/http.c	Sat Apr 09 20:00:52 2011 -0400
@@ -198,7 +198,7 @@
                         on_success, on_failure,
                         NULL, log_error, log_debug,
                         sock, uw_really_send, close);
-        uw_send(ctx, sock);
+        if (rr != KEEP_OPEN) uw_send(ctx, sock);
 
         if (rr == SERVED || rr == FAILED)
           close(sock);
--- a/src/c/urweb.c	Sat Apr 09 14:36:47 2011 -0400
+++ b/src/c/urweb.c	Sat Apr 09 20:00:52 2011 -0400
@@ -311,16 +311,25 @@
   return ch;
 }
 
-static void client_send(client *c, uw_buffer *msg) {
+static void client_send(client *c, uw_buffer *msg, const char *script, int script_len) {
   pthread_mutex_lock(&c->lock);
 
   if (c->sock != -1) {
     c->send(c->sock, on_success, strlen(on_success));
     c->send(c->sock, begin_msgs, sizeof(begin_msgs) - 1);
+    if (script_len > 0) {
+      c->send(c->sock, "E\n", 2);
+      c->send(c->sock, script, script_len);
+      c->send(c->sock, "\n", 1);
+    }
     c->send(c->sock, msg->start, uw_buffer_used(msg));
     c->close(c->sock);
     c->sock = -1;
-  } else if (uw_buffer_append(&c->msgs, msg->start, uw_buffer_used(msg)))
+  } else if ((script_len > 0
+              && (c->send(c->sock, "E\n", 2)
+                  || c->send(c->sock, script, script_len)
+                  || c->send(c->sock, "\n", 1)))
+             || uw_buffer_append(&c->msgs, msg->start, uw_buffer_used(msg)))
     fprintf(stderr, "Client message buffer size exceeded");
 
   pthread_mutex_unlock(&c->lock);
@@ -3167,7 +3176,7 @@
 
     assert (c != NULL && c->mode == USED);
 
-    client_send(c, &d->msgs);
+    client_send(c, &d->msgs, ctx->script.start, uw_buffer_used(&ctx->script));
   }
 
   if (ctx->client)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/ms.ur	Sat Apr 09 20:00:52 2011 -0400
@@ -0,0 +1,35 @@
+table ms : {Client : client, Channel : channel xbody}
+
+val hitMe =
+    me <- self;
+    ch <- oneRowE1 (SELECT (ms.Channel)
+                    FROM ms
+                    WHERE ms.Client = {[me]});
+
+    s <- source 0;
+    send ch <xml>
+      <dyn signal={n <- signal s; return <xml>{[n]}</xml>}/>
+      <button value="Inc" onclick={n <- get s; set s (n + 1)}/>
+    </xml>
+
+fun main' () =
+    me <- self;
+    ch <- channel;
+    dml (INSERT INTO ms (Client, Channel) VALUES ({[me]}, {[ch]}));
+
+    s <- source <xml/>;
+
+    return <xml><body onload={let
+                                  fun loop () =
+                                      x <- recv ch;
+                                      set s x;
+                                      loop ()
+                              in
+                                  loop ()
+                              end}>
+      <button value="Another" onclick={rpc hitMe}/>
+      <dyn signal={signal s}/>
+    </body></xml>
+
+fun main () =
+    return <xml><body><form><submit action={main'}/></form></body></xml>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/ms.urp	Sat Apr 09 20:00:52 2011 -0400
@@ -0,0 +1,4 @@
+database dbname=test
+sql ms.sql
+
+ms
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/ms.urs	Sat Apr 09 20:00:52 2011 -0400
@@ -0,0 +1,1 @@
+val main : unit -> transaction page