agoo 2.9.0 → 2.10.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of agoo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/ext/agoo/con.c +104 -78
- data/ext/agoo/con.h +9 -4
- data/ext/agoo/debug.c +9 -9
- data/ext/agoo/debug.h +1 -0
- data/ext/agoo/error_stream.c +14 -6
- data/ext/agoo/gqleval.c +93 -14
- data/ext/agoo/gqlsub.c +37 -0
- data/ext/agoo/gqlsub.h +24 -0
- data/ext/agoo/gqlvalue.c +14 -0
- data/ext/agoo/gqlvalue.h +1 -0
- data/ext/agoo/graphql.c +13 -2
- data/ext/agoo/pub.c +0 -3
- data/ext/agoo/res.c +19 -5
- data/ext/agoo/res.h +1 -1
- data/ext/agoo/rgraphql.c +37 -0
- data/ext/agoo/rserver.c +26 -11
- data/ext/agoo/sdl.c +13 -13
- data/ext/agoo/sdl.h +2 -1
- data/ext/agoo/server.c +115 -0
- data/ext/agoo/server.h +8 -0
- data/ext/agoo/text.c +6 -4
- data/ext/agoo/websocket.c +9 -19
- data/lib/agoo/version.rb +1 -1
- data/test/rack_handler_test.rb +6 -1
- metadata +4 -2
data/ext/agoo/pub.c
CHANGED
@@ -75,8 +75,6 @@ agoo_pub_publish(const char *subject, int slen, const char *message, size_t mlen
|
|
75
75
|
|
76
76
|
agooPub
|
77
77
|
agoo_pub_write(agooUpgraded up, const char *message, size_t mlen, bool bin) {
|
78
|
-
// Allocate an extra 16 bytes so the message can be expanded in place if a
|
79
|
-
// WebSocket write.
|
80
78
|
agooPub p = (agooPub)AGOO_MALLOC(sizeof(struct _agooPub));
|
81
79
|
|
82
80
|
if (NULL != p) {
|
@@ -130,4 +128,3 @@ agoo_pub_destroy(agooPub pub) {
|
|
130
128
|
}
|
131
129
|
AGOO_FREE(pub);
|
132
130
|
}
|
133
|
-
|
data/ext/agoo/res.c
CHANGED
@@ -46,6 +46,7 @@ agoo_res_destroy(agooRes res) {
|
|
46
46
|
agoo_text_release(res->message);
|
47
47
|
}
|
48
48
|
res->next = NULL;
|
49
|
+
res->message = NULL;
|
49
50
|
pthread_mutex_lock(&res->con->loop->lock);
|
50
51
|
if (NULL == res->con->loop->res_tail) {
|
51
52
|
res->con->loop->res_head = res;
|
@@ -58,7 +59,7 @@ agoo_res_destroy(agooRes res) {
|
|
58
59
|
}
|
59
60
|
|
60
61
|
void
|
61
|
-
agoo_res_message_push(agooRes res, agooText t
|
62
|
+
agoo_res_message_push(agooRes res, agooText t) {
|
62
63
|
if (NULL != t) {
|
63
64
|
agoo_text_ref(t);
|
64
65
|
}
|
@@ -73,7 +74,7 @@ agoo_res_message_push(agooRes res, agooText t, bool final) {
|
|
73
74
|
}
|
74
75
|
end->next = t;
|
75
76
|
}
|
76
|
-
res->final =
|
77
|
+
res->final = true;
|
77
78
|
}
|
78
79
|
pthread_mutex_unlock(&res->lock);
|
79
80
|
}
|
@@ -91,7 +92,21 @@ agoo_res_add_early(agooRes res, agooEarly early) {
|
|
91
92
|
t = agoo_text_append(t, "\r\n", 2);
|
92
93
|
}
|
93
94
|
t = agoo_text_append(t, "\r\n", 2);
|
94
|
-
|
95
|
+
|
96
|
+
pthread_mutex_lock(&res->lock);
|
97
|
+
if (!res->final) {
|
98
|
+
if (NULL == res->message) {
|
99
|
+
res->message = t;
|
100
|
+
} else {
|
101
|
+
agooText end = res->message;
|
102
|
+
|
103
|
+
for (; NULL != end->next; end = end->next) {
|
104
|
+
}
|
105
|
+
end->next = t;
|
106
|
+
}
|
107
|
+
res->final = false;
|
108
|
+
}
|
109
|
+
pthread_mutex_unlock(&res->lock);
|
95
110
|
}
|
96
111
|
|
97
112
|
agooText
|
@@ -113,8 +128,7 @@ agoo_res_message_next(agooRes res) {
|
|
113
128
|
if (NULL != res->message) {
|
114
129
|
agooText t2 = res->message;
|
115
130
|
|
116
|
-
res->message =
|
117
|
-
// TBD make sure it is not release by the called, change code if it is
|
131
|
+
res->message = t2->next;
|
118
132
|
agoo_text_release(t2);
|
119
133
|
}
|
120
134
|
t = res->message;
|
data/ext/agoo/res.h
CHANGED
@@ -28,7 +28,7 @@ typedef struct _agooRes {
|
|
28
28
|
extern agooRes agoo_res_create(struct _agooCon *con);
|
29
29
|
extern void agoo_res_destroy(agooRes res);
|
30
30
|
|
31
|
-
extern void agoo_res_message_push(agooRes res, agooText t
|
31
|
+
extern void agoo_res_message_push(agooRes res, agooText t);
|
32
32
|
extern void agoo_res_add_early(agooRes res, agooEarly early);
|
33
33
|
extern agooText agoo_res_message_peek(agooRes res);
|
34
34
|
extern agooText agoo_res_message_next(agooRes res);
|
data/ext/agoo/rgraphql.c
CHANGED
@@ -12,7 +12,9 @@
|
|
12
12
|
#include "gqlintro.h"
|
13
13
|
#include "gqlvalue.h"
|
14
14
|
#include "graphql.h"
|
15
|
+
#include "pub.h"
|
15
16
|
#include "sdl.h"
|
17
|
+
#include "server.h"
|
16
18
|
|
17
19
|
typedef struct _eval {
|
18
20
|
gqlDoc doc;
|
@@ -423,6 +425,15 @@ resolve(agooErr err, gqlDoc doc, gqlRef target, gqlField field, gqlSel sel, gqlV
|
|
423
425
|
}
|
424
426
|
child = rb_funcall(obj, rb_intern(sel->name), 1, rargs);
|
425
427
|
}
|
428
|
+
if (GQL_SUBSCRIPTION == doc->op->kind && RUBY_T_STRING == rb_type(child)) {
|
429
|
+
gqlValue c;
|
430
|
+
|
431
|
+
if (NULL == (c = gql_string_create(err, rb_string_value_ptr(&child), RSTRING_LEN(child))) ||
|
432
|
+
AGOO_ERR_OK != gql_object_set(err, result, "subject", c)) {
|
433
|
+
return err->code;
|
434
|
+
}
|
435
|
+
return AGOO_ERR_OK;
|
436
|
+
}
|
426
437
|
if (NULL != sel->alias) {
|
427
438
|
key = sel->alias;
|
428
439
|
}
|
@@ -750,6 +761,30 @@ graphql_sdl_dump(VALUE self, VALUE options) {
|
|
750
761
|
return dump;
|
751
762
|
}
|
752
763
|
|
764
|
+
/* Document-method: publish
|
765
|
+
*
|
766
|
+
* call-seq: publish(subject, event)
|
767
|
+
*
|
768
|
+
* Publish an event on the given subject. A subject must be a String while the
|
769
|
+
* event must be one of the objects represented by the the GraphQL
|
770
|
+
* schema. Generally the subjects are selected to identify which objects are
|
771
|
+
* being published and should match the value returned by the subscription
|
772
|
+
* methods.
|
773
|
+
*/
|
774
|
+
static VALUE
|
775
|
+
graphql_publish(VALUE self, VALUE subject, VALUE event) {
|
776
|
+
const char *subj;
|
777
|
+
struct _agooErr err = AGOO_ERR_INIT;
|
778
|
+
|
779
|
+
rb_check_type(subject, T_STRING);
|
780
|
+
subj = StringValuePtr(subject);
|
781
|
+
|
782
|
+
if (AGOO_ERR_OK != agoo_server_gpublish(&err, subj, (gqlRef)event)) {
|
783
|
+
rb_raise(rb_eStandardError, "%s", err.msg);
|
784
|
+
}
|
785
|
+
return Qnil;
|
786
|
+
}
|
787
|
+
|
753
788
|
/* Document-class: Agoo::Graphql
|
754
789
|
*
|
755
790
|
* The Agoo::GraphQL class provides support for the GraphQL API as defined in
|
@@ -772,4 +807,6 @@ graphql_init(VALUE mod) {
|
|
772
807
|
rb_define_module_function(graphql_class, "load_file", graphql_load_file, 1);
|
773
808
|
|
774
809
|
rb_define_module_function(graphql_class, "sdl_dump", graphql_sdl_dump, 1);
|
810
|
+
|
811
|
+
rb_define_module_function(graphql_class, "publish", graphql_publish, 2);
|
775
812
|
}
|
data/ext/agoo/rserver.c
CHANGED
@@ -312,7 +312,7 @@ rescue_error(VALUE x) {
|
|
312
312
|
message = agoo_text_create(buf, cnt);
|
313
313
|
|
314
314
|
req->res->close = true;
|
315
|
-
agoo_res_message_push(req->res, message
|
315
|
+
agoo_res_message_push(req->res, message);
|
316
316
|
agoo_queue_wakeup(&agoo_server.con_queue);
|
317
317
|
} else {
|
318
318
|
/*
|
@@ -340,7 +340,7 @@ handle_base_inner(void *x) {
|
|
340
340
|
rb_funcall((VALUE)req->hook->handler, on_request_id, 2, rr, rres);
|
341
341
|
}
|
342
342
|
DATA_PTR(rr) = NULL;
|
343
|
-
agoo_res_message_push(req->res, response_text(rres)
|
343
|
+
agoo_res_message_push(req->res, response_text(rres));
|
344
344
|
agoo_queue_wakeup(&agoo_server.con_queue);
|
345
345
|
|
346
346
|
return Qfalse;
|
@@ -367,10 +367,25 @@ header_cb(VALUE key, VALUE value, agooText *tp) {
|
|
367
367
|
}
|
368
368
|
}
|
369
369
|
if (0 != strcasecmp("Content-Length", ks)) {
|
370
|
-
*
|
371
|
-
|
372
|
-
|
373
|
-
|
370
|
+
char *end = index(vs, '\n');
|
371
|
+
|
372
|
+
do {
|
373
|
+
end = index(vs, '\n');
|
374
|
+
*tp = agoo_text_append(*tp, ks, klen);
|
375
|
+
*tp = agoo_text_append(*tp, ": ", 2);
|
376
|
+
if (NULL == end) {
|
377
|
+
if (0 < vlen) {
|
378
|
+
*tp = agoo_text_append(*tp, vs, vlen);
|
379
|
+
}
|
380
|
+
} else {
|
381
|
+
if (vs < end) {
|
382
|
+
*tp = agoo_text_append(*tp, vs, end - vs);
|
383
|
+
}
|
384
|
+
vlen -= end - vs + 1;
|
385
|
+
vs = end + 1;
|
386
|
+
}
|
387
|
+
*tp = agoo_text_append(*tp, "\r\n", 2);
|
388
|
+
} while (NULL != end && 0 < vlen);
|
374
389
|
}
|
375
390
|
return ST_CONTINUE;
|
376
391
|
}
|
@@ -515,7 +530,7 @@ handle_rack_inner(void *x) {
|
|
515
530
|
req->hook = agoo_hook_create(AGOO_NONE, NULL, (void*)handler, PUSH_HOOK, &agoo_server.eval_queue);
|
516
531
|
rupgraded_create(req->res->con, handler, request_env(req, Qnil));
|
517
532
|
t = agoo_sse_upgrade(req, t);
|
518
|
-
agoo_res_message_push(req->res, t
|
533
|
+
agoo_res_message_push(req->res, t);
|
519
534
|
agoo_queue_wakeup(&agoo_server.con_queue);
|
520
535
|
return Qfalse;
|
521
536
|
default:
|
@@ -546,7 +561,7 @@ handle_rack_inner(void *x) {
|
|
546
561
|
rb_iterate(rb_each, bv, body_append_cb, (VALUE)&t);
|
547
562
|
}
|
548
563
|
}
|
549
|
-
agoo_res_message_push(req->res, t
|
564
|
+
agoo_res_message_push(req->res, t);
|
550
565
|
agoo_queue_wakeup(&agoo_server.con_queue);
|
551
566
|
|
552
567
|
return Qfalse;
|
@@ -572,7 +587,7 @@ handle_wab_inner(void *x) {
|
|
572
587
|
rb_funcall((VALUE)req->hook->handler, on_request_id, 2, rr, rres);
|
573
588
|
}
|
574
589
|
DATA_PTR(rr) = NULL;
|
575
|
-
agoo_res_message_push(req->res, response_text(rres)
|
590
|
+
agoo_res_message_push(req->res, response_text(rres));
|
576
591
|
agoo_queue_wakeup(&agoo_server.con_queue);
|
577
592
|
|
578
593
|
return Qfalse;
|
@@ -686,7 +701,7 @@ handle_protected(agooReq req, bool gvi) {
|
|
686
701
|
agooText message = agoo_text_create(buf, cnt);
|
687
702
|
|
688
703
|
req->res->close = true;
|
689
|
-
agoo_res_message_push(req->res, message
|
704
|
+
agoo_res_message_push(req->res, message);
|
690
705
|
agoo_queue_wakeup(&agoo_server.con_queue);
|
691
706
|
break;
|
692
707
|
}
|
@@ -1098,7 +1113,7 @@ domain(VALUE self, VALUE host, VALUE path) {
|
|
1098
1113
|
volatile VALUE v = rb_funcall(host, rb_intern("inspect"), 0);
|
1099
1114
|
char rx[1024];
|
1100
1115
|
|
1101
|
-
if (sizeof(rx) <= RSTRING_LEN(v)) {
|
1116
|
+
if (sizeof(rx) <= (size_t)RSTRING_LEN(v)) {
|
1102
1117
|
rb_raise(rb_eArgError, "host Regex limited to %ld characters", sizeof(rx));
|
1103
1118
|
}
|
1104
1119
|
strcpy(rx, rb_string_value_ptr((VALUE*)&v) + 1);
|
data/ext/agoo/sdl.c
CHANGED
@@ -1318,25 +1318,25 @@ make_sel(agooErr err, agooDoc doc, gqlDoc gdoc, gqlOp op, gqlSel *parentp) {
|
|
1318
1318
|
|
1319
1319
|
|
1320
1320
|
static int
|
1321
|
-
make_op(agooErr err, agooDoc doc, gqlDoc gdoc) {
|
1321
|
+
make_op(agooErr err, agooDoc doc, gqlDoc gdoc, gqlOpKind kind) {
|
1322
1322
|
char name[256];
|
1323
1323
|
const char *start;
|
1324
|
-
gqlOpKind kind;
|
1325
1324
|
gqlOp op;
|
1326
1325
|
size_t nlen;
|
1327
1326
|
|
1328
1327
|
agoo_doc_skip_white(doc);
|
1329
1328
|
start = doc->cur;
|
1330
1329
|
agoo_doc_read_token(doc);
|
1331
|
-
if (doc->cur
|
1332
|
-
(5 == (doc->cur - start) && 0 == strncmp(query_str, start, sizeof(query_str) - 1))
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1330
|
+
if ( start < doc->cur) {
|
1331
|
+
if (5 == (doc->cur - start) && 0 == strncmp(query_str, start, sizeof(query_str) - 1)) {
|
1332
|
+
kind = GQL_QUERY;
|
1333
|
+
} else if (8 == (doc->cur - start) && 0 == strncmp(mutation_str, start, sizeof(mutation_str) - 1)) {
|
1334
|
+
kind = GQL_MUTATION;
|
1335
|
+
} else if (12 == (doc->cur - start) && 0 == strncmp(subscription_str, start, sizeof(subscription_str) - 1)) {
|
1336
|
+
kind = GQL_SUBSCRIPTION;
|
1337
|
+
} else {
|
1338
|
+
return agoo_doc_err(doc, err, "Invalid operation type");
|
1339
|
+
}
|
1340
1340
|
}
|
1341
1341
|
agoo_doc_skip_white(doc);
|
1342
1342
|
start = doc->cur;
|
@@ -1597,7 +1597,7 @@ validate_doc(agooErr err, gqlDoc doc) {
|
|
1597
1597
|
}
|
1598
1598
|
|
1599
1599
|
gqlDoc
|
1600
|
-
sdl_parse_doc(agooErr err, const char *str, int len, gqlVar vars) {
|
1600
|
+
sdl_parse_doc(agooErr err, const char *str, int len, gqlVar vars, gqlOpKind default_kind) {
|
1601
1601
|
struct _agooDoc doc;
|
1602
1602
|
gqlDoc gdoc = NULL;
|
1603
1603
|
|
@@ -1616,7 +1616,7 @@ sdl_parse_doc(agooErr err, const char *str, int len, gqlVar vars) {
|
|
1616
1616
|
case 'q':
|
1617
1617
|
case 'm':
|
1618
1618
|
case 's':
|
1619
|
-
if (AGOO_ERR_OK != make_op(err, &doc, gdoc)) {
|
1619
|
+
if (AGOO_ERR_OK != make_op(err, &doc, gdoc, default_kind)) {
|
1620
1620
|
gql_doc_destroy(gdoc);
|
1621
1621
|
return NULL;
|
1622
1622
|
}
|
data/ext/agoo/sdl.h
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
#define AGOO_SDL_H
|
5
5
|
|
6
6
|
#include "err.h"
|
7
|
+
#include "graphql.h"
|
7
8
|
|
8
9
|
struct _gqlType;
|
9
10
|
struct _gqlVar;
|
@@ -12,7 +13,7 @@ struct _gqlValue;
|
|
12
13
|
extern int sdl_parse(agooErr err, const char *str, int len);
|
13
14
|
|
14
15
|
// Parse a execution definition.
|
15
|
-
extern struct _gqlDoc* sdl_parse_doc(agooErr err, const char *str, int len, struct _gqlVar *vars);
|
16
|
+
extern struct _gqlDoc* sdl_parse_doc(agooErr err, const char *str, int len, struct _gqlVar *vars, gqlOpKind default_kind);
|
16
17
|
|
17
18
|
extern gqlVar gql_op_var_create(agooErr err, const char *name, struct _gqlType *type, struct _gqlValue *value);
|
18
19
|
|
data/ext/agoo/server.c
CHANGED
@@ -12,11 +12,16 @@
|
|
12
12
|
#include "con.h"
|
13
13
|
#include "domain.h"
|
14
14
|
#include "dtime.h"
|
15
|
+
#include "gqlsub.h"
|
16
|
+
#include "gqlvalue.h"
|
17
|
+
#include "graphql.h"
|
15
18
|
#include "http.h"
|
16
19
|
#include "hook.h"
|
17
20
|
#include "log.h"
|
18
21
|
#include "page.h"
|
19
22
|
#include "pub.h"
|
23
|
+
#include "res.h"
|
24
|
+
#include "text.h"
|
20
25
|
#include "upgraded.h"
|
21
26
|
|
22
27
|
#include "server.h"
|
@@ -34,6 +39,7 @@ agoo_server_setup(agooErr err) {
|
|
34
39
|
memset(&agoo_server, 0, sizeof(struct _agooServer));
|
35
40
|
pthread_mutex_init(&agoo_server.up_lock, 0);
|
36
41
|
agoo_server.up_list = NULL;
|
42
|
+
agoo_server.gsub_list = NULL;
|
37
43
|
agoo_server.max_push_pending = 32;
|
38
44
|
|
39
45
|
if (AGOO_ERR_OK != agoo_pages_init(err) ||
|
@@ -336,3 +342,112 @@ agoo_server_publish(struct _agooPub *pub) {
|
|
336
342
|
}
|
337
343
|
}
|
338
344
|
}
|
345
|
+
|
346
|
+
void
|
347
|
+
agoo_server_add_gsub(gqlSub sub) {
|
348
|
+
pthread_mutex_lock(&agoo_server.up_lock);
|
349
|
+
sub->next = agoo_server.gsub_list;
|
350
|
+
agoo_server.gsub_list = sub;
|
351
|
+
pthread_mutex_unlock(&agoo_server.up_lock);
|
352
|
+
}
|
353
|
+
|
354
|
+
void
|
355
|
+
agoo_server_del_gsub(gqlSub sub) {
|
356
|
+
gqlSub s;
|
357
|
+
gqlSub prev = NULL;
|
358
|
+
|
359
|
+
pthread_mutex_lock(&agoo_server.up_lock);
|
360
|
+
for (s = agoo_server.gsub_list; NULL != s; s = s->next) {
|
361
|
+
if (s == sub) {
|
362
|
+
if (NULL == prev) {
|
363
|
+
agoo_server.gsub_list = s->next;
|
364
|
+
} else {
|
365
|
+
prev->next = s->next;
|
366
|
+
}
|
367
|
+
}
|
368
|
+
prev = s;
|
369
|
+
}
|
370
|
+
pthread_mutex_unlock(&agoo_server.up_lock);
|
371
|
+
}
|
372
|
+
|
373
|
+
static bool
|
374
|
+
subject_check(const char *pattern, const char *subject) {
|
375
|
+
for (; '\0' != *pattern && '\0' != *subject; subject++) {
|
376
|
+
if (*subject == *pattern) {
|
377
|
+
pattern++;
|
378
|
+
} else if ('*' == *pattern) {
|
379
|
+
for (; '\0' != *subject && '.' != *subject; subject++) {
|
380
|
+
}
|
381
|
+
if ('\0' == *subject) {
|
382
|
+
return true;
|
383
|
+
}
|
384
|
+
pattern++;
|
385
|
+
} else if ('>' == *pattern) {
|
386
|
+
return true;
|
387
|
+
} else {
|
388
|
+
break;
|
389
|
+
}
|
390
|
+
}
|
391
|
+
return '\0' == *pattern && '\0' == *subject;
|
392
|
+
}
|
393
|
+
|
394
|
+
static agooText
|
395
|
+
gpub_eval(agooErr err, gqlDoc query, gqlRef event) {
|
396
|
+
agooText t = NULL;
|
397
|
+
gqlSel sel;
|
398
|
+
gqlValue result;
|
399
|
+
|
400
|
+
if (NULL == query->ops || NULL == query->ops->sels) {
|
401
|
+
agoo_err_set(err, AGOO_ERR_TYPE, "subscription not valid");
|
402
|
+
return NULL;
|
403
|
+
}
|
404
|
+
sel = query->ops->sels;
|
405
|
+
if (NULL != (result = gql_object_create(err))) {
|
406
|
+
struct _gqlField field;
|
407
|
+
|
408
|
+
memset(&field, 0, sizeof(field));
|
409
|
+
field.type = sel->type;
|
410
|
+
if (AGOO_ERR_OK != gql_eval_sels(err, query, event, &field, sel->sels, result, 0)) {
|
411
|
+
gql_value_destroy(result);
|
412
|
+
return NULL;
|
413
|
+
}
|
414
|
+
if (NULL == (t = agoo_text_allocate(1024))) {
|
415
|
+
AGOO_ERR_MEM(err, "Text");
|
416
|
+
return NULL;
|
417
|
+
}
|
418
|
+
t = gql_value_json(t, result, 0, 0);
|
419
|
+
gql_value_destroy(result);
|
420
|
+
}
|
421
|
+
return t;
|
422
|
+
}
|
423
|
+
|
424
|
+
int
|
425
|
+
agoo_server_gpublish(agooErr err, const char *subject, gqlRef event) {
|
426
|
+
gqlSub sub;
|
427
|
+
gqlType type;
|
428
|
+
|
429
|
+
if (NULL == gql_type_func || NULL == (type = gql_type_func(event))) {
|
430
|
+
return agoo_err_set(err, AGOO_ERR_TYPE, "Not able to determine the type for a GraphQL publish.");
|
431
|
+
}
|
432
|
+
pthread_mutex_lock(&agoo_server.up_lock);
|
433
|
+
for (sub = agoo_server.gsub_list; NULL != sub; sub = sub->next) {
|
434
|
+
if (subject_check(sub->subject, subject)) {
|
435
|
+
agooRes res;
|
436
|
+
agooText t;
|
437
|
+
|
438
|
+
if (NULL == (res = agoo_res_create(sub->con))) {
|
439
|
+
AGOO_ERR_MEM(err, "Response");
|
440
|
+
break;
|
441
|
+
}
|
442
|
+
if (NULL == (t = gpub_eval(err, sub->query, event))) {
|
443
|
+
break;
|
444
|
+
}
|
445
|
+
res->con_kind = AGOO_CON_ANY;
|
446
|
+
agoo_res_message_push(res, t);
|
447
|
+
agoo_con_res_append(sub->con, res);
|
448
|
+
}
|
449
|
+
}
|
450
|
+
pthread_mutex_unlock(&agoo_server.up_lock);
|
451
|
+
|
452
|
+
return err->code;
|
453
|
+
}
|
data/ext/agoo/server.h
CHANGED
@@ -9,6 +9,7 @@
|
|
9
9
|
#include "atomic.h"
|
10
10
|
#include "bind.h"
|
11
11
|
#include "err.h"
|
12
|
+
#include "gqleval.h"
|
12
13
|
#include "hook.h"
|
13
14
|
#include "queue.h"
|
14
15
|
|
@@ -17,6 +18,8 @@ struct _agooConLoop;
|
|
17
18
|
struct _agooPub;
|
18
19
|
struct _agooReq;
|
19
20
|
struct _agooUpgraded;
|
21
|
+
struct _gqlSub;
|
22
|
+
struct _gqlValue;
|
20
23
|
|
21
24
|
typedef struct _agooServer {
|
22
25
|
volatile bool inited;
|
@@ -39,6 +42,7 @@ typedef struct _agooServer {
|
|
39
42
|
atomic_int con_cnt;
|
40
43
|
|
41
44
|
struct _agooUpgraded *up_list;
|
45
|
+
struct _gqlSub *gsub_list;
|
42
46
|
pthread_mutex_t up_lock;
|
43
47
|
int max_push_pending;
|
44
48
|
void *env_nil_value;
|
@@ -66,6 +70,10 @@ extern int agoo_server_add_func_hook(agooErr err,
|
|
66
70
|
|
67
71
|
extern void agoo_server_publish(struct _agooPub *pub);
|
68
72
|
|
73
|
+
extern void agoo_server_add_gsub(struct _gqlSub *sub);
|
74
|
+
extern void agoo_server_del_gsub(struct _gqlSub *sub);
|
75
|
+
extern int agoo_server_gpublish(agooErr err, const char *subject, gqlRef event);
|
76
|
+
|
69
77
|
extern struct _agooServer agoo_server;
|
70
78
|
|
71
79
|
extern double agoo_io_loop_ratio;
|