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.
- data/README.md +22 -0
- data/Rakefile +55 -0
- data/bin/nutcracker +2 -0
- data/ext/nutcracker/ChangeLog +66 -0
- data/ext/nutcracker/LICENSE +177 -0
- data/ext/nutcracker/Makefile.am +7 -0
- data/ext/nutcracker/Makefile.in +726 -0
- data/ext/nutcracker/NOTICE +124 -0
- data/ext/nutcracker/README.md +240 -0
- data/ext/nutcracker/aclocal.m4 +956 -0
- data/ext/nutcracker/conf/nutcracker.leaf.yml +10 -0
- data/ext/nutcracker/conf/nutcracker.root.yml +8 -0
- data/ext/nutcracker/conf/nutcracker.yml +67 -0
- data/ext/nutcracker/config.h.in +316 -0
- data/ext/nutcracker/config/config.guess +1561 -0
- data/ext/nutcracker/config/config.sub +1686 -0
- data/ext/nutcracker/config/depcomp +630 -0
- data/ext/nutcracker/config/install-sh +520 -0
- data/ext/nutcracker/config/ltmain.sh +8413 -0
- data/ext/nutcracker/config/missing +376 -0
- data/ext/nutcracker/configure +18862 -0
- data/ext/nutcracker/configure.ac +155 -0
- data/ext/nutcracker/contrib/Makefile.am +3 -0
- data/ext/nutcracker/contrib/Makefile.in +560 -0
- data/ext/nutcracker/contrib/yaml-0.1.4.tar.gz +0 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/LICENSE +19 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.am +20 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.in +736 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/README +27 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/aclocal.m4 +956 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config.h.in +80 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/config.guess +1561 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/config.sub +1686 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/depcomp +630 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/install-sh +520 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/ltmain.sh +8406 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/missing +376 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/configure +13085 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/configure.ac +75 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/doc/doxygen.cfg +222 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/include/yaml.h +1971 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/libtool.m4 +7357 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltoptions.m4 +368 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltsugar.m4 +123 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltversion.m4 +23 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/lt~obsolete.m4 +92 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.am +4 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.in +484 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/api.c +1392 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/dumper.c +394 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/emitter.c +2329 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/loader.c +432 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/parser.c +1374 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/reader.c +465 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/scanner.c +3570 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/writer.c +141 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/yaml_private.h +640 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.am +8 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.in +675 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor-alt.c +800 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor.c +1130 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter-alt.c +217 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter.c +202 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-dumper.c +311 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-emitter.c +327 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-loader.c +63 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-parser.c +63 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-scanner.c +63 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-reader.c +354 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-version.c +29 -0
- data/ext/nutcracker/extconf.rb +5 -0
- data/ext/nutcracker/m4/libtool.m4 +7376 -0
- data/ext/nutcracker/m4/ltoptions.m4 +368 -0
- data/ext/nutcracker/m4/ltsugar.m4 +123 -0
- data/ext/nutcracker/m4/ltversion.m4 +23 -0
- data/ext/nutcracker/m4/lt~obsolete.m4 +92 -0
- data/ext/nutcracker/notes/c-styleguide.txt +425 -0
- data/ext/nutcracker/notes/debug.txt +96 -0
- data/ext/nutcracker/notes/memcache.txt +123 -0
- data/ext/nutcracker/notes/recommendation.md +118 -0
- data/ext/nutcracker/notes/redis.md +415 -0
- data/ext/nutcracker/notes/socket.txt +131 -0
- data/ext/nutcracker/scripts/multi_get.sh +26 -0
- data/ext/nutcracker/scripts/nutcracker.init +73 -0
- data/ext/nutcracker/scripts/nutcracker.spec +52 -0
- data/ext/nutcracker/scripts/pipelined_read.sh +23 -0
- data/ext/nutcracker/scripts/pipelined_write.sh +29 -0
- data/ext/nutcracker/scripts/populate_memcached.sh +24 -0
- data/ext/nutcracker/scripts/redis-check.py +23 -0
- data/ext/nutcracker/scripts/redis-check.sh +564 -0
- data/ext/nutcracker/src/Makefile.am +46 -0
- data/ext/nutcracker/src/Makefile.in +726 -0
- data/ext/nutcracker/src/hashkit/Makefile.am +22 -0
- data/ext/nutcracker/src/hashkit/Makefile.in +501 -0
- data/ext/nutcracker/src/hashkit/nc_crc32.c +105 -0
- data/ext/nutcracker/src/hashkit/nc_fnv.c +82 -0
- data/ext/nutcracker/src/hashkit/nc_hashkit.h +74 -0
- data/ext/nutcracker/src/hashkit/nc_hsieh.c +93 -0
- data/ext/nutcracker/src/hashkit/nc_jenkins.c +230 -0
- data/ext/nutcracker/src/hashkit/nc_ketama.c +240 -0
- data/ext/nutcracker/src/hashkit/nc_md5.c +379 -0
- data/ext/nutcracker/src/hashkit/nc_modula.c +144 -0
- data/ext/nutcracker/src/hashkit/nc_murmur.c +99 -0
- data/ext/nutcracker/src/hashkit/nc_one_at_a_time.c +51 -0
- data/ext/nutcracker/src/hashkit/nc_random.c +146 -0
- data/ext/nutcracker/src/nc.c +573 -0
- data/ext/nutcracker/src/nc_array.c +204 -0
- data/ext/nutcracker/src/nc_array.h +73 -0
- data/ext/nutcracker/src/nc_client.c +189 -0
- data/ext/nutcracker/src/nc_client.h +28 -0
- data/ext/nutcracker/src/nc_conf.c +1766 -0
- data/ext/nutcracker/src/nc_conf.h +134 -0
- data/ext/nutcracker/src/nc_connection.c +392 -0
- data/ext/nutcracker/src/nc_connection.h +99 -0
- data/ext/nutcracker/src/nc_core.c +334 -0
- data/ext/nutcracker/src/nc_core.h +131 -0
- data/ext/nutcracker/src/nc_event.c +214 -0
- data/ext/nutcracker/src/nc_event.h +39 -0
- data/ext/nutcracker/src/nc_log.c +254 -0
- data/ext/nutcracker/src/nc_log.h +120 -0
- data/ext/nutcracker/src/nc_mbuf.c +285 -0
- data/ext/nutcracker/src/nc_mbuf.h +67 -0
- data/ext/nutcracker/src/nc_message.c +828 -0
- data/ext/nutcracker/src/nc_message.h +253 -0
- data/ext/nutcracker/src/nc_proxy.c +359 -0
- data/ext/nutcracker/src/nc_proxy.h +34 -0
- data/ext/nutcracker/src/nc_queue.h +788 -0
- data/ext/nutcracker/src/nc_rbtree.c +348 -0
- data/ext/nutcracker/src/nc_rbtree.h +47 -0
- data/ext/nutcracker/src/nc_request.c +588 -0
- data/ext/nutcracker/src/nc_response.c +332 -0
- data/ext/nutcracker/src/nc_server.c +841 -0
- data/ext/nutcracker/src/nc_server.h +143 -0
- data/ext/nutcracker/src/nc_signal.c +131 -0
- data/ext/nutcracker/src/nc_signal.h +34 -0
- data/ext/nutcracker/src/nc_stats.c +1188 -0
- data/ext/nutcracker/src/nc_stats.h +206 -0
- data/ext/nutcracker/src/nc_string.c +109 -0
- data/ext/nutcracker/src/nc_string.h +112 -0
- data/ext/nutcracker/src/nc_util.c +619 -0
- data/ext/nutcracker/src/nc_util.h +214 -0
- data/ext/nutcracker/src/proto/Makefile.am +14 -0
- data/ext/nutcracker/src/proto/Makefile.in +482 -0
- data/ext/nutcracker/src/proto/nc_memcache.c +1306 -0
- data/ext/nutcracker/src/proto/nc_proto.h +155 -0
- data/ext/nutcracker/src/proto/nc_redis.c +2102 -0
- data/lib/nutcracker.rb +7 -0
- data/lib/nutcracker/version.rb +3 -0
- 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
|