agoo 2.5.4 → 2.5.5

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.

Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/bin/agoo +3 -1
  4. data/ext/agoo/base64.h +3 -3
  5. data/ext/agoo/bind.c +1 -1
  6. data/ext/agoo/bind.h +3 -3
  7. data/ext/agoo/con.c +4 -2
  8. data/ext/agoo/con.h +3 -3
  9. data/ext/agoo/debug.c +7 -0
  10. data/ext/agoo/debug.h +13 -6
  11. data/ext/agoo/doc.c +159 -0
  12. data/ext/agoo/doc.h +34 -0
  13. data/ext/agoo/dtime.h +3 -3
  14. data/ext/agoo/err.h +3 -3
  15. data/ext/agoo/error_stream.h +3 -3
  16. data/ext/agoo/extconf.rb +1 -1
  17. data/ext/agoo/gqlintro.c +333 -0
  18. data/ext/agoo/gqlintro.h +10 -0
  19. data/ext/agoo/gqlvalue.c +1035 -0
  20. data/ext/agoo/gqlvalue.h +88 -0
  21. data/ext/agoo/graphql.c +1078 -0
  22. data/ext/agoo/graphql.h +198 -0
  23. data/ext/agoo/hook.c +2 -0
  24. data/ext/agoo/hook.h +4 -3
  25. data/ext/agoo/http.c +2 -1
  26. data/ext/agoo/http.h +3 -3
  27. data/ext/agoo/kinds.h +3 -3
  28. data/ext/agoo/log.h +3 -3
  29. data/ext/agoo/log_queue.h +3 -3
  30. data/ext/agoo/method.h +3 -3
  31. data/ext/agoo/page.h +3 -3
  32. data/ext/agoo/pub.h +3 -3
  33. data/ext/agoo/queue.h +3 -3
  34. data/ext/agoo/rack_logger.h +3 -3
  35. data/ext/agoo/req.c +2 -2
  36. data/ext/agoo/req.h +3 -3
  37. data/ext/agoo/request.h +3 -3
  38. data/ext/agoo/res.h +3 -3
  39. data/ext/agoo/response.h +3 -3
  40. data/ext/agoo/rhook.c +2 -2
  41. data/ext/agoo/rhook.h +4 -3
  42. data/ext/agoo/rlog.h +3 -3
  43. data/ext/agoo/rresponse.h +3 -3
  44. data/ext/agoo/rserver.c +64 -0
  45. data/ext/agoo/rserver.h +3 -3
  46. data/ext/agoo/rupgraded.c +1 -1
  47. data/ext/agoo/rupgraded.h +3 -3
  48. data/ext/agoo/sdl.c +334 -0
  49. data/ext/agoo/sdl.h +10 -0
  50. data/ext/agoo/seg.h +3 -3
  51. data/ext/agoo/server.c +3 -1
  52. data/ext/agoo/server.h +5 -4
  53. data/ext/agoo/sha1.h +3 -3
  54. data/ext/agoo/sse.h +3 -3
  55. data/ext/agoo/sub.h +3 -3
  56. data/ext/agoo/subject.h +3 -3
  57. data/ext/agoo/text.h +3 -3
  58. data/ext/agoo/upgraded.h +3 -3
  59. data/ext/agoo/websocket.h +3 -3
  60. data/lib/agoo/version.rb +1 -1
  61. data/lib/rack/handler/agoo.rb +3 -1
  62. metadata +12 -12
  63. data/ext/agoo/foo/agoo.c +0 -109
  64. data/ext/agoo/foo/con.c +0 -1220
  65. data/ext/agoo/foo/con.h +0 -65
  66. data/ext/agoo/foo/page.c +0 -699
  67. data/ext/agoo/foo/pub.c +0 -131
  68. data/ext/agoo/foo/pub.h +0 -40
  69. data/ext/agoo/foo/rserver.c +0 -1016
  70. data/ext/agoo/foo/server.c +0 -303
  71. data/ext/agoo/foo/server.h +0 -67
  72. data/ext/agoo/foo/upgraded.c +0 -182
