nutcracker 0.2.3

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.
Files changed (149) hide show
  1. data/README.md +22 -0
  2. data/Rakefile +55 -0
  3. data/bin/nutcracker +2 -0
  4. data/ext/nutcracker/ChangeLog +66 -0
  5. data/ext/nutcracker/LICENSE +177 -0
  6. data/ext/nutcracker/Makefile.am +7 -0
  7. data/ext/nutcracker/Makefile.in +726 -0
  8. data/ext/nutcracker/NOTICE +124 -0
  9. data/ext/nutcracker/README.md +240 -0
  10. data/ext/nutcracker/aclocal.m4 +956 -0
  11. data/ext/nutcracker/conf/nutcracker.leaf.yml +10 -0
  12. data/ext/nutcracker/conf/nutcracker.root.yml +8 -0
  13. data/ext/nutcracker/conf/nutcracker.yml +67 -0
  14. data/ext/nutcracker/config.h.in +316 -0
  15. data/ext/nutcracker/config/config.guess +1561 -0
  16. data/ext/nutcracker/config/config.sub +1686 -0
  17. data/ext/nutcracker/config/depcomp +630 -0
  18. data/ext/nutcracker/config/install-sh +520 -0
  19. data/ext/nutcracker/config/ltmain.sh +8413 -0
  20. data/ext/nutcracker/config/missing +376 -0
  21. data/ext/nutcracker/configure +18862 -0
  22. data/ext/nutcracker/configure.ac +155 -0
  23. data/ext/nutcracker/contrib/Makefile.am +3 -0
  24. data/ext/nutcracker/contrib/Makefile.in +560 -0
  25. data/ext/nutcracker/contrib/yaml-0.1.4.tar.gz +0 -0
  26. data/ext/nutcracker/contrib/yaml-0.1.4/LICENSE +19 -0
  27. data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.am +20 -0
  28. data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.in +736 -0
  29. data/ext/nutcracker/contrib/yaml-0.1.4/README +27 -0
  30. data/ext/nutcracker/contrib/yaml-0.1.4/aclocal.m4 +956 -0
  31. data/ext/nutcracker/contrib/yaml-0.1.4/config.h.in +80 -0
  32. data/ext/nutcracker/contrib/yaml-0.1.4/config/config.guess +1561 -0
  33. data/ext/nutcracker/contrib/yaml-0.1.4/config/config.sub +1686 -0
  34. data/ext/nutcracker/contrib/yaml-0.1.4/config/depcomp +630 -0
  35. data/ext/nutcracker/contrib/yaml-0.1.4/config/install-sh +520 -0
  36. data/ext/nutcracker/contrib/yaml-0.1.4/config/ltmain.sh +8406 -0
  37. data/ext/nutcracker/contrib/yaml-0.1.4/config/missing +376 -0
  38. data/ext/nutcracker/contrib/yaml-0.1.4/configure +13085 -0
  39. data/ext/nutcracker/contrib/yaml-0.1.4/configure.ac +75 -0
  40. data/ext/nutcracker/contrib/yaml-0.1.4/doc/doxygen.cfg +222 -0
  41. data/ext/nutcracker/contrib/yaml-0.1.4/include/yaml.h +1971 -0
  42. data/ext/nutcracker/contrib/yaml-0.1.4/m4/libtool.m4 +7357 -0
  43. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltoptions.m4 +368 -0
  44. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltsugar.m4 +123 -0
  45. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltversion.m4 +23 -0
  46. data/ext/nutcracker/contrib/yaml-0.1.4/m4/lt~obsolete.m4 +92 -0
  47. data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.am +4 -0
  48. data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.in +484 -0
  49. data/ext/nutcracker/contrib/yaml-0.1.4/src/api.c +1392 -0
  50. data/ext/nutcracker/contrib/yaml-0.1.4/src/dumper.c +394 -0
  51. data/ext/nutcracker/contrib/yaml-0.1.4/src/emitter.c +2329 -0
  52. data/ext/nutcracker/contrib/yaml-0.1.4/src/loader.c +432 -0
  53. data/ext/nutcracker/contrib/yaml-0.1.4/src/parser.c +1374 -0
  54. data/ext/nutcracker/contrib/yaml-0.1.4/src/reader.c +465 -0
  55. data/ext/nutcracker/contrib/yaml-0.1.4/src/scanner.c +3570 -0
  56. data/ext/nutcracker/contrib/yaml-0.1.4/src/writer.c +141 -0
  57. data/ext/nutcracker/contrib/yaml-0.1.4/src/yaml_private.h +640 -0
  58. data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.am +8 -0
  59. data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.in +675 -0
  60. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor-alt.c +800 -0
  61. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor.c +1130 -0
  62. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter-alt.c +217 -0
  63. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter.c +202 -0
  64. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-dumper.c +311 -0
  65. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-emitter.c +327 -0
  66. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-loader.c +63 -0
  67. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-parser.c +63 -0
  68. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-scanner.c +63 -0
  69. data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-reader.c +354 -0
  70. data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-version.c +29 -0
  71. data/ext/nutcracker/extconf.rb +5 -0
  72. data/ext/nutcracker/m4/libtool.m4 +7376 -0
  73. data/ext/nutcracker/m4/ltoptions.m4 +368 -0
  74. data/ext/nutcracker/m4/ltsugar.m4 +123 -0
  75. data/ext/nutcracker/m4/ltversion.m4 +23 -0
  76. data/ext/nutcracker/m4/lt~obsolete.m4 +92 -0
  77. data/ext/nutcracker/notes/c-styleguide.txt +425 -0
  78. data/ext/nutcracker/notes/debug.txt +96 -0
  79. data/ext/nutcracker/notes/memcache.txt +123 -0
  80. data/ext/nutcracker/notes/recommendation.md +118 -0
  81. data/ext/nutcracker/notes/redis.md +415 -0
  82. data/ext/nutcracker/notes/socket.txt +131 -0
  83. data/ext/nutcracker/scripts/multi_get.sh +26 -0
  84. data/ext/nutcracker/scripts/nutcracker.init +73 -0
  85. data/ext/nutcracker/scripts/nutcracker.spec +52 -0
  86. data/ext/nutcracker/scripts/pipelined_read.sh +23 -0
  87. data/ext/nutcracker/scripts/pipelined_write.sh +29 -0
  88. data/ext/nutcracker/scripts/populate_memcached.sh +24 -0
  89. data/ext/nutcracker/scripts/redis-check.py +23 -0
  90. data/ext/nutcracker/scripts/redis-check.sh +564 -0
  91. data/ext/nutcracker/src/Makefile.am +46 -0
  92. data/ext/nutcracker/src/Makefile.in +726 -0
  93. data/ext/nutcracker/src/hashkit/Makefile.am +22 -0
  94. data/ext/nutcracker/src/hashkit/Makefile.in +501 -0
  95. data/ext/nutcracker/src/hashkit/nc_crc32.c +105 -0
  96. data/ext/nutcracker/src/hashkit/nc_fnv.c +82 -0
  97. data/ext/nutcracker/src/hashkit/nc_hashkit.h +74 -0
  98. data/ext/nutcracker/src/hashkit/nc_hsieh.c +93 -0
  99. data/ext/nutcracker/src/hashkit/nc_jenkins.c +230 -0
  100. data/ext/nutcracker/src/hashkit/nc_ketama.c +240 -0
  101. data/ext/nutcracker/src/hashkit/nc_md5.c +379 -0
  102. data/ext/nutcracker/src/hashkit/nc_modula.c +144 -0
  103. data/ext/nutcracker/src/hashkit/nc_murmur.c +99 -0
  104. data/ext/nutcracker/src/hashkit/nc_one_at_a_time.c +51 -0
  105. data/ext/nutcracker/src/hashkit/nc_random.c +146 -0
  106. data/ext/nutcracker/src/nc.c +573 -0
  107. data/ext/nutcracker/src/nc_array.c +204 -0
  108. data/ext/nutcracker/src/nc_array.h +73 -0
  109. data/ext/nutcracker/src/nc_client.c +189 -0
  110. data/ext/nutcracker/src/nc_client.h +28 -0
  111. data/ext/nutcracker/src/nc_conf.c +1766 -0
  112. data/ext/nutcracker/src/nc_conf.h +134 -0
  113. data/ext/nutcracker/src/nc_connection.c +392 -0
  114. data/ext/nutcracker/src/nc_connection.h +99 -0
  115. data/ext/nutcracker/src/nc_core.c +334 -0
  116. data/ext/nutcracker/src/nc_core.h +131 -0
  117. data/ext/nutcracker/src/nc_event.c +214 -0
  118. data/ext/nutcracker/src/nc_event.h +39 -0
  119. data/ext/nutcracker/src/nc_log.c +254 -0
  120. data/ext/nutcracker/src/nc_log.h +120 -0
  121. data/ext/nutcracker/src/nc_mbuf.c +285 -0
  122. data/ext/nutcracker/src/nc_mbuf.h +67 -0
  123. data/ext/nutcracker/src/nc_message.c +828 -0
  124. data/ext/nutcracker/src/nc_message.h +253 -0
  125. data/ext/nutcracker/src/nc_proxy.c +359 -0
  126. data/ext/nutcracker/src/nc_proxy.h +34 -0
  127. data/ext/nutcracker/src/nc_queue.h +788 -0
  128. data/ext/nutcracker/src/nc_rbtree.c +348 -0
  129. data/ext/nutcracker/src/nc_rbtree.h +47 -0
  130. data/ext/nutcracker/src/nc_request.c +588 -0
  131. data/ext/nutcracker/src/nc_response.c +332 -0
  132. data/ext/nutcracker/src/nc_server.c +841 -0
  133. data/ext/nutcracker/src/nc_server.h +143 -0
  134. data/ext/nutcracker/src/nc_signal.c +131 -0
  135. data/ext/nutcracker/src/nc_signal.h +34 -0
  136. data/ext/nutcracker/src/nc_stats.c +1188 -0
  137. data/ext/nutcracker/src/nc_stats.h +206 -0
  138. data/ext/nutcracker/src/nc_string.c +109 -0
  139. data/ext/nutcracker/src/nc_string.h +112 -0
  140. data/ext/nutcracker/src/nc_util.c +619 -0
  141. data/ext/nutcracker/src/nc_util.h +214 -0
  142. data/ext/nutcracker/src/proto/Makefile.am +14 -0
  143. data/ext/nutcracker/src/proto/Makefile.in +482 -0
  144. data/ext/nutcracker/src/proto/nc_memcache.c +1306 -0
  145. data/ext/nutcracker/src/proto/nc_proto.h +155 -0
  146. data/ext/nutcracker/src/proto/nc_redis.c +2102 -0
  147. data/lib/nutcracker.rb +7 -0
  148. data/lib/nutcracker/version.rb +3 -0
  149. metadata +194 -0
