agoo 2.15.7 → 2.15.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/bin/agoo +47 -39
- data/ext/agoo/bind.c +209 -198
- data/ext/agoo/rgraphql.c +7 -4
- data/ext/agoo/rserver.c +689 -688
- data/ext/agoo/server.c +255 -253
- data/lib/agoo/version.rb +1 -1
- data/lib/rack/handler/agoo.rb +130 -128
- metadata +3 -3
data/ext/agoo/server.c
CHANGED
@@ -26,11 +26,11 @@
|
|
26
26
|
|
27
27
|
#include "server.h"
|
28
28
|
|
29
|
-
#define LOOP_UP
|
29
|
+
#define LOOP_UP 100
|
30
30
|
|
31
|
-
struct _agooServer
|
31
|
+
struct _agooServer agoo_server = {false};
|
32
32
|
|
33
|
-
double
|
33
|
+
double agoo_io_loop_ratio = 0.5;
|
34
34
|
|
35
35
|
int
|
36
36
|
agoo_server_setup(agooErr err) {
|
@@ -41,19 +41,19 @@ agoo_server_setup(agooErr err) {
|
|
41
41
|
agoo_server.max_push_pending = 32;
|
42
42
|
|
43
43
|
if (AGOO_ERR_OK != agoo_pages_init(err) ||
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
AGOO_ERR_OK != agoo_queue_multi_init(err, &agoo_server.con_queue, 1024, false, true) ||
|
45
|
+
AGOO_ERR_OK != agoo_queue_multi_init(err, &agoo_server.eval_queue, 1024, true, true)) {
|
46
|
+
return err->code;
|
47
47
|
}
|
48
|
-
long
|
48
|
+
long i;
|
49
49
|
|
50
50
|
agoo_server.loop_max = 4;
|
51
51
|
if (0 < (i = sysconf(_SC_NPROCESSORS_ONLN))) {
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
i = (int)(i * agoo_io_loop_ratio);
|
53
|
+
if (1 >= i) {
|
54
|
+
i = 1;
|
55
|
+
}
|
56
|
+
agoo_server.loop_max = (int)i;
|
57
57
|
}
|
58
58
|
return AGOO_ERR_OK;
|
59
59
|
}
|
@@ -61,8 +61,8 @@ agoo_server_setup(agooErr err) {
|
|
61
61
|
#ifdef HAVE_OPENSSL_SSL_H
|
62
62
|
static int
|
63
63
|
ssl_error(agooErr err, const char *filename, int line) {
|
64
|
-
char
|
65
|
-
unsigned long
|
64
|
+
char buf[224];
|
65
|
+
unsigned long e = ERR_get_error();
|
66
66
|
|
67
67
|
ERR_error_string_n(e, buf, sizeof(buf));
|
68
68
|
|
@@ -76,18 +76,18 @@ agoo_server_ssl_init(agooErr err, const char *cert_pem, const char *key_pem) {
|
|
76
76
|
SSL_load_error_strings();
|
77
77
|
SSL_library_init();
|
78
78
|
if (NULL == (agoo_server.ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) {
|
79
|
-
|
79
|
+
return ssl_error(err, __FILE__, __LINE__);
|
80
80
|
}
|
81
81
|
SSL_CTX_set_ecdh_auto(agoo_server.ssl_ctx, 1);
|
82
82
|
|
83
83
|
if (!SSL_CTX_use_certificate_file(agoo_server.ssl_ctx, cert_pem, SSL_FILETYPE_PEM)) {
|
84
|
-
|
84
|
+
return ssl_error(err, __FILE__, __LINE__);
|
85
85
|
}
|
86
86
|
if (!SSL_CTX_use_PrivateKey_file(agoo_server.ssl_ctx, key_pem, SSL_FILETYPE_PEM)) {
|
87
|
-
|
87
|
+
return ssl_error(err, __FILE__, __LINE__);
|
88
88
|
}
|
89
89
|
if (!SSL_CTX_check_private_key(agoo_server.ssl_ctx)) {
|
90
|
-
|
90
|
+
return agoo_err_set(err, AGOO_ERR_TLS, "TLS private key check failed");
|
91
91
|
}
|
92
92
|
#endif
|
93
93
|
return AGOO_ERR_OK;
|
@@ -95,94 +95,96 @@ agoo_server_ssl_init(agooErr err, const char *cert_pem, const char *key_pem) {
|
|
95
95
|
|
96
96
|
static void
|
97
97
|
add_con_loop() {
|
98
|
-
struct _agooErr
|
99
|
-
agooConLoop
|
98
|
+
struct _agooErr err = AGOO_ERR_INIT;
|
99
|
+
agooConLoop loop = agoo_conloop_create(&err, 0);
|
100
100
|
|
101
101
|
if (NULL != loop) {
|
102
|
-
|
103
|
-
|
104
|
-
|
102
|
+
loop->next = agoo_server.con_loops;
|
103
|
+
agoo_server.con_loops = loop;
|
104
|
+
agoo_server.loop_cnt++;
|
105
105
|
}
|
106
106
|
}
|
107
107
|
|
108
108
|
static void*
|
109
109
|
listen_loop(void *x) {
|
110
|
-
int
|
111
|
-
struct pollfd
|
112
|
-
struct pollfd
|
113
|
-
struct _agooErr
|
114
|
-
struct sockaddr_in
|
115
|
-
int
|
116
|
-
int
|
117
|
-
socklen_t
|
118
|
-
agooCon
|
119
|
-
int
|
120
|
-
uint64_t
|
121
|
-
agooBind
|
110
|
+
int optval = 1;
|
111
|
+
struct pollfd pa[100];
|
112
|
+
struct pollfd *p;
|
113
|
+
struct _agooErr err = AGOO_ERR_INIT;
|
114
|
+
struct sockaddr_in client_addr;
|
115
|
+
int client_sock;
|
116
|
+
int pcnt = 0;
|
117
|
+
socklen_t alen = 0;
|
118
|
+
agooCon con;
|
119
|
+
int i;
|
120
|
+
uint64_t cnt = 0;
|
121
|
+
agooBind b;
|
122
122
|
|
123
123
|
for (b = agoo_server.binds, p = pa; NULL != b; b = b->next, p++, pcnt++) {
|
124
|
-
|
125
|
-
|
126
|
-
|
124
|
+
p->fd = b->fd;
|
125
|
+
p->events = POLLIN;
|
126
|
+
p->revents = 0;
|
127
127
|
}
|
128
128
|
memset(&client_addr, 0, sizeof(client_addr));
|
129
129
|
atomic_fetch_add(&agoo_server.running, 1);
|
130
130
|
while (agoo_server.active) {
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
131
|
+
if (0 > (i = poll(pa, pcnt, 200))) {
|
132
|
+
if (EAGAIN == errno) {
|
133
|
+
continue;
|
134
|
+
}
|
135
|
+
agoo_log_cat(&agoo_error_cat, "Server polling error. %s.", strerror(errno));
|
136
|
+
// Either a signal or something bad like out of memory. Might as well exit.
|
137
|
+
break;
|
138
|
+
}
|
139
|
+
if (0 == i) { // nothing to read
|
140
|
+
continue;
|
141
|
+
}
|
142
|
+
for (b = agoo_server.binds, p = pa; NULL != b; b = b->next, p++) {
|
143
|
+
if (0 != (p->revents & POLLIN)) {
|
144
|
+
if (0 > (client_sock = accept(p->fd, (struct sockaddr*)&client_addr, &alen))) {
|
145
|
+
agoo_log_cat(&agoo_error_cat, "Server with pid %d accept connection failed. %s.", getpid(), strerror(errno));
|
146
|
+
} else if (NULL == (con = agoo_con_create(&err, client_sock, ++cnt, b))) {
|
147
|
+
agoo_log_cat(&agoo_error_cat, "Server with pid %d accept connection failed. %s.", getpid(), err.msg);
|
148
|
+
close(client_sock);
|
149
|
+
cnt--;
|
150
|
+
agoo_err_clear(&err);
|
151
|
+
} else {
|
152
|
+
int con_cnt;
|
153
153
|
#ifdef OSX_OS
|
154
|
-
|
154
|
+
setsockopt(client_sock, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval));
|
155
155
|
#endif
|
156
156
|
#ifdef PLATFORM_LINUX
|
157
|
-
|
157
|
+
setsockopt(client_sock, IPPROTO_TCP, TCP_QUICKACK, &optval, sizeof(optval));
|
158
158
|
#endif
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
159
|
+
fcntl(client_sock, F_SETFL, O_NONBLOCK);
|
160
|
+
//fcntl(client_sock, F_SETFL, FNDELAY);
|
161
|
+
setsockopt(client_sock, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval));
|
162
|
+
setsockopt(client_sock, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval));
|
163
|
+
agoo_log_cat(&agoo_con_cat, "Server with pid %d accepted connection %llu on %s [%d] from %s",
|
164
|
+
getpid(), (unsigned long long)cnt, b->id, con->sock, con->remote);
|
165
|
+
|
166
|
+
con_cnt = atomic_fetch_add(&agoo_server.con_cnt, 1);
|
167
|
+
/* TBD
|
168
|
+
if (agoo_server.loop_max > agoo_server.loop_cnt && agoo_server.loop_cnt * LOOP_UP < con_cnt) {
|
169
|
+
add_con_loop();
|
170
|
+
}
|
171
|
+
*/
|
172
|
+
agoo_queue_push(&agoo_server.con_queue, (void*)con);
|
173
|
+
}
|
174
|
+
}
|
175
|
+
if (0 != (p->revents & (POLLERR | POLLHUP | POLLNVAL))) {
|
176
|
+
if (0 != (p->revents & (POLLHUP | POLLNVAL))) {
|
177
|
+
agoo_log_cat(&agoo_error_cat, "Agoo server with pid %d socket on %s closed.", getpid(), b->id);
|
178
|
+
} else {
|
179
|
+
agoo_log_cat(&agoo_error_cat, "Agoo server with pid %d socket on %s error.", getpid(), b->id);
|
180
|
+
}
|
181
|
+
agoo_server.active = false;
|
182
|
+
}
|
183
|
+
p->revents = 0;
|
184
|
+
}
|
183
185
|
}
|
184
186
|
for (b = agoo_server.binds; NULL != b; b = b->next) {
|
185
|
-
|
187
|
+
agoo_bind_close(b);
|
186
188
|
}
|
187
189
|
atomic_fetch_sub(&agoo_server.running, 1);
|
188
190
|
|
@@ -191,12 +193,12 @@ listen_loop(void *x) {
|
|
191
193
|
|
192
194
|
int
|
193
195
|
agoo_server_start(agooErr err, const char *app_name, const char *version) {
|
194
|
-
double
|
195
|
-
int
|
196
|
-
int
|
196
|
+
double giveup;
|
197
|
+
int xcnt = 0;
|
198
|
+
int stat;
|
197
199
|
|
198
200
|
if (0 != (stat = pthread_create(&agoo_server.listen_thread, NULL, listen_loop, NULL))) {
|
199
|
-
|
201
|
+
return agoo_err_set(err, stat, "Failed to create server listener thread. %s", strerror(stat));
|
200
202
|
}
|
201
203
|
xcnt++;
|
202
204
|
agoo_server.con_loops = agoo_conloop_create(err, 0);
|
@@ -207,36 +209,36 @@ agoo_server_start(agooErr err, const char *app_name, const char *version) {
|
|
207
209
|
// might as well create the maximum number of con threads as is
|
208
210
|
// reasonable.
|
209
211
|
if (1 >= agoo_server.thread_cnt) {
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
212
|
+
while (agoo_server.loop_cnt < agoo_server.loop_max) {
|
213
|
+
add_con_loop();
|
214
|
+
xcnt++;
|
215
|
+
}
|
214
216
|
}
|
215
217
|
giveup = dtime() + 1.0;
|
216
218
|
while (dtime() < giveup) {
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
219
|
+
if (xcnt <= (long)atomic_load(&agoo_server.running)) {
|
220
|
+
break;
|
221
|
+
}
|
222
|
+
dsleep(0.01);
|
221
223
|
}
|
222
224
|
if (agoo_info_cat.on) {
|
223
|
-
|
225
|
+
agooBind b;
|
224
226
|
|
225
|
-
|
226
|
-
|
227
|
-
|
227
|
+
for (b = agoo_server.binds; NULL != b; b = b->next) {
|
228
|
+
agoo_log_cat(&agoo_info_cat, "%s %s with pid %d is listening on %s.", app_name, version, getpid(), b->id);
|
229
|
+
}
|
228
230
|
}
|
229
231
|
return AGOO_ERR_OK;
|
230
232
|
}
|
231
233
|
|
232
234
|
int
|
233
235
|
setup_listen(agooErr err) {
|
234
|
-
agooBind
|
236
|
+
agooBind b;
|
235
237
|
|
236
238
|
for (b = agoo_server.binds; NULL != b; b = b->next) {
|
237
|
-
|
238
|
-
|
239
|
-
|
239
|
+
if (AGOO_ERR_OK != agoo_bind_listen(err, b)) {
|
240
|
+
return err->code;
|
241
|
+
}
|
240
242
|
}
|
241
243
|
agoo_server.active = true;
|
242
244
|
|
@@ -246,55 +248,55 @@ setup_listen(agooErr err) {
|
|
246
248
|
void
|
247
249
|
agoo_server_shutdown(const char *app_name, void (*stop)()) {
|
248
250
|
if (agoo_server.inited) {
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
251
|
+
agooConLoop loop;
|
252
|
+
|
253
|
+
agoo_log_cat(&agoo_info_cat, "%s with pid %d shutting down.", app_name, getpid());
|
254
|
+
agoo_server.inited = false;
|
255
|
+
if (agoo_server.active) {
|
256
|
+
double giveup = dtime() + 1.0;
|
257
|
+
|
258
|
+
agoo_server.active = false;
|
259
|
+
pthread_detach(agoo_server.listen_thread);
|
260
|
+
for (loop = agoo_server.con_loops; NULL != loop; loop = loop->next) {
|
261
|
+
pthread_detach(loop->thread);
|
262
|
+
}
|
263
|
+
while (0 < (long)atomic_load(&agoo_server.running)) {
|
264
|
+
dsleep(0.1);
|
265
|
+
if (giveup < dtime()) {
|
266
|
+
break;
|
267
|
+
}
|
268
|
+
}
|
269
|
+
if (NULL != stop) {
|
270
|
+
stop();
|
271
|
+
}
|
272
|
+
while (NULL != agoo_server.hooks) {
|
273
|
+
agooHook h = agoo_server.hooks;
|
274
|
+
|
275
|
+
agoo_server.hooks = h->next;
|
276
|
+
agoo_hook_destroy(h);
|
277
|
+
}
|
278
|
+
}
|
279
|
+
while (NULL != agoo_server.binds) {
|
280
|
+
agooBind b = agoo_server.binds;
|
281
|
+
|
282
|
+
agoo_server.binds = b->next;
|
283
|
+
agoo_bind_destroy(b);
|
284
|
+
}
|
285
|
+
agoo_queue_cleanup(&agoo_server.con_queue);
|
286
|
+
while (NULL != (loop = agoo_server.con_loops)) {
|
287
|
+
agoo_server.con_loops = loop->next;
|
288
|
+
agoo_conloop_destroy(loop);
|
289
|
+
}
|
290
|
+
agoo_queue_cleanup(&agoo_server.eval_queue);
|
291
|
+
|
292
|
+
agoo_pages_cleanup();
|
293
|
+
agoo_http_cleanup();
|
294
|
+
agoo_domain_cleanup();
|
293
295
|
#ifdef HAVE_OPENSSL_SSL_H
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
296
|
+
if (NULL != agoo_server.ssl_ctx) {
|
297
|
+
SSL_CTX_free(agoo_server.ssl_ctx);
|
298
|
+
EVP_cleanup();
|
299
|
+
}
|
298
300
|
#endif
|
299
301
|
}
|
300
302
|
}
|
@@ -302,30 +304,30 @@ agoo_server_shutdown(const char *app_name, void (*stop)()) {
|
|
302
304
|
void
|
303
305
|
agoo_server_bind(agooBind b) {
|
304
306
|
// If a bind with the same port already exists, replace it.
|
305
|
-
agooBind
|
306
|
-
agooBind
|
307
|
+
agooBind prev = NULL;
|
308
|
+
agooBind bx = NULL;
|
307
309
|
|
308
310
|
if (NULL == b->read) {
|
309
|
-
|
311
|
+
b->read = agoo_con_http_read;
|
310
312
|
}
|
311
313
|
if (NULL == b->write) {
|
312
|
-
|
314
|
+
b->write = agoo_con_http_write;
|
313
315
|
}
|
314
316
|
if (NULL == b->events) {
|
315
|
-
|
317
|
+
b->events = agoo_con_http_events;
|
316
318
|
}
|
317
319
|
for (bx = agoo_server.binds; NULL != bx; bx = bx->next) {
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
320
|
+
if (bx->port == b->port) {
|
321
|
+
b->next = bx->next;
|
322
|
+
if (NULL == prev) {
|
323
|
+
agoo_server.binds = b;
|
324
|
+
} else {
|
325
|
+
prev->next = b;
|
326
|
+
}
|
327
|
+
agoo_bind_destroy(bx);
|
328
|
+
return;
|
329
|
+
}
|
330
|
+
prev = bx;
|
329
331
|
}
|
330
332
|
b->next = agoo_server.binds;
|
331
333
|
agoo_server.binds = b;
|
@@ -335,9 +337,9 @@ void
|
|
335
337
|
agoo_server_add_upgraded(agooUpgraded up) {
|
336
338
|
pthread_mutex_lock(&agoo_server.up_lock);
|
337
339
|
if (NULL == agoo_server.up_list) {
|
338
|
-
|
340
|
+
up->next = NULL;
|
339
341
|
} else {
|
340
|
-
|
342
|
+
agoo_server.up_list->prev = up;
|
341
343
|
}
|
342
344
|
up->next = agoo_server.up_list;
|
343
345
|
agoo_server.up_list = up;
|
@@ -346,41 +348,41 @@ agoo_server_add_upgraded(agooUpgraded up) {
|
|
346
348
|
}
|
347
349
|
|
348
350
|
int
|
349
|
-
agoo_server_add_func_hook(agooErr
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
agooHook
|
356
|
-
agooHook
|
357
|
-
agooHook
|
351
|
+
agoo_server_add_func_hook(agooErr err,
|
352
|
+
agooMethod method,
|
353
|
+
const char *pattern,
|
354
|
+
void (*func)(agooReq req),
|
355
|
+
agooQueue queue,
|
356
|
+
bool quick) {
|
357
|
+
agooHook h;
|
358
|
+
agooHook prev = NULL;
|
359
|
+
agooHook hook = agoo_hook_func_create(method, pattern, func, queue);
|
358
360
|
|
359
361
|
if (NULL == hook) {
|
360
|
-
|
362
|
+
return AGOO_ERR_MEM(err, "HTTP Server Hook");
|
361
363
|
}
|
362
364
|
hook->no_queue = quick;
|
363
365
|
for (h = agoo_server.hooks; NULL != h; h = h->next) {
|
364
|
-
|
366
|
+
prev = h;
|
365
367
|
}
|
366
368
|
if (NULL != prev) {
|
367
|
-
|
369
|
+
prev->next = hook;
|
368
370
|
} else {
|
369
|
-
|
371
|
+
agoo_server.hooks = hook;
|
370
372
|
}
|
371
373
|
return AGOO_ERR_OK;
|
372
374
|
}
|
373
375
|
|
374
376
|
void
|
375
377
|
agoo_server_publish(struct _agooPub *pub) {
|
376
|
-
agooConLoop
|
378
|
+
agooConLoop loop;
|
377
379
|
|
378
380
|
for (loop = agoo_server.con_loops; NULL != loop; loop = loop->next) {
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
381
|
+
if (NULL == loop->next) {
|
382
|
+
agoo_queue_push(&loop->pub_queue, pub);
|
383
|
+
} else {
|
384
|
+
agoo_queue_push(&loop->pub_queue, agoo_pub_dup(pub));
|
385
|
+
}
|
384
386
|
}
|
385
387
|
}
|
386
388
|
|
@@ -394,19 +396,19 @@ agoo_server_add_gsub(gqlSub sub) {
|
|
394
396
|
|
395
397
|
void
|
396
398
|
agoo_server_del_gsub(gqlSub sub) {
|
397
|
-
gqlSub
|
398
|
-
gqlSub
|
399
|
+
gqlSub s;
|
400
|
+
gqlSub prev = NULL;
|
399
401
|
|
400
402
|
pthread_mutex_lock(&agoo_server.up_lock);
|
401
403
|
for (s = agoo_server.gsub_list; NULL != s; s = s->next) {
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
404
|
+
if (s == sub) {
|
405
|
+
if (NULL == prev) {
|
406
|
+
agoo_server.gsub_list = s->next;
|
407
|
+
} else {
|
408
|
+
prev->next = s->next;
|
409
|
+
}
|
410
|
+
}
|
411
|
+
prev = s;
|
410
412
|
}
|
411
413
|
pthread_mutex_unlock(&agoo_server.up_lock);
|
412
414
|
}
|
@@ -414,79 +416,79 @@ agoo_server_del_gsub(gqlSub sub) {
|
|
414
416
|
static bool
|
415
417
|
subject_check(const char *pattern, const char *subject) {
|
416
418
|
for (; '\0' != *pattern && '\0' != *subject; subject++) {
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
419
|
+
if (*subject == *pattern) {
|
420
|
+
pattern++;
|
421
|
+
} else if ('*' == *pattern) {
|
422
|
+
for (; '\0' != *subject && '.' != *subject; subject++) {
|
423
|
+
}
|
424
|
+
if ('\0' == *subject) {
|
425
|
+
return true;
|
426
|
+
}
|
427
|
+
pattern++;
|
428
|
+
} else if ('>' == *pattern) {
|
429
|
+
return true;
|
430
|
+
} else {
|
431
|
+
break;
|
432
|
+
}
|
431
433
|
}
|
432
434
|
return '\0' == *pattern && '\0' == *subject;
|
433
435
|
}
|
434
436
|
|
435
437
|
static agooText
|
436
438
|
gpub_eval(agooErr err, gqlDoc query, gqlRef event) {
|
437
|
-
agooText
|
438
|
-
gqlSel
|
439
|
-
gqlValue
|
439
|
+
agooText t = NULL;
|
440
|
+
gqlSel sel;
|
441
|
+
gqlValue result;
|
440
442
|
|
441
443
|
if (NULL == query->ops || NULL == query->ops->sels) {
|
442
|
-
|
443
|
-
|
444
|
+
agoo_err_set(err, AGOO_ERR_TYPE, "subscription not valid");
|
445
|
+
return NULL;
|
444
446
|
}
|
445
447
|
sel = query->ops->sels;
|
446
448
|
if (NULL != (result = gql_object_create(err))) {
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
449
|
+
struct _gqlField field;
|
450
|
+
|
451
|
+
memset(&field, 0, sizeof(field));
|
452
|
+
field.type = sel->type;
|
453
|
+
if (AGOO_ERR_OK != gql_eval_sels(err, query, event, &field, sel->sels, result, 0)) {
|
454
|
+
gql_value_destroy(result);
|
455
|
+
return NULL;
|
456
|
+
}
|
457
|
+
if (NULL == (t = agoo_text_allocate(1024))) {
|
458
|
+
AGOO_ERR_MEM(err, "Text");
|
459
|
+
return NULL;
|
460
|
+
}
|
461
|
+
t = gql_value_json(t, result, 0, 0);
|
462
|
+
gql_value_destroy(result);
|
461
463
|
}
|
462
464
|
return t;
|
463
465
|
}
|
464
466
|
|
465
467
|
int
|
466
468
|
agoo_server_gpublish(agooErr err, const char *subject, gqlRef event) {
|
467
|
-
gqlSub
|
468
|
-
gqlType
|
469
|
+
gqlSub sub;
|
470
|
+
gqlType type;
|
469
471
|
|
470
472
|
if (NULL == gql_type_func || NULL == (type = gql_type_func(event))) {
|
471
|
-
|
473
|
+
return agoo_err_set(err, AGOO_ERR_TYPE, "Not able to determine the type for a GraphQL publish.");
|
472
474
|
}
|
473
475
|
pthread_mutex_lock(&agoo_server.up_lock);
|
474
476
|
for (sub = agoo_server.gsub_list; NULL != sub; sub = sub->next) {
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
477
|
+
if (subject_check(sub->subject, subject)) {
|
478
|
+
agooRes res;
|
479
|
+
agooText t;
|
480
|
+
|
481
|
+
if (NULL == (res = agoo_res_create(sub->con))) {
|
482
|
+
AGOO_ERR_MEM(err, "Response");
|
483
|
+
break;
|
484
|
+
}
|
485
|
+
if (NULL == (t = gpub_eval(err, sub->query, event))) {
|
486
|
+
break;
|
487
|
+
}
|
488
|
+
res->con_kind = AGOO_CON_ANY;
|
489
|
+
agoo_res_message_push(res, t);
|
490
|
+
agoo_con_res_append(sub->con, res);
|
491
|
+
}
|
490
492
|
}
|
491
493
|
pthread_mutex_unlock(&agoo_server.up_lock);
|
492
494
|
|