Send error replies on disconnection 51/16251/2
authorJose Bollo <jose.bollo@iot.bzh>
Mon, 20 Aug 2018 15:45:42 +0000 (17:45 +0200)
committerJosé Bollo <jose.bollo@iot.bzh>
Thu, 23 Aug 2018 06:35:38 +0000 (08:35 +0200)
The pending calls receive an error notification
when the server hang up.

Bug-AGL: SPEC-1668

Change-Id: I052dca5e338a7650d7630856e21f1d3a81c6f265
Signed-off-by: Jose Bollo <jose.bollo@iot.bzh>
src/afb-proto-ws.c
src/afb-stub-ws.c
src/afb-wsj1.c
test/AFB.js
test/monitoring/AFB.js

index c079bf6..89d4522 100644 (file)
@@ -89,7 +89,7 @@ For the purpose of handling events the server can:
 struct client_call {
        struct client_call *next;       /* the next call */
        struct afb_proto_ws *protows;   /* the proto_ws */
-       void *request;
+       void *request;                  /* the request closure */
        uint32_t callid;                /* the message identifier */
 };
 
@@ -936,8 +936,18 @@ static void on_hangup(void *closure)
 {
        struct afb_proto_ws *protows = closure;
        struct client_describe *cd, *ncd;
+       struct client_call *call, *ncall;
+
+       ncd = __atomic_exchange_n(&protows->describes, NULL, __ATOMIC_RELAXED);
+       ncall = __atomic_exchange_n(&protows->calls, NULL, __ATOMIC_RELAXED);
+
+       while (ncall) {
+               call= ncall;
+               ncall = call->next;
+               protows->client_itf->on_reply(protows->closure, call->request, NULL, "disconnected", "server hung up");
+               free(call);
+       }
 
-       ncd = protows->describes;
        while (ncd) {
                cd= ncd;
                ncd = cd->next;
index 10b3fc7..ae83e53 100644 (file)
@@ -430,8 +430,7 @@ static void release_all_sessions(struct afb_stub_ws *stubws)
 {
        struct server_session *s, *n;
 
-       s = stubws->sessions;
-       stubws->sessions = NULL;
+       s = __atomic_exchange_n(&stubws->sessions, NULL, __ATOMIC_RELAXED);
        while(s) {
                n = s->next;
                afb_session_unref(s->session);
index 73242e3..7fb8516 100644 (file)
@@ -44,6 +44,7 @@
 
 static void wsj1_on_hangup(struct afb_wsj1 *wsj1);
 static void wsj1_on_text(struct afb_wsj1 *wsj1, char *text, size_t size);
+static struct afb_wsj1_msg *wsj1_msg_make(struct afb_wsj1 *wsj1, char *text, size_t size);
 
 static struct afb_ws_itf wsj1_itf = {
        .on_hangup = (void*)wsj1_on_hangup,
@@ -141,6 +142,32 @@ void afb_wsj1_unref(struct afb_wsj1 *wsj1)
 
 static void wsj1_on_hangup(struct afb_wsj1 *wsj1)
 {
+       struct wsj1_call *call, *ncall;
+       struct afb_wsj1_msg *msg;
+       char *text;
+       int len;
+
+       static const char error_object_str[] = "{"
+               "\"jtype\":\"afb-reply\","
+               "\"request\":{"
+                       "\"status\":\"disconnected\","
+                       "\"info\":\"server hung up\"}}";
+
+       ncall = __atomic_exchange_n(&wsj1->calls, NULL, __ATOMIC_RELAXED);
+       while (ncall) {
+               call = ncall;
+               ncall = call->next;
+               len = asprintf(&text, "[%d,\"%s\",%s]", RETERR, call->id, error_object_str);
+               if (len > 0) {
+                       msg = wsj1_msg_make(wsj1, text, (size_t)len);
+                       if (msg != NULL) {
+                               call->callback(call->closure, msg);
+                               afb_wsj1_msg_unref(msg);
+                       }
+               }
+               free(call);
+       }
+
        if (wsj1->itf->on_hangup != NULL)
                wsj1->itf->on_hangup(wsj1->closure, wsj1);
 }
index 8fccdb0..aa63416 100644 (file)
@@ -67,12 +67,13 @@ var AFB_websocket;
        var PROTO1 = "x-afb-ws-json1";
 
        AFB_websocket = function(on_open, on_abort) {
-               var u = urlws;
+               var u = urlws, p = '?';
                if (AFB_context.token) {
                        u = u + '?x-afb-token=' + AFB_context.token;
-                       if (AFB_context.uuid)
-                               u = u + '&x-afb-uuid=' + AFB_context.uuid;
+                       p = '&';
                }
+               if (AFB_context.uuid)
+                       u = u + p + 'x-afb-uuid=' + AFB_context.uuid;
                this.ws = new WebSocket(u, [ PROTO1 ]);
                this.url = u;
                this.pendings = {};
@@ -104,8 +105,15 @@ var AFB_websocket;
        }
 
        function onclose(event) {
+               var err = {
+                       jtype: 'afb-reply',
+                       request: {
+                               status: 'disconnected',
+                               info: 'server hung up'
+                       }
+               };
                for (var id in this.pendings) {
-                       try { this.pendings[id][1](); } catch (x) {/*TODO?*/}
+                       try { this.pendings[id][1](err); } catch (x) {/*NOTHING*/}
                }
                this.pendings = {};
                this.onclose && this.onclose();
index 8fccdb0..aa63416 100644 (file)
@@ -67,12 +67,13 @@ var AFB_websocket;
        var PROTO1 = "x-afb-ws-json1";
 
        AFB_websocket = function(on_open, on_abort) {
-               var u = urlws;
+               var u = urlws, p = '?';
                if (AFB_context.token) {
                        u = u + '?x-afb-token=' + AFB_context.token;
-                       if (AFB_context.uuid)
-                               u = u + '&x-afb-uuid=' + AFB_context.uuid;
+                       p = '&';
                }
+               if (AFB_context.uuid)
+                       u = u + p + 'x-afb-uuid=' + AFB_context.uuid;
                this.ws = new WebSocket(u, [ PROTO1 ]);
                this.url = u;
                this.pendings = {};
@@ -104,8 +105,15 @@ var AFB_websocket;
        }
 
        function onclose(event) {
+               var err = {
+                       jtype: 'afb-reply',
+                       request: {
+                               status: 'disconnected',
+                               info: 'server hung up'
+                       }
+               };
                for (var id in this.pendings) {
-                       try { this.pendings[id][1](); } catch (x) {/*TODO?*/}
+                       try { this.pendings[id][1](err); } catch (x) {/*NOTHING*/}
                }
                this.pendings = {};
                this.onclose && this.onclose();