@@ -0,0 +1,99 @@
1
+ /*
2
+ * twemproxy - A fast and lightweight proxy for memcached protocol.
3
+ * Copyright (C) 2011 Twitter, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #ifndef _NC_CONNECTION_H_
19
+ #define _NC_CONNECTION_H_
20
+
21
+ #include <nc_core.h>
22
+
23
+ typedef rstatus_t (*conn_recv_t)(struct context *, struct conn*);
24
+ typedef struct msg* (*conn_recv_next_t)(struct context *, struct conn *, bool);
25
+ typedef void (*conn_recv_done_t)(struct context *, struct conn *, struct msg *, struct msg *);
26
+
27
+ typedef rstatus_t (*conn_send_t)(struct context *, struct conn*);
28
+ typedef struct msg* (*conn_send_next_t)(struct context *, struct conn *);
29
+ typedef void (*conn_send_done_t)(struct context *, struct conn *, struct msg *);
30
+
31
+ typedef void (*conn_close_t)(struct context *, struct conn *);
32
+ typedef bool (*conn_active_t)(struct conn *);
33
+
34
+ typedef void (*conn_ref_t)(struct conn *, void *);
35
+ typedef void (*conn_unref_t)(struct conn *);
36
+
37
+ typedef void (*conn_msgq_t)(struct context *, struct conn *, struct msg *);
38
+
39
+ struct conn {
40
+ TAILQ_ENTRY(conn) conn_tqe; /* link in server_pool / server / free q */
41
+ void *owner; /* connection owner - server_pool / server */
42
+
43
+ int sd; /* socket descriptor */
44
+ int family; /* socket address family */
45
+ socklen_t addrlen; /* socket length */
46
+ struct sockaddr *addr; /* socket address (ref in server or server_pool) */
47
+
48
+ struct msg_tqh imsg_q; /* incoming request Q */
49
+ struct msg_tqh omsg_q; /* outstanding request Q */
50
+ struct msg *rmsg; /* current message being rcvd */
51
+ struct msg *smsg; /* current message being sent */
52
+
53
+ conn_recv_t recv; /* recv (read) handler */
54
+ conn_recv_next_t recv_next; /* recv next message handler */
55
+ conn_recv_done_t recv_done; /* read done handler */
56
+ conn_send_t send; /* send (write) handler */
57
+ conn_send_next_t send_next; /* write next message handler */
58
+ conn_send_done_t send_done; /* write done handler */
59
+ conn_close_t close; /* close handler */
60
+ conn_active_t active; /* active? handler */
61
+
62
+ conn_ref_t ref; /* connection reference handler */
63
+ conn_unref_t unref; /* connection unreference handler */
64
+
65
+ conn_msgq_t enqueue_inq; /* connection inq msg enqueue handler */
66
+ conn_msgq_t dequeue_inq; /* connection inq msg dequeue handler */
67
+ conn_msgq_t enqueue_outq; /* connection outq msg enqueue handler */
68
+ conn_msgq_t dequeue_outq; /* connection outq msg dequeue handler */
69
+
70
+ size_t recv_bytes; /* received (read) bytes */
71
+ size_t send_bytes; /* sent (written) bytes */
72
+
73
+ uint32_t events; /* connection io events */
74
+ err_t err; /* connection errno */
75
+ unsigned recv_active:1; /* recv active? */
76
+ unsigned recv_ready:1; /* recv ready? */
77
+ unsigned send_active:1; /* send active? */
78
+ unsigned send_ready:1; /* send ready? */
79
+
80
+ unsigned client:1; /* client? or server? */
81
+ unsigned proxy:1; /* proxy? */
82
+ unsigned connecting:1; /* connecting? */
83
+ unsigned connected:1; /* connected? */
84
+ unsigned eof:1; /* eof? aka passive close? */
85
+ unsigned done:1; /* done? aka close? */
86
+ unsigned redis:1; /* redis? */
87
+ };
88
+
89
+ TAILQ_HEAD(conn_tqh, conn);
90
+
91
+ struct conn *conn_get(void *owner, bool client, bool redis);
92
+ struct conn *conn_get_proxy(void *owner);
93
+ void conn_put(struct conn *conn);
94
+ ssize_t conn_recv(struct conn *conn, void *buf, size_t size);
95
+ ssize_t conn_sendv(struct conn *conn, struct array *sendv, size_t nsend);
96
+ void conn_init(void);
97
+ void conn_deinit(void);
98
+
99
+ #endif
@@ -0,0 +1,334 @@
1
+ /*
2
+ * twemproxy - A fast and lightweight proxy for memcached protocol.
3
+ * Copyright (C) 2011 Twitter, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #include <stdlib.h>
19
+ #include <unistd.h>
20
+
21
+ #include <sys/epoll.h>
22
+
23
+ #include <nc_core.h>
24
+ #include <nc_event.h>
25
+ #include <nc_conf.h>
26
+ #include <nc_server.h>
27
+ #include <nc_proxy.h>
28
+
29
+ static uint32_t ctx_id; /* context generation */
30
+
31
+ static struct context *
32
+ core_ctx_create(struct instance *nci)
33
+ {
34
+ rstatus_t status;
35
+ struct context *ctx;
36
+
37
+ ctx = nc_alloc(sizeof(*ctx));
38
+ if (ctx == NULL) {
39
+ return NULL;
40
+ }
41
+ ctx->id = ++ctx_id;
42
+ ctx->cf = NULL;
43
+ ctx->stats = NULL;
44
+ array_null(&ctx->pool);
45
+ ctx->ep = -1;
46
+ ctx->nevent = EVENT_SIZE_HINT;
47
+ ctx->max_timeout = nci->stats_interval;
48
+ ctx->timeout = ctx->max_timeout;
49
+ ctx->event = NULL;
50
+
51
+ /* parse and create configuration */
52
+ ctx->cf = conf_create(nci->conf_filename);
53
+ if (ctx->cf == NULL) {
54
+ nc_free(ctx);
55
+ return NULL;
56
+ }
57
+
58
+ /* initialize server pool from configuration */
59
+ status = server_pool_init(&ctx->pool, &ctx->cf->pool, ctx);
60
+ if (status != NC_OK) {
61
+ conf_destroy(ctx->cf);
62
+ nc_free(ctx);
63
+ return NULL;
64
+ }
65
+
66
+ /* create stats per server pool */
67
+ ctx->stats = stats_create(nci->stats_port, nci->stats_addr, nci->stats_interval,
68
+ nci->hostname, &ctx->pool);
69
+ if (ctx->stats == NULL) {
70
+ server_pool_deinit(&ctx->pool);
71
+ conf_destroy(ctx->cf);
72
+ nc_free(ctx);
73
+ return NULL;
74
+ }
75
+
76
+ /* initialize event handling for client, proxy and server */
77
+ status = event_init(ctx, EVENT_SIZE_HINT);
78
+ if (status != NC_OK) {
79
+ stats_destroy(ctx->stats);
80
+ server_pool_deinit(&ctx->pool);
81
+ conf_destroy(ctx->cf);
82
+ nc_free(ctx);
83
+ return NULL;
84
+ }
85
+
86
+ /* preconnect? servers in server pool */
87
+ status = server_pool_preconnect(ctx);
88
+ if (status != NC_OK) {
89
+ server_pool_disconnect(ctx);
90
+ event_deinit(ctx);
91
+ stats_destroy(ctx->stats);
92
+ server_pool_deinit(&ctx->pool);
93
+ conf_destroy(ctx->cf);
94
+ nc_free(ctx);
95
+ return NULL;
96
+ }
97
+
98
+ /* initialize proxy per server pool */
99
+ status = proxy_init(ctx);
100
+ if (status != NC_OK) {
101
+ server_pool_disconnect(ctx);
102
+ event_deinit(ctx);
103
+ stats_destroy(ctx->stats);
104
+ server_pool_deinit(&ctx->pool);
105
+ conf_destroy(ctx->cf);
106
+ nc_free(ctx);
107
+ return NULL;
108
+ }
109
+
110
+ log_debug(LOG_VVERB, "created ctx %p id %"PRIu32"", ctx, ctx->id);
111
+
112
+ return ctx;
113
+ }
114
+
115
+ static void
116
+ core_ctx_destroy(struct context *ctx)
117
+ {
118
+ log_debug(LOG_VVERB, "destroy ctx %p id %"PRIu32"", ctx, ctx->id);
119
+ proxy_deinit(ctx);
120
+ server_pool_disconnect(ctx);
121
+ event_deinit(ctx);
122
+ stats_destroy(ctx->stats);
123
+ server_pool_deinit(&ctx->pool);
124
+ conf_destroy(ctx->cf);
125
+ nc_free(ctx);
126
+ }
127
+
128
+ struct context *
129
+ core_start(struct instance *nci)
130
+ {
131
+ struct context *ctx;
132
+
133
+ mbuf_init(nci);
134
+ msg_init();
135
+ conn_init();
136
+
137
+ ctx = core_ctx_create(nci);
138
+ if (ctx != NULL) {
139
+ nci->ctx = ctx;
140
+ return ctx;
141
+ }
142
+
143
+ conn_deinit();
144
+ msg_deinit();
145
+ mbuf_deinit();
146
+
147
+ return NULL;
148
+ }
149
+
150
+ void
151
+ core_stop(struct context *ctx)
152
+ {
153
+ conn_deinit();
154
+ msg_deinit();
155
+ mbuf_deinit();
156
+ core_ctx_destroy(ctx);
157
+ }
158
+
159
+ static rstatus_t
160
+ core_recv(struct context *ctx, struct conn *conn)
161
+ {
162
+ rstatus_t status;
163
+
164
+ status = conn->recv(ctx, conn);
165
+ if (status != NC_OK) {
166
+ log_debug(LOG_INFO, "recv on %c %d failed: %s",
167
+ conn->client ? 'c' : (conn->proxy ? 'p' : 's'), conn->sd,
168
+ strerror(errno));
169
+ }
170
+
171
+ return status;
172
+ }
173
+
174
+ static rstatus_t
175
+ core_send(struct context *ctx, struct conn *conn)
176
+ {
177
+ rstatus_t status;
178
+
179
+ status = conn->send(ctx, conn);
180
+ if (status != NC_OK) {
181
+ log_debug(LOG_INFO, "send on %c %d failed: %s",
182
+ conn->client ? 'c' : (conn->proxy ? 'p' : 's'), conn->sd,
183
+ strerror(errno));
184
+ }
185
+
186
+ return status;
187
+ }
188
+
189
+ static void
190
+ core_close(struct context *ctx, struct conn *conn)
191
+ {
192
+ rstatus_t status;
193
+ char type, *addrstr;
194
+
195
+ ASSERT(conn->sd > 0);
196
+
197
+ if (conn->client) {
198
+ type = 'c';
199
+ addrstr = nc_unresolve_peer_desc(conn->sd);
200
+ } else {
201
+ type = conn->proxy ? 'p' : 's';
202
+ addrstr = nc_unresolve_addr(conn->addr, conn->addrlen);
203
+ }
204
+ log_debug(LOG_NOTICE, "close %c %d '%s' on event %04"PRIX32" eof %d done "
205
+ "%d rb %zu sb %zu%c %s", type, conn->sd, addrstr, conn->events,
206
+ conn->eof, conn->done, conn->recv_bytes, conn->send_bytes,
207
+ conn->err ? ':' : ' ', conn->err ? strerror(conn->err) : "");
208
+
209
+ status = event_del_conn(ctx->ep, conn);
210
+ if (status < 0) {
211
+ log_warn("event del conn e %d %c %d failed, ignored: %s", ctx->ep,
212
+ type, conn->sd, strerror(errno));
213
+ }
214
+
215
+ conn->close(ctx, conn);
216
+ }
217
+
218
+ static void
219
+ core_error(struct context *ctx, struct conn *conn)
220
+ {
221
+ rstatus_t status;
222
+ char type = conn->client ? 'c' : (conn->proxy ? 'p' : 's');
223
+
224
+ status = nc_get_soerror(conn->sd);
225
+ if (status < 0) {
226
+ log_warn("get soerr on %c %d failed, ignored: %s", type, conn->sd,
227
+ strerror(errno));
228
+ }
229
+ conn->err = errno;
230
+
231
+ core_close(ctx, conn);
232
+ }
233
+
234
+ static void
235
+ core_timeout(struct context *ctx)
236
+ {
237
+ for (;;) {
238
+ struct msg *msg;
239
+ struct conn *conn;
240
+ int64_t now, then;
241
+
242
+ msg = msg_tmo_min();
243
+ if (msg == NULL) {
244
+ ctx->timeout = ctx->max_timeout;
245
+ return;
246
+ }
247
+
248
+ /* skip over req that are in-error or done */
249
+
250
+ if (msg->error || msg->done) {
251
+ msg_tmo_delete(msg);
252
+ continue;
253
+ }
254
+
255
+ /*
256
+ * timeout expired req and all the outstanding req on the timing
257
+ * out server
258
+ */
259
+
260
+ conn = msg->tmo_rbe.data;
261
+ then = msg->tmo_rbe.key;
262
+
263
+ now = nc_msec_now();
264
+ if (now < then) {
265
+ int delta = (int)(then - now);
266
+ ctx->timeout = MIN(delta, ctx->max_timeout);
267
+ return;
268
+ }
269
+
270
+ log_debug(LOG_INFO, "req %"PRIu64" on s %d timedout", msg->id, conn->sd);
271
+
272
+ msg_tmo_delete(msg);
273
+ conn->err = ETIMEDOUT;
274
+
275
+ core_close(ctx, conn);
276
+ }
277
+ }
278
+
279
+ static void
280
+ core_core(struct context *ctx, struct conn *conn, uint32_t events)
281
+ {
282
+ rstatus_t status;
283
+
284
+ log_debug(LOG_VVERB, "event %04"PRIX32" on %c %d", events,
285
+ conn->client ? 'c' : (conn->proxy ? 'p' : 's'), conn->sd);
286
+
287
+ conn->events = events;
288
+
289
+ /* error takes precedence over read | write */
290
+ if (events & EPOLLERR) {
291
+ core_error(ctx, conn);
292
+ return;
293
+ }
294
+
295
+ /* read takes precedence over write */
296
+ if (events & (EPOLLIN | EPOLLHUP)) {
297
+ status = core_recv(ctx, conn);
298
+ if (status != NC_OK || conn->done || conn->err) {
299
+ core_close(ctx, conn);
300
+ return;
301
+ }
302
+ }
303
+
304
+ if (events & EPOLLOUT) {
305
+ status = core_send(ctx, conn);
306
+ if (status != NC_OK || conn->done || conn->err) {
307
+ core_close(ctx, conn);
308
+ return;
309
+ }
310
+ }
311
+ }
312
+
313
+ rstatus_t
314
+ core_loop(struct context *ctx)
315
+ {
316
+ int i, nsd;
317
+
318
+ nsd = event_wait(ctx->ep, ctx->event, ctx->nevent, ctx->timeout);
319
+ if (nsd < 0) {
320
+ return nsd;
321
+ }
322
+
323
+ for (i = 0; i < nsd; i++) {
324
+ struct epoll_event *ev = &ctx->event[i];
325
+
326
+ core_core(ctx, ev->data.ptr, ev->events);
327
+ }
328
+
329
+ core_timeout(ctx);
330
+
331
+ stats_swap(ctx->stats);
332
+
333
+ return NC_OK;
334
+ }
@@ -0,0 +1,131 @@
1
+ /*
2
+ * twemproxy - A fast and lightweight proxy for memcached protocol.
3
+ * Copyright (C) 2011 Twitter, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #ifndef _NC_CORE_H_
19
+ #define _NC_CORE_H_
20
+
21
+ #ifdef HAVE_CONFIG_H
22
+ # include <config.h>
23
+ #endif
24
+
25
+ #ifdef HAVE_DEBUG_LOG
26
+ # define NC_DEBUG_LOG 1
27
+ #endif
28
+
29
+ #ifdef HAVE_ASSERT_PANIC
30
+ # define NC_ASSERT_PANIC 1
31
+ #endif
32
+
33
+ #ifdef HAVE_ASSERT_LOG
34
+ # define NC_ASSERT_LOG 1
35
+ #endif
36
+
37
+ #ifdef HAVE_STATS
38
+ # define NC_STATS 1
39
+ #else
40
+ # define NC_STATS 0
41
+ #endif
42
+
43
+ #ifdef HAVE_LITTLE_ENDIAN
44
+ # define NC_LITTLE_ENDIAN 1
45
+ #endif
46
+
47
+ #define NC_OK 0
48
+ #define NC_ERROR -1
49
+ #define NC_EAGAIN -2
50
+ #define NC_ENOMEM -3
51
+
52
+ typedef int rstatus_t; /* return type */
53
+ typedef int err_t; /* error type */
54
+
55
+ struct array;
56
+ struct string;
57
+ struct context;
58
+ struct conn;
59
+ struct conn_tqh;
60
+ struct msg;
61
+ struct msg_tqh;
62
+ struct server;
63
+ struct server_pool;
64
+ struct mbuf;
65
+ struct mhdr;
66
+ struct conf;
67
+ struct stats;
68
+ struct epoll_event;
69
+ struct instance;
70
+
71
+ #include <stddef.h>
72
+ #include <stdint.h>
73
+ #include <stdbool.h>
74
+ #include <inttypes.h>
75
+ #include <string.h>
76
+ #include <errno.h>
77
+ #include <limits.h>
78
+ #include <time.h>
79
+ #include <unistd.h>
80
+ #include <pthread.h>
81
+
82
+ #include <sys/types.h>
83
+ #include <sys/socket.h>
84
+ #include <sys/un.h>
85
+ #include <netinet/in.h>
86
+
87
+ #include <nc_array.h>
88
+ #include <nc_string.h>
89
+ #include <nc_queue.h>
90
+ #include <nc_rbtree.h>
91
+ #include <nc_log.h>
92
+ #include <nc_util.h>
93
+ #include <nc_stats.h>
94
+ #include <nc_mbuf.h>
95
+ #include <nc_message.h>
96
+ #include <nc_connection.h>
97
+
98
+ struct context {
99
+ uint32_t id; /* unique context id */
100
+ struct conf *cf; /* configuration */
101
+ struct stats *stats; /* stats */
102
+
103
+ struct array pool; /* server_pool[] */
104
+
105
+ int ep; /* epoll device */
106
+ int nevent; /* # epoll event */
107
+ int max_timeout; /* epoll wait max timeout in msec */
108
+ int timeout; /* epoll wait timeout in msec */
109
+ struct epoll_event *event; /* epoll event */
110
+ };
111
+
112
+ struct instance {
113
+ struct context *ctx; /* active context */
114
+ int log_level; /* log level */
115
+ char *log_filename; /* log filename */
116
+ char *conf_filename; /* configuration filename */
117
+ uint16_t stats_port; /* stats monitoring port */
118
+ int stats_interval; /* stats aggregation interval */
119
+ char *stats_addr; /* stats monitoring addr */
120
+ char hostname[NC_MAXHOSTNAMELEN]; /* hostname */
121
+ size_t mbuf_chunk_size; /* mbuf chunk size */
122
+ pid_t pid; /* process id */
123
+ char *pid_filename; /* pid filename */
124
+ unsigned pidfile:1; /* pid file created? */
125
+ };
126
+
127
+ struct context *core_start(struct instance *nci);
128
+ void core_stop(struct context *ctx);
129
+ rstatus_t core_loop(struct context *ctx);
130
+
131
+ #endif