aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJose Bollo <jose.bollo@iot.bzh>2018-08-20 17:45:42 +0200
committerJosé Bollo <jose.bollo@iot.bzh>2018-08-23 08:35:38 +0200
commite36f8d572ca660f5c06fe45297d13c7a6818cc65 (patch)
tree51cf8b93d3d7a636d2f6fbab8057f10ee0f3ef0d
parenta1a507793efff92b35603e4948e9f6dff4fba99c (diff)
Send error replies on disconnection
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>
-rw-r--r--src/afb-proto-ws.c14
-rw-r--r--src/afb-stub-ws.c3
-rw-r--r--src/afb-wsj1.c27
-rw-r--r--test/AFB.js16
-rw-r--r--test/monitoring/AFB.js16
5 files changed, 64 insertions, 12 deletions
diff --git a/src/afb-proto-ws.c b/src/afb-proto-ws.c
index c079bf69..89d4522c 100644
--- a/src/afb-proto-ws.c
+++ b/src/afb-proto-ws.c
@@ -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;
diff --git a/src/afb-stub-ws.c b/src/afb-stub-ws.c
index 10b3fc77..ae83e534 100644
--- a/src/afb-stub-ws.c
+++ b/src/afb-stub-ws.c
@@ -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);
diff --git a/src/afb-wsj1.c b/src/afb-wsj1.c
index 73242e34..7fb85169 100644
--- a/src/afb-wsj1.c
+++ b/src/afb-wsj1.c
@@ -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);
}
diff --git a/test/AFB.js b/test/AFB.js
index 8fccdb04..aa634168 100644
--- a/test/AFB.js
+++ b/test/AFB.js
@@ -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();
diff --git a/test/monitoring/AFB.js b/test/monitoring/AFB.js
index 8fccdb04..aa634168 100644
--- a/test/monitoring/AFB.js
+++ b/test/monitoring/AFB.js
@@ -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();