@@ -1,303 +0,0 @@
1
- // Copyright (c) 2018, Peter Ohler, All rights reserved.
2
-
3
- #include <fcntl.h>
4
- #include <netdb.h>
5
- #include <netinet/tcp.h>
6
- #include <poll.h>
7
- #include <string.h>
8
- #include <sys/socket.h>
9
- #include <sys/types.h>
10
- #include <unistd.h>
11
-
12
- #include "con.h"
13
- #include "dtime.h"
14
- #include "http.h"
15
- #include "hook.h"
16
- #include "log.h"
17
- #include "page.h"
18
- #include "pub.h"
19
- #include "upgraded.h"
20
-
21
- #include "server.h"
22
-
23
- #define LOOP_UP 512
24
- #define MAX_LOOP 4
25
-
26
- struct _Server the_server = {false};
27
-
28
- void
29
- server_setup() {
30
- memset(&the_server, 0, sizeof(struct _Server));
31
- pthread_mutex_init(&the_server.up_lock, 0);
32
- the_server.up_list = NULL;
33
- the_server.max_push_pending = 32;
34
- pages_init();
35
- queue_multi_init(&the_server.con_queue, 1024, false, true);
36
- queue_multi_init(&the_server.eval_queue, 1024, false, true);
37
- }
38
-
39
- static void
40
- add_con_loop() {
41
- struct _Err err = ERR_INIT;
42
- ConLoop loop = conloop_create(&err, 0);
43
-
44
- if (NULL != loop) {
45
- loop->next = the_server.con_loops;
46
- the_server.con_loops = loop;
47
- the_server.loop_cnt++;
48
- }
49
- }
50
-
51
- static void*
52
- listen_loop(void *x) {
53
- int optval = 1;
54
- struct pollfd pa[100];
55
- struct pollfd *p;
56
- struct _Err err = ERR_INIT;
57
- struct sockaddr_in client_addr;
58
- int client_sock;
59
- int pcnt = 0;
60
- socklen_t alen = 0;
61
- Con con;
62
- int i;
63
- uint64_t cnt = 0;
64
- Bind b;
65
-
66
- // TBD support multiple sockets, count binds, allocate pollfd, setup
67
- //
68
- for (b = the_server.binds, p = pa; NULL != b; b = b->next, p++, pcnt++) {
69
- p->fd = b->fd;
70
- p->events = POLLIN;
71
- p->revents = 0;
72
- }
73
- memset(&client_addr, 0, sizeof(client_addr));
74
- atomic_fetch_add(&the_server.running, 1);
75
- while (the_server.active) {
76
- if (0 > (i = poll(pa, pcnt, 200))) {
77
- if (EAGAIN == errno) {
78
- continue;
79
- }
80
- log_cat(&error_cat, "Server polling error. %s.", strerror(errno));
81
- // Either a signal or something bad like out of memory. Might as well exit.
82
- break;
83
- }
84
- if (0 == i) { // nothing to read
85
- continue;
86
- }
87
- for (b = the_server.binds, p = pa; NULL != b; b = b->next, p++) {
88
- if (0 != (p->revents & POLLIN)) {
89
- if (0 > (client_sock = accept(p->fd, (struct sockaddr*)&client_addr, &alen))) {
90
- log_cat(&error_cat, "Server with pid %d accept connection failed. %s.", getpid(), strerror(errno));
91
- } else if (NULL == (con = con_create(&err, client_sock, ++cnt, b))) {
92
- log_cat(&error_cat, "Server with pid %d accept connection failed. %s.", getpid(), err.msg);
93
- close(client_sock);
94
- cnt--;
95
- err_clear(&err);
96
- } else {
97
- int con_cnt;
98
- #ifdef OSX_OS
99
- setsockopt(client_sock, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval));
100
- #endif
101
- #ifdef PLATFORM_LINUX
102
- setsockopt(client_sock, IPPROTO_TCP, TCP_QUICKACK, &optval, sizeof(optval));
103
- #endif
104
- fcntl(client_sock, F_SETFL, O_NONBLOCK);
105
- //fcntl(client_sock, F_SETFL, FNDELAY);
106
- setsockopt(client_sock, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval));
107
- setsockopt(client_sock, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval));
108
- log_cat(&con_cat, "Server with pid %d accepted connection %llu on %s [%d]",
109
- getpid(), (unsigned long long)cnt, b->id, con->sock);
110
-
111
- con_cnt = atomic_fetch_add(&the_server.con_cnt, 1);
112
- if (MAX_LOOP > the_server.loop_cnt && the_server.loop_cnt * LOOP_UP < con_cnt) {
113
- add_con_loop();
114
- }
115
- queue_push(&the_server.con_queue, (void*)con);
116
- }
117
- }
118
- if (0 != (p->revents & (POLLERR | POLLHUP | POLLNVAL))) {
119
- if (0 != (p->revents & (POLLHUP | POLLNVAL))) {
120
- log_cat(&error_cat, "Agoo server with pid %d socket on %s closed.", getpid(), b->id);
121
- } else {
122
- log_cat(&error_cat, "Agoo server with pid %d socket on %s error.", getpid(), b->id);
123
- }
124
- the_server.active = false;
125
- }
126
- p->revents = 0;
127
- }
128
- }
129
- for (b = the_server.binds; NULL != b; b = b->next) {
130
- bind_close(b);
131
- }
132
- atomic_fetch_sub(&the_server.running, 1);
133
-
134
- return NULL;
135
- }
136
-
137
- int
138
- server_start(Err err, const char *app_name, const char *version) {
139
- double giveup;
140
-
141
- pthread_create(&the_server.listen_thread, NULL, listen_loop, NULL);
142
- the_server.con_loops = conloop_create(err, 0);
143
- the_server.loop_cnt = 1;
144
-
145
- giveup = dtime() + 1.0;
146
- while (dtime() < giveup) {
147
- if (2 <= atomic_load(&the_server.running)) {
148
- break;
149
- }
150
- dsleep(0.01);
151
- }
152
- if (info_cat.on) {
153
- Bind b;
154
-
155
- for (b = the_server.binds; NULL != b; b = b->next) {
156
- log_cat(&info_cat, "%s %s with pid %d is listening on %s.", app_name, version, getpid(), b->id);
157
- }
158
- }
159
- return ERR_OK;
160
- }
161
-
162
- int
163
- setup_listen(Err err) {
164
- Bind b;
165
-
166
- for (b = the_server.binds; NULL != b; b = b->next) {
167
- if (ERR_OK != bind_listen(err, b)) {
168
- return err->code;
169
- }
170
- }
171
- the_server.active = true;
172
-
173
- return ERR_OK;
174
- }
175
-
176
- void
177
- server_shutdown(const char *app_name, void (*stop)()) {
178
- if (the_server.inited) {
179
- ConLoop loop;
180
-
181
- log_cat(&info_cat, "%s with pid %d shutting down.", app_name, getpid());
182
- the_server.inited = false;
183
- if (the_server.active) {
184
- double giveup = dtime() + 1.0;
185
-
186
- the_server.active = false;
187
- pthread_detach(the_server.listen_thread);
188
- for (loop = the_server.con_loops; NULL != loop; loop = loop->next) {
189
- pthread_detach(loop->thread);
190
- }
191
- while (0 < atomic_load(&the_server.running)) {
192
- dsleep(0.1);
193
- if (giveup < dtime()) {
194
- break;
195
- }
196
- }
197
- stop();
198
-
199
- while (NULL != the_server.hooks) {
200
- Hook h = the_server.hooks;
201
-
202
- the_server.hooks = h->next;
203
- hook_destroy(h);
204
- }
205
- }
206
- while (NULL != the_server.binds) {
207
- Bind b = the_server.binds;
208
-
209
- the_server.binds = b->next;
210
- bind_destroy(b);
211
- }
212
- queue_cleanup(&the_server.con_queue);
213
- for (loop = the_server.con_loops; NULL != loop; loop = loop->next) {
214
- queue_cleanup(&loop->pub_queue);
215
- }
216
- queue_cleanup(&the_server.eval_queue);
217
-
218
- pages_cleanup();
219
- http_cleanup();
220
- }
221
- }
222
-
223
- void
224
- server_bind(Bind b) {
225
- // If a bind with the same port already exists, replace it.
226
- Bind prev = NULL;
227
-
228
- if (NULL == b->read) {
229
- b->read = con_http_read;
230
- }
231
- if (NULL == b->write) {
232
- b->write = con_http_write;
233
- }
234
- if (NULL == b->events) {
235
- b->events = con_http_events;
236
- }
237
- for (Bind bx = the_server.binds; NULL != bx; bx = bx->next) {
238
- if (bx->port == b->port) {
239
- b->next = bx->next;
240
- if (NULL == prev) {
241
- the_server.binds = b;
242
- } else {
243
- prev->next = b;
244
- }
245
- bind_destroy(bx);
246
- return;
247
- }
248
- prev = bx;
249
- }
250
- b->next = the_server.binds;
251
- the_server.binds = b;
252
- }
253
-
254
- void
255
- server_add_upgraded(Upgraded up) {
256
- pthread_mutex_lock(&the_server.up_lock);
257
- if (NULL == the_server.up_list) {
258
- up->next = NULL;
259
- } else {
260
- the_server.up_list->prev = up;
261
- }
262
- up->next = the_server.up_list;
263
- the_server.up_list = up;
264
- up->con->up = up;
265
- pthread_mutex_unlock(&the_server.up_lock);
266
- }
267
-
268
- int
269
- server_add_func_hook(Err err,
270
- Method method,
271
- const char *pattern,
272
- void (*func)(Req req),
273
- Queue queue) {
274
- Hook h;
275
- Hook prev = NULL;
276
- Hook hook = hook_func_create(method, pattern, func, queue);
277
-
278
- if (NULL == hook) {
279
- return err_set(err, ERR_MEMORY, "failed to allocate memory for HTTP server Hook.");
280
- }
281
- for (h = the_server.hooks; NULL != h; h = h->next) {
282
- prev = h;
283
- }
284
- if (NULL != prev) {
285
- prev->next = hook;
286
- } else {
287
- the_server.hooks = hook;
288
- }
289
- return ERR_OK;
290
- }
291
-
292
- void
293
- server_publish(struct _Pub *pub) {
294
- ConLoop loop;
295
-
296
- for (loop = the_server.con_loops; NULL != loop; loop = loop->next) {
297
- if (NULL == loop->next) {
298
- queue_push(&loop->pub_queue, pub);
299
- } else {
300
- queue_push(&loop->pub_queue, pub_dup(pub));
301
- }
302
- }
303
- }
@@ -1,67 +0,0 @@
1
- // Copyright (c) 2018, Peter Ohler, All rights reserved.
2
-
3
- #ifndef __AGOO_SERVER_H__
4
- #define __AGOO_SERVER_H__
5
-
6
- #include <pthread.h>
7
- #include <stdbool.h>
8
- #include <stdatomic.h>
9
-
10
- #include "bind.h"
11
- #include "err.h"
12
- #include "hook.h"
13
- #include "queue.h"
14
-
15
- struct _ConLoop;
16
- struct _Pub;
17
- struct _Req;
18
- struct _Upgraded;
19
-
20
- typedef struct _Server {
21
- volatile bool inited;
22
- volatile bool active;
23
- int thread_cnt;
24
- bool pedantic;
25
- bool root_first;
26
- pthread_t listen_thread;
27
- struct _Queue con_queue;
28
- Hook hooks;
29
- Hook hook404;
30
- Bind binds;
31
-
32
- struct _Queue eval_queue;
33
-
34
- struct _ConLoop *con_loops;
35
- int loop_cnt;
36
- atomic_int con_cnt;
37
-
38
- struct _Upgraded *up_list;
39
- pthread_mutex_t up_lock;
40
- int max_push_pending;
41
- void *env_nil_value;
42
- void *ctx_nil_value;
43
-
44
- // A count of the running threads from the wrapper or the server managed
45
- // threads.
46
- atomic_int running;
47
- } *Server;
48
-
49
- extern struct _Server the_server;
50
-
51
- extern void server_setup();
52
- extern void server_shutdown(const char *app_name, void (*stop)());
53
- extern void server_bind(Bind b);
54
-
55
- extern int setup_listen(Err err);
56
- extern int server_start(Err err, const char *app_name, const char *version);
57
-
58
- extern void server_add_upgraded(struct _Upgraded *up);
59
- extern int server_add_func_hook(Err err,
60
- Method method,
61
- const char *pattern,
62
- void (*func)(struct _Req *req),
63
- Queue queue);
64
-
65
- extern void server_publish(struct _Pub *pub);
66
-
67
- #endif // __AGOO_SERVER_H__
@@ -1,182 +0,0 @@
1
- // Copyright (c) 2018, Peter Ohler, All rights reserved.
2
-
3
- #include <stdio.h>
4
- #include <string.h>
5
-
6
- #include "con.h"
7
- #include "debug.h"
8
- #include "pub.h"
9
- #include "server.h"
10
- #include "subject.h"
11
- #include "upgraded.h"
12
-
13
- static void
14
- destroy(Upgraded up) {
15
- Subject subject;
16
-
17
- if (NULL != up->on_destroy) {
18
- up->on_destroy(up);
19
- }
20
- if (NULL == up->prev) {
21
- the_server.up_list = up->next;
22
- if (NULL != up->next) {
23
- up->next->prev = NULL;
24
- }
25
- } else {
26
- up->prev->next = up->next;
27
- if (NULL != up->next) {
28
- up->next->prev = up->prev;
29
- }
30
- }
31
- while (NULL != (subject = up->subjects)) {
32
- up->subjects = up->subjects->next;
33
- subject_destroy(subject);
34
- }
35
- DEBUG_FREE(mem_upgraded, up);
36
- free(up);
37
- }
38
-
39
- void
40
- upgraded_release(Upgraded up) {
41
- pthread_mutex_lock(&the_server.up_lock);
42
- if (atomic_fetch_sub(&up->ref_cnt, 1) <= 1) {
43
- destroy(up);
44
- }
45
- pthread_mutex_unlock(&the_server.up_lock);
46
- }
47
-
48
- void
49
- upgraded_release_con(Upgraded up) {
50
- pthread_mutex_lock(&the_server.up_lock);
51
- up->con = NULL;
52
- if (atomic_fetch_sub(&up->ref_cnt, 1) <= 1) {
53
- destroy(up);
54
- }
55
- pthread_mutex_unlock(&the_server.up_lock);
56
- }
57
-
58
- // Called from the con_loop thread, no need to lock, this steals the subject
59
- // so the pub subject should set to NULL
60
- void
61
- upgraded_add_subject(Upgraded up, Subject subject) {
62
- Subject s;
63
-
64
- for (s = up->subjects; NULL != s; s = s->next) {
65
- if (0 == strcmp(subject->pattern, s->pattern)) {
66
- subject_destroy(subject);
67
- return;
68
- }
69
- }
70
- subject->next = up->subjects;
71
- up->subjects = subject;
72
- }
73
-
74
- void
75
- upgraded_del_subject(Upgraded up, Subject subject) {
76
- if (NULL == subject) {
77
- while (NULL != (subject = up->subjects)) {
78
- up->subjects = up->subjects->next;
79
- subject_destroy(subject);
80
- }
81
- } else {
82
- Subject s;
83
- Subject prev = NULL;
84
-
85
- for (s = up->subjects; NULL != s; s = s->next) {
86
- if (0 == strcmp(subject->pattern, s->pattern)) {
87
- if (NULL == prev) {
88
- up->subjects = s->next;
89
- } else {
90
- prev->next = s->next;
91
- }
92
- subject_destroy(s);
93
- break;
94
- }
95
- prev = s;
96
- }
97
- }
98
- }
99
-
100
- bool
101
- upgraded_match(Upgraded up, const char *subject) {
102
- Subject s;
103
-
104
- for (s = up->subjects; NULL != s; s = s->next) {
105
- if (subject_check(s, subject)) {
106
- return true;
107
- }
108
- }
109
- return false;
110
- }
111
-
112
- void
113
- upgraded_ref(Upgraded up) {
114
- atomic_fetch_add(&up->ref_cnt, 1);
115
- }
116
-
117
- bool
118
- upgraded_write(Upgraded up, const char *message, size_t mlen, bool bin, bool inc_ref) {
119
- Pub p;
120
-
121
- if (0 < the_server.max_push_pending && the_server.max_push_pending <= atomic_load(&up->pending)) {
122
- atomic_fetch_sub(&up->ref_cnt, 1);
123
- // Too many pending messages.
124
- return false;
125
- }
126
- if (inc_ref) {
127
- atomic_fetch_add(&up->ref_cnt, 1);
128
- }
129
- p = pub_write(up, message, mlen, bin);
130
- atomic_fetch_add(&up->pending, 1);
131
- server_publish(p);
132
-
133
- return true;
134
- }
135
-
136
- void
137
- upgraded_subscribe(Upgraded up, const char *subject, int slen, bool inc_ref) {
138
- if (inc_ref) {
139
- atomic_fetch_add(&up->ref_cnt, 1);
140
- }
141
- atomic_fetch_add(&up->pending, 1);
142
- server_publish(pub_subscribe(up, subject, slen));
143
- }
144
-
145
- void
146
- upgraded_unsubscribe(Upgraded up, const char *subject, int slen, bool inc_ref) {
147
- if (inc_ref) {
148
- atomic_fetch_add(&up->ref_cnt, 1);
149
- }
150
- atomic_fetch_add(&up->pending, 1);
151
- server_publish(pub_unsubscribe(up, subject, slen));
152
- }
153
-
154
- void
155
- upgraded_close(Upgraded up, bool inc_ref) {
156
- if (inc_ref) {
157
- atomic_fetch_add(&up->ref_cnt, 1);
158
- }
159
- atomic_fetch_add(&up->pending, 1);
160
- server_publish(pub_close(up));
161
- }
162
-
163
- int
164
- upgraded_pending(Upgraded up) {
165
- return atomic_load(&up->pending);
166
- }
167
-
168
- Upgraded
169
- upgraded_create(Con c, void * ctx, void *env) {
170
- Upgraded up = (Upgraded)malloc(sizeof(struct _Upgraded));
171
-
172
- if (NULL != up) {
173
- DEBUG_ALLOC(mem_upgraded, up);
174
- memset(up, 0, sizeof(struct _Upgraded));
175
- up->con = c;
176
- up->ctx = ctx;
177
- up->env = env;
178
- atomic_init(&up->pending, 0);
179
- atomic_init(&up->ref_cnt, 1); // start with 1 for the Con reference
180
- }
181
- return up;
182
- }