nutcracker 0.3.0.12 → 0.4.0.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/README.md +3 -3
- data/Rakefile +12 -10
- data/ext/nutcracker/Makefile.in +215 -162
- data/ext/nutcracker/README.md +16 -4
- data/ext/nutcracker/aclocal.m4 +432 -254
- data/ext/nutcracker/{contrib/yaml-0.1.4/configure → autom4te.cache/output.0} +11367 -4545
- data/ext/nutcracker/autom4te.cache/output.1 +19907 -0
- data/ext/nutcracker/autom4te.cache/output.2 +19907 -0
- data/ext/nutcracker/autom4te.cache/requests +518 -0
- data/ext/nutcracker/autom4te.cache/traces.0 +2715 -0
- data/ext/nutcracker/autom4te.cache/traces.1 +967 -0
- data/ext/nutcracker/autom4te.cache/traces.2 +2715 -0
- data/ext/nutcracker/config/compile +347 -0
- data/ext/nutcracker/config/config.guess +116 -78
- data/ext/nutcracker/config/config.sub +65 -45
- data/ext/nutcracker/config/depcomp +295 -192
- data/ext/nutcracker/config/install-sh +7 -7
- data/ext/nutcracker/config/ltmain.sh +15 -20
- data/ext/nutcracker/config/missing +149 -265
- data/ext/nutcracker/configure +493 -367
- data/ext/nutcracker/contrib/Makefile.in +158 -116
- data/ext/nutcracker/extconf.rb +0 -1
- data/ext/nutcracker/m4/libtool.m4 +4 -23
- data/ext/nutcracker/m4/ltoptions.m4 +0 -0
- data/ext/nutcracker/m4/ltsugar.m4 +0 -0
- data/ext/nutcracker/m4/ltversion.m4 +0 -0
- data/ext/nutcracker/m4/lt~obsolete.m4 +0 -0
- data/ext/nutcracker/notes/recommendation.md +1 -1
- data/ext/nutcracker/notes/redis.md +35 -3
- data/ext/nutcracker/scripts/benchmark-mget.py +43 -0
- data/ext/nutcracker/scripts/nutcracker.spec +61 -3
- data/ext/nutcracker/scripts/redis-check.sh +43 -0
- data/ext/nutcracker/src/Makefile.in +205 -142
- data/ext/nutcracker/src/event/Makefile.in +164 -66
- data/ext/nutcracker/src/hashkit/Makefile.in +164 -66
- data/ext/nutcracker/src/nc_conf.c +2 -0
- data/ext/nutcracker/src/nc_connection.c +31 -0
- data/ext/nutcracker/src/nc_connection.h +3 -0
- data/ext/nutcracker/src/nc_core.c +38 -2
- data/ext/nutcracker/src/nc_core.h +11 -0
- data/ext/nutcracker/src/nc_log.c +90 -12
- data/ext/nutcracker/src/nc_log.h +11 -0
- data/ext/nutcracker/src/nc_mbuf.h +1 -1
- data/ext/nutcracker/src/nc_message.c +162 -116
- data/ext/nutcracker/src/nc_message.h +161 -129
- data/ext/nutcracker/src/nc_proxy.c +34 -4
- data/ext/nutcracker/src/nc_request.c +158 -32
- data/ext/nutcracker/src/nc_server.c +59 -5
- data/ext/nutcracker/src/nc_server.h +1 -0
- data/ext/nutcracker/src/nc_signal.c +2 -2
- data/ext/nutcracker/src/nc_stats.c +21 -0
- data/ext/nutcracker/src/nc_stats.h +28 -26
- data/ext/nutcracker/src/nc_string.c +176 -1
- data/ext/nutcracker/src/nc_string.h +26 -0
- data/ext/nutcracker/src/nc_util.c +12 -0
- data/ext/nutcracker/src/nc_util.h +1 -0
- data/ext/nutcracker/src/proto/Makefile.in +164 -66
- data/ext/nutcracker/src/proto/nc_memcache.c +279 -88
- data/ext/nutcracker/src/proto/nc_proto.h +3 -4
- data/ext/nutcracker/src/proto/nc_redis.c +561 -134
- data/lib/nutcracker/version.rb +1 -1
- metadata +31 -67
- data/ext/nutcracker/contrib/yaml-0.1.4/LICENSE +0 -19
- data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.am +0 -20
- data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.in +0 -736
- data/ext/nutcracker/contrib/yaml-0.1.4/README +0 -27
- data/ext/nutcracker/contrib/yaml-0.1.4/aclocal.m4 +0 -956
- data/ext/nutcracker/contrib/yaml-0.1.4/config.h.in +0 -80
- data/ext/nutcracker/contrib/yaml-0.1.4/config/config.guess +0 -1561
- data/ext/nutcracker/contrib/yaml-0.1.4/config/config.sub +0 -1686
- data/ext/nutcracker/contrib/yaml-0.1.4/config/depcomp +0 -630
- data/ext/nutcracker/contrib/yaml-0.1.4/config/install-sh +0 -520
- data/ext/nutcracker/contrib/yaml-0.1.4/config/ltmain.sh +0 -8406
- data/ext/nutcracker/contrib/yaml-0.1.4/config/missing +0 -376
- data/ext/nutcracker/contrib/yaml-0.1.4/configure.ac +0 -75
- data/ext/nutcracker/contrib/yaml-0.1.4/doc/doxygen.cfg +0 -222
- data/ext/nutcracker/contrib/yaml-0.1.4/include/yaml.h +0 -1971
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/libtool.m4 +0 -7357
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltoptions.m4 +0 -368
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltsugar.m4 +0 -123
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltversion.m4 +0 -23
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/lt~obsolete.m4 +0 -92
- data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.am +0 -4
- data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.in +0 -484
- data/ext/nutcracker/contrib/yaml-0.1.4/src/api.c +0 -1392
- data/ext/nutcracker/contrib/yaml-0.1.4/src/dumper.c +0 -394
- data/ext/nutcracker/contrib/yaml-0.1.4/src/emitter.c +0 -2329
- data/ext/nutcracker/contrib/yaml-0.1.4/src/loader.c +0 -432
- data/ext/nutcracker/contrib/yaml-0.1.4/src/parser.c +0 -1374
- data/ext/nutcracker/contrib/yaml-0.1.4/src/reader.c +0 -465
- data/ext/nutcracker/contrib/yaml-0.1.4/src/scanner.c +0 -3570
- data/ext/nutcracker/contrib/yaml-0.1.4/src/writer.c +0 -141
- data/ext/nutcracker/contrib/yaml-0.1.4/src/yaml_private.h +0 -640
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.am +0 -8
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.in +0 -675
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor-alt.c +0 -800
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor.c +0 -1130
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter-alt.c +0 -217
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter.c +0 -202
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-dumper.c +0 -311
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-emitter.c +0 -327
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-loader.c +0 -63
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-parser.c +0 -63
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-scanner.c +0 -63
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-reader.c +0 -354
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-version.c +0 -29
@@ -21,139 +21,163 @@
|
|
21
21
|
#include <nc_core.h>
|
22
22
|
|
23
23
|
typedef void (*msg_parse_t)(struct msg *);
|
24
|
-
typedef rstatus_t (*
|
24
|
+
typedef rstatus_t (*msg_fragment_t)(struct msg *, uint32_t, struct msg_tqh *);
|
25
25
|
typedef void (*msg_coalesce_t)(struct msg *r);
|
26
|
+
typedef rstatus_t (*msg_reply_t)(struct msg *r);
|
26
27
|
|
27
28
|
typedef enum msg_parse_result {
|
28
29
|
MSG_PARSE_OK, /* parsing ok */
|
29
30
|
MSG_PARSE_ERROR, /* parsing error */
|
30
31
|
MSG_PARSE_REPAIR, /* more to parse -> repair parsed & unparsed data */
|
31
|
-
MSG_PARSE_FRAGMENT, /* multi-vector request -> fragment */
|
32
32
|
MSG_PARSE_AGAIN, /* incomplete -> parse again */
|
33
33
|
} msg_parse_result_t;
|
34
34
|
|
35
|
+
#define MSG_TYPE_CODEC(ACTION) \
|
36
|
+
ACTION( UNKNOWN ) \
|
37
|
+
ACTION( REQ_MC_GET ) /* memcache retrieval requests */ \
|
38
|
+
ACTION( REQ_MC_GETS ) \
|
39
|
+
ACTION( REQ_MC_DELETE ) /* memcache delete request */ \
|
40
|
+
ACTION( REQ_MC_CAS ) /* memcache cas request and storage request */ \
|
41
|
+
ACTION( REQ_MC_SET ) /* memcache storage request */ \
|
42
|
+
ACTION( REQ_MC_ADD ) \
|
43
|
+
ACTION( REQ_MC_REPLACE ) \
|
44
|
+
ACTION( REQ_MC_APPEND ) \
|
45
|
+
ACTION( REQ_MC_PREPEND ) \
|
46
|
+
ACTION( REQ_MC_INCR ) /* memcache arithmetic request */ \
|
47
|
+
ACTION( REQ_MC_DECR ) \
|
48
|
+
ACTION( REQ_MC_QUIT ) /* memcache quit request */ \
|
49
|
+
ACTION( RSP_MC_NUM ) /* memcache arithmetic response */ \
|
50
|
+
ACTION( RSP_MC_STORED ) /* memcache cas and storage response */ \
|
51
|
+
ACTION( RSP_MC_NOT_STORED ) \
|
52
|
+
ACTION( RSP_MC_EXISTS ) \
|
53
|
+
ACTION( RSP_MC_NOT_FOUND ) \
|
54
|
+
ACTION( RSP_MC_END ) \
|
55
|
+
ACTION( RSP_MC_VALUE ) \
|
56
|
+
ACTION( RSP_MC_DELETED ) /* memcache delete response */ \
|
57
|
+
ACTION( RSP_MC_ERROR ) /* memcache error responses */ \
|
58
|
+
ACTION( RSP_MC_CLIENT_ERROR ) \
|
59
|
+
ACTION( RSP_MC_SERVER_ERROR ) \
|
60
|
+
ACTION( REQ_REDIS_DEL ) /* redis commands - keys */ \
|
61
|
+
ACTION( REQ_REDIS_EXISTS ) \
|
62
|
+
ACTION( REQ_REDIS_EXPIRE ) \
|
63
|
+
ACTION( REQ_REDIS_EXPIREAT ) \
|
64
|
+
ACTION( REQ_REDIS_PEXPIRE ) \
|
65
|
+
ACTION( REQ_REDIS_PEXPIREAT ) \
|
66
|
+
ACTION( REQ_REDIS_PERSIST ) \
|
67
|
+
ACTION( REQ_REDIS_PTTL ) \
|
68
|
+
ACTION( REQ_REDIS_SORT ) \
|
69
|
+
ACTION( REQ_REDIS_TTL ) \
|
70
|
+
ACTION( REQ_REDIS_TYPE ) \
|
71
|
+
ACTION( REQ_REDIS_APPEND ) /* redis requests - string */ \
|
72
|
+
ACTION( REQ_REDIS_BITCOUNT ) \
|
73
|
+
ACTION( REQ_REDIS_DECR ) \
|
74
|
+
ACTION( REQ_REDIS_DECRBY ) \
|
75
|
+
ACTION( REQ_REDIS_DUMP ) \
|
76
|
+
ACTION( REQ_REDIS_GET ) \
|
77
|
+
ACTION( REQ_REDIS_GETBIT ) \
|
78
|
+
ACTION( REQ_REDIS_GETRANGE ) \
|
79
|
+
ACTION( REQ_REDIS_GETSET ) \
|
80
|
+
ACTION( REQ_REDIS_INCR ) \
|
81
|
+
ACTION( REQ_REDIS_INCRBY ) \
|
82
|
+
ACTION( REQ_REDIS_INCRBYFLOAT ) \
|
83
|
+
ACTION( REQ_REDIS_MGET ) \
|
84
|
+
ACTION( REQ_REDIS_MSET ) \
|
85
|
+
ACTION( REQ_REDIS_PSETEX ) \
|
86
|
+
ACTION( REQ_REDIS_RESTORE ) \
|
87
|
+
ACTION( REQ_REDIS_SET ) \
|
88
|
+
ACTION( REQ_REDIS_SETBIT ) \
|
89
|
+
ACTION( REQ_REDIS_SETEX ) \
|
90
|
+
ACTION( REQ_REDIS_SETNX ) \
|
91
|
+
ACTION( REQ_REDIS_SETRANGE ) \
|
92
|
+
ACTION( REQ_REDIS_STRLEN ) \
|
93
|
+
ACTION( REQ_REDIS_HDEL ) /* redis requests - hashes */ \
|
94
|
+
ACTION( REQ_REDIS_HEXISTS ) \
|
95
|
+
ACTION( REQ_REDIS_HGET ) \
|
96
|
+
ACTION( REQ_REDIS_HGETALL ) \
|
97
|
+
ACTION( REQ_REDIS_HINCRBY ) \
|
98
|
+
ACTION( REQ_REDIS_HINCRBYFLOAT ) \
|
99
|
+
ACTION( REQ_REDIS_HKEYS ) \
|
100
|
+
ACTION( REQ_REDIS_HLEN ) \
|
101
|
+
ACTION( REQ_REDIS_HMGET ) \
|
102
|
+
ACTION( REQ_REDIS_HMSET ) \
|
103
|
+
ACTION( REQ_REDIS_HSET ) \
|
104
|
+
ACTION( REQ_REDIS_HSETNX ) \
|
105
|
+
ACTION( REQ_REDIS_HSCAN) \
|
106
|
+
ACTION( REQ_REDIS_HVALS ) \
|
107
|
+
ACTION( REQ_REDIS_LINDEX ) /* redis requests - lists */ \
|
108
|
+
ACTION( REQ_REDIS_LINSERT ) \
|
109
|
+
ACTION( REQ_REDIS_LLEN ) \
|
110
|
+
ACTION( REQ_REDIS_LPOP ) \
|
111
|
+
ACTION( REQ_REDIS_LPUSH ) \
|
112
|
+
ACTION( REQ_REDIS_LPUSHX ) \
|
113
|
+
ACTION( REQ_REDIS_LRANGE ) \
|
114
|
+
ACTION( REQ_REDIS_LREM ) \
|
115
|
+
ACTION( REQ_REDIS_LSET ) \
|
116
|
+
ACTION( REQ_REDIS_LTRIM ) \
|
117
|
+
ACTION( REQ_REDIS_PFADD ) /* redis requests - hyperloglog */ \
|
118
|
+
ACTION( REQ_REDIS_PFCOUNT ) \
|
119
|
+
ACTION( REQ_REDIS_PFMERGE ) \
|
120
|
+
ACTION( REQ_REDIS_RPOP ) \
|
121
|
+
ACTION( REQ_REDIS_RPOPLPUSH ) \
|
122
|
+
ACTION( REQ_REDIS_RPUSH ) \
|
123
|
+
ACTION( REQ_REDIS_RPUSHX ) \
|
124
|
+
ACTION( REQ_REDIS_SADD ) /* redis requests - sets */ \
|
125
|
+
ACTION( REQ_REDIS_SCARD ) \
|
126
|
+
ACTION( REQ_REDIS_SDIFF ) \
|
127
|
+
ACTION( REQ_REDIS_SDIFFSTORE ) \
|
128
|
+
ACTION( REQ_REDIS_SINTER ) \
|
129
|
+
ACTION( REQ_REDIS_SINTERSTORE ) \
|
130
|
+
ACTION( REQ_REDIS_SISMEMBER ) \
|
131
|
+
ACTION( REQ_REDIS_SMEMBERS ) \
|
132
|
+
ACTION( REQ_REDIS_SMOVE ) \
|
133
|
+
ACTION( REQ_REDIS_SPOP ) \
|
134
|
+
ACTION( REQ_REDIS_SRANDMEMBER ) \
|
135
|
+
ACTION( REQ_REDIS_SREM ) \
|
136
|
+
ACTION( REQ_REDIS_SUNION ) \
|
137
|
+
ACTION( REQ_REDIS_SUNIONSTORE ) \
|
138
|
+
ACTION( REQ_REDIS_SSCAN) \
|
139
|
+
ACTION( REQ_REDIS_ZADD ) /* redis requests - sorted sets */ \
|
140
|
+
ACTION( REQ_REDIS_ZCARD ) \
|
141
|
+
ACTION( REQ_REDIS_ZCOUNT ) \
|
142
|
+
ACTION( REQ_REDIS_ZINCRBY ) \
|
143
|
+
ACTION( REQ_REDIS_ZINTERSTORE ) \
|
144
|
+
ACTION( REQ_REDIS_ZLEXCOUNT ) \
|
145
|
+
ACTION( REQ_REDIS_ZRANGE ) \
|
146
|
+
ACTION( REQ_REDIS_ZRANGEBYLEX ) \
|
147
|
+
ACTION( REQ_REDIS_ZRANGEBYSCORE ) \
|
148
|
+
ACTION( REQ_REDIS_ZRANK ) \
|
149
|
+
ACTION( REQ_REDIS_ZREM ) \
|
150
|
+
ACTION( REQ_REDIS_ZREMRANGEBYRANK ) \
|
151
|
+
ACTION( REQ_REDIS_ZREMRANGEBYLEX ) \
|
152
|
+
ACTION( REQ_REDIS_ZREMRANGEBYSCORE ) \
|
153
|
+
ACTION( REQ_REDIS_ZREVRANGE ) \
|
154
|
+
ACTION( REQ_REDIS_ZREVRANGEBYSCORE ) \
|
155
|
+
ACTION( REQ_REDIS_ZREVRANK ) \
|
156
|
+
ACTION( REQ_REDIS_ZSCORE ) \
|
157
|
+
ACTION( REQ_REDIS_ZUNIONSTORE ) \
|
158
|
+
ACTION( REQ_REDIS_ZSCAN) \
|
159
|
+
ACTION( REQ_REDIS_EVAL ) /* redis requests - eval */ \
|
160
|
+
ACTION( REQ_REDIS_EVALSHA ) \
|
161
|
+
ACTION( REQ_REDIS_PING ) /* redis requests - ping/quit */ \
|
162
|
+
ACTION( REQ_REDIS_QUIT) \
|
163
|
+
ACTION( RSP_REDIS_STATUS ) /* redis response */ \
|
164
|
+
ACTION( RSP_REDIS_ERROR ) \
|
165
|
+
ACTION( RSP_REDIS_INTEGER ) \
|
166
|
+
ACTION( RSP_REDIS_BULK ) \
|
167
|
+
ACTION( RSP_REDIS_MULTIBULK ) \
|
168
|
+
ACTION( SENTINEL ) \
|
169
|
+
|
170
|
+
|
171
|
+
#define DEFINE_ACTION(_name) MSG_##_name,
|
35
172
|
typedef enum msg_type {
|
36
|
-
|
37
|
-
MSG_REQ_MC_GET, /* memcache retrieval requests */
|
38
|
-
MSG_REQ_MC_GETS,
|
39
|
-
MSG_REQ_MC_DELETE, /* memcache delete request */
|
40
|
-
MSG_REQ_MC_CAS, /* memcache cas request and storage request */
|
41
|
-
MSG_REQ_MC_SET, /* memcache storage request */
|
42
|
-
MSG_REQ_MC_ADD,
|
43
|
-
MSG_REQ_MC_REPLACE,
|
44
|
-
MSG_REQ_MC_APPEND,
|
45
|
-
MSG_REQ_MC_PREPEND,
|
46
|
-
MSG_REQ_MC_INCR, /* memcache arithmetic request */
|
47
|
-
MSG_REQ_MC_DECR,
|
48
|
-
MSG_REQ_MC_QUIT, /* memcache quit request */
|
49
|
-
MSG_RSP_MC_NUM, /* memcache arithmetic response */
|
50
|
-
MSG_RSP_MC_STORED, /* memcache cas and storage response */
|
51
|
-
MSG_RSP_MC_NOT_STORED,
|
52
|
-
MSG_RSP_MC_EXISTS,
|
53
|
-
MSG_RSP_MC_NOT_FOUND,
|
54
|
-
MSG_RSP_MC_END,
|
55
|
-
MSG_RSP_MC_VALUE,
|
56
|
-
MSG_RSP_MC_DELETED, /* memcache delete response */
|
57
|
-
MSG_RSP_MC_ERROR, /* memcache error responses */
|
58
|
-
MSG_RSP_MC_CLIENT_ERROR,
|
59
|
-
MSG_RSP_MC_SERVER_ERROR,
|
60
|
-
MSG_REQ_REDIS_DEL, /* redis commands - keys */
|
61
|
-
MSG_REQ_REDIS_EXISTS,
|
62
|
-
MSG_REQ_REDIS_EXPIRE,
|
63
|
-
MSG_REQ_REDIS_EXPIREAT,
|
64
|
-
MSG_REQ_REDIS_PEXPIRE,
|
65
|
-
MSG_REQ_REDIS_PEXPIREAT,
|
66
|
-
MSG_REQ_REDIS_PERSIST,
|
67
|
-
MSG_REQ_REDIS_PTTL,
|
68
|
-
MSG_REQ_REDIS_TTL,
|
69
|
-
MSG_REQ_REDIS_TYPE,
|
70
|
-
MSG_REQ_REDIS_APPEND, /* redis requests - string */
|
71
|
-
MSG_REQ_REDIS_BITCOUNT,
|
72
|
-
MSG_REQ_REDIS_DECR,
|
73
|
-
MSG_REQ_REDIS_DECRBY,
|
74
|
-
MSG_REQ_REDIS_DUMP,
|
75
|
-
MSG_REQ_REDIS_GET,
|
76
|
-
MSG_REQ_REDIS_GETBIT,
|
77
|
-
MSG_REQ_REDIS_GETRANGE,
|
78
|
-
MSG_REQ_REDIS_GETSET,
|
79
|
-
MSG_REQ_REDIS_INCR,
|
80
|
-
MSG_REQ_REDIS_INCRBY,
|
81
|
-
MSG_REQ_REDIS_INCRBYFLOAT,
|
82
|
-
MSG_REQ_REDIS_MGET,
|
83
|
-
MSG_REQ_REDIS_PSETEX,
|
84
|
-
MSG_REQ_REDIS_RESTORE,
|
85
|
-
MSG_REQ_REDIS_SET,
|
86
|
-
MSG_REQ_REDIS_SETBIT,
|
87
|
-
MSG_REQ_REDIS_SETEX,
|
88
|
-
MSG_REQ_REDIS_SETNX,
|
89
|
-
MSG_REQ_REDIS_SETRANGE,
|
90
|
-
MSG_REQ_REDIS_STRLEN,
|
91
|
-
MSG_REQ_REDIS_HDEL, /* redis requests - hashes */
|
92
|
-
MSG_REQ_REDIS_HEXISTS,
|
93
|
-
MSG_REQ_REDIS_HGET,
|
94
|
-
MSG_REQ_REDIS_HGETALL,
|
95
|
-
MSG_REQ_REDIS_HINCRBY,
|
96
|
-
MSG_REQ_REDIS_HINCRBYFLOAT,
|
97
|
-
MSG_REQ_REDIS_HKEYS,
|
98
|
-
MSG_REQ_REDIS_HLEN,
|
99
|
-
MSG_REQ_REDIS_HMGET,
|
100
|
-
MSG_REQ_REDIS_HMSET,
|
101
|
-
MSG_REQ_REDIS_HSET,
|
102
|
-
MSG_REQ_REDIS_HSETNX,
|
103
|
-
MSG_REQ_REDIS_HVALS,
|
104
|
-
MSG_REQ_REDIS_LINDEX, /* redis requests - lists */
|
105
|
-
MSG_REQ_REDIS_LINSERT,
|
106
|
-
MSG_REQ_REDIS_LLEN,
|
107
|
-
MSG_REQ_REDIS_LPOP,
|
108
|
-
MSG_REQ_REDIS_LPUSH,
|
109
|
-
MSG_REQ_REDIS_LPUSHX,
|
110
|
-
MSG_REQ_REDIS_LRANGE,
|
111
|
-
MSG_REQ_REDIS_LREM,
|
112
|
-
MSG_REQ_REDIS_LSET,
|
113
|
-
MSG_REQ_REDIS_LTRIM,
|
114
|
-
MSG_REQ_REDIS_RPOP,
|
115
|
-
MSG_REQ_REDIS_RPOPLPUSH,
|
116
|
-
MSG_REQ_REDIS_RPUSH,
|
117
|
-
MSG_REQ_REDIS_RPUSHX,
|
118
|
-
MSG_REQ_REDIS_SADD, /* redis requests - sets */
|
119
|
-
MSG_REQ_REDIS_SCARD,
|
120
|
-
MSG_REQ_REDIS_SDIFF,
|
121
|
-
MSG_REQ_REDIS_SDIFFSTORE,
|
122
|
-
MSG_REQ_REDIS_SINTER,
|
123
|
-
MSG_REQ_REDIS_SINTERSTORE,
|
124
|
-
MSG_REQ_REDIS_SISMEMBER,
|
125
|
-
MSG_REQ_REDIS_SMEMBERS,
|
126
|
-
MSG_REQ_REDIS_SMOVE,
|
127
|
-
MSG_REQ_REDIS_SPOP,
|
128
|
-
MSG_REQ_REDIS_SRANDMEMBER,
|
129
|
-
MSG_REQ_REDIS_SREM,
|
130
|
-
MSG_REQ_REDIS_SUNION,
|
131
|
-
MSG_REQ_REDIS_SUNIONSTORE,
|
132
|
-
MSG_REQ_REDIS_ZADD, /* redis requests - sorted sets */
|
133
|
-
MSG_REQ_REDIS_ZCARD,
|
134
|
-
MSG_REQ_REDIS_ZCOUNT,
|
135
|
-
MSG_REQ_REDIS_ZINCRBY,
|
136
|
-
MSG_REQ_REDIS_ZINTERSTORE,
|
137
|
-
MSG_REQ_REDIS_ZRANGE,
|
138
|
-
MSG_REQ_REDIS_ZRANGEBYSCORE,
|
139
|
-
MSG_REQ_REDIS_ZRANK,
|
140
|
-
MSG_REQ_REDIS_ZREM,
|
141
|
-
MSG_REQ_REDIS_ZREMRANGEBYRANK,
|
142
|
-
MSG_REQ_REDIS_ZREMRANGEBYSCORE,
|
143
|
-
MSG_REQ_REDIS_ZREVRANGE,
|
144
|
-
MSG_REQ_REDIS_ZREVRANGEBYSCORE,
|
145
|
-
MSG_REQ_REDIS_ZREVRANK,
|
146
|
-
MSG_REQ_REDIS_ZSCORE,
|
147
|
-
MSG_REQ_REDIS_ZUNIONSTORE,
|
148
|
-
MSG_REQ_REDIS_EVAL, /* redis requests - eval */
|
149
|
-
MSG_REQ_REDIS_EVALSHA,
|
150
|
-
MSG_RSP_REDIS_STATUS, /* redis response */
|
151
|
-
MSG_RSP_REDIS_ERROR,
|
152
|
-
MSG_RSP_REDIS_INTEGER,
|
153
|
-
MSG_RSP_REDIS_BULK,
|
154
|
-
MSG_RSP_REDIS_MULTIBULK,
|
155
|
-
MSG_SENTINEL
|
173
|
+
MSG_TYPE_CODEC(DEFINE_ACTION)
|
156
174
|
} msg_type_t;
|
175
|
+
#undef DEFINE_ACTION
|
176
|
+
|
177
|
+
struct keypos {
|
178
|
+
uint8_t *start; /* key start pos */
|
179
|
+
uint8_t *end; /* key end pos */
|
180
|
+
};
|
157
181
|
|
158
182
|
struct msg {
|
159
183
|
TAILQ_ENTRY(msg) c_tqe; /* link in client q */
|
@@ -168,6 +192,7 @@ struct msg {
|
|
168
192
|
|
169
193
|
struct mhdr mhdr; /* message mbuf header */
|
170
194
|
uint32_t mlen; /* message length */
|
195
|
+
int64_t start_ts; /* request start timestamp in usec */
|
171
196
|
|
172
197
|
int state; /* current parser state */
|
173
198
|
uint8_t *pos; /* parser position marker */
|
@@ -176,15 +201,14 @@ struct msg {
|
|
176
201
|
msg_parse_t parser; /* message parser */
|
177
202
|
msg_parse_result_t result; /* message parsing result */
|
178
203
|
|
179
|
-
|
180
|
-
|
204
|
+
msg_fragment_t fragment; /* message fragment */
|
205
|
+
msg_reply_t reply; /* gen message reply (example: ping) */
|
181
206
|
msg_coalesce_t pre_coalesce; /* message pre-coalesce */
|
182
207
|
msg_coalesce_t post_coalesce; /* message post-coalesce */
|
183
208
|
|
184
209
|
msg_type_t type; /* message type */
|
185
210
|
|
186
|
-
|
187
|
-
uint8_t *key_end; /* key end */
|
211
|
+
struct array *keys; /* array of keypos, for req */
|
188
212
|
|
189
213
|
uint32_t vlen; /* value length (memcache) */
|
190
214
|
uint8_t *end; /* end marker (memcache) */
|
@@ -198,7 +222,9 @@ struct msg {
|
|
198
222
|
|
199
223
|
struct msg *frag_owner; /* owner of fragment message */
|
200
224
|
uint32_t nfrag; /* # fragment */
|
225
|
+
uint32_t nfrag_done; /* # fragment done */
|
201
226
|
uint64_t frag_id; /* id of fragmented message */
|
227
|
+
struct msg **frag_seq; /* sequence of fragment message, map from keys to fragments*/
|
202
228
|
|
203
229
|
err_t err; /* errno on error? */
|
204
230
|
unsigned error:1; /* error? */
|
@@ -206,10 +232,9 @@ struct msg {
|
|
206
232
|
unsigned request:1; /* request? or response? */
|
207
233
|
unsigned quit:1; /* quit request? */
|
208
234
|
unsigned noreply:1; /* noreply? */
|
235
|
+
unsigned noforward:1; /* not need forward (example: ping) */
|
209
236
|
unsigned done:1; /* done? */
|
210
237
|
unsigned fdone:1; /* all fragments are done? */
|
211
|
-
unsigned first_fragment:1;/* first fragment? */
|
212
|
-
unsigned last_fragment:1; /* last fragment? */
|
213
238
|
unsigned swallow:1; /* swallow response? */
|
214
239
|
unsigned redis:1; /* redis? */
|
215
240
|
};
|
@@ -222,13 +247,20 @@ void msg_tmo_delete(struct msg *msg);
|
|
222
247
|
|
223
248
|
void msg_init(void);
|
224
249
|
void msg_deinit(void);
|
250
|
+
struct string *msg_type_string(msg_type_t type);
|
225
251
|
struct msg *msg_get(struct conn *conn, bool request, bool redis);
|
226
252
|
void msg_put(struct msg *msg);
|
227
253
|
struct msg *msg_get_error(bool redis, err_t err);
|
228
|
-
void msg_dump(struct msg *msg);
|
254
|
+
void msg_dump(struct msg *msg, int level);
|
229
255
|
bool msg_empty(struct msg *msg);
|
230
256
|
rstatus_t msg_recv(struct context *ctx, struct conn *conn);
|
231
257
|
rstatus_t msg_send(struct context *ctx, struct conn *conn);
|
258
|
+
uint64_t msg_gen_frag_id(void);
|
259
|
+
uint32_t msg_backend_idx(struct msg *msg, uint8_t *key, uint32_t keylen);
|
260
|
+
struct mbuf *msg_ensure_mbuf(struct msg *msg, size_t len);
|
261
|
+
rstatus_t msg_append(struct msg *msg, uint8_t *pos, size_t n);
|
262
|
+
rstatus_t msg_prepend(struct msg *msg, uint8_t *pos, size_t n);
|
263
|
+
rstatus_t msg_prepend_format(struct msg *msg, const char *fmt, ...);
|
232
264
|
|
233
265
|
struct msg *req_get(struct conn *conn);
|
234
266
|
void req_put(struct msg *msg);
|
@@ -276,24 +276,54 @@ proxy_accept(struct context *ctx, struct conn *p)
|
|
276
276
|
continue;
|
277
277
|
}
|
278
278
|
|
279
|
-
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
279
|
+
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ECONNABORTED) {
|
280
280
|
log_debug(LOG_VERB, "accept on p %d not ready - eagain", p->sd);
|
281
281
|
p->recv_ready = 0;
|
282
282
|
return NC_OK;
|
283
283
|
}
|
284
284
|
|
285
|
-
/*
|
286
|
-
*
|
287
|
-
*
|
285
|
+
/*
|
286
|
+
* Workaround of https://github.com/twitter/twemproxy/issues/97
|
287
|
+
*
|
288
|
+
* We should never reach here because the check for conn_ncurr_cconn()
|
289
|
+
* against ctx->max_ncconn should catch this earlier in the cycle.
|
290
|
+
* If we reach here ignore EMFILE/ENFILE, return NC_OK will enable
|
291
|
+
* the server continue to run instead of close the server socket
|
292
|
+
*
|
293
|
+
* The right solution however, is on EMFILE/ENFILE to mask out IN
|
294
|
+
* event on the proxy and mask it back in when some existing
|
295
|
+
* connections gets closed
|
288
296
|
*/
|
297
|
+
if (errno == EMFILE || errno == ENFILE) {
|
298
|
+
log_debug(LOG_CRIT, "accept on p %d with max fds %"PRIu32" "
|
299
|
+
"used connections %"PRIu32" max client connections %"PRIu32" "
|
300
|
+
"curr client connections %"PRIu32" failed: %s",
|
301
|
+
p->sd, ctx->max_nfd, conn_ncurr_conn(),
|
302
|
+
ctx->max_ncconn, conn_ncurr_cconn(), strerror(errno));
|
303
|
+
|
304
|
+
p->recv_ready = 0;
|
305
|
+
|
306
|
+
return NC_OK;
|
307
|
+
}
|
289
308
|
|
290
309
|
log_error("accept on p %d failed: %s", p->sd, strerror(errno));
|
310
|
+
|
291
311
|
return NC_ERROR;
|
292
312
|
}
|
293
313
|
|
294
314
|
break;
|
295
315
|
}
|
296
316
|
|
317
|
+
if (conn_ncurr_cconn() >= ctx->max_ncconn) {
|
318
|
+
log_debug(LOG_CRIT, "client connections %"PRIu32" exceed limit %"PRIu32,
|
319
|
+
conn_ncurr_cconn(), ctx->max_ncconn);
|
320
|
+
status = close(sd);
|
321
|
+
if (status < 0) {
|
322
|
+
log_error("close c %d failed, ignored: %s", sd, strerror(errno));
|
323
|
+
}
|
324
|
+
return NC_OK;
|
325
|
+
}
|
326
|
+
|
297
327
|
c = conn_get(p->owner, true, p->redis);
|
298
328
|
if (c == NULL) {
|
299
329
|
log_error("get conn for c %d from p %d failed: %s", sd, p->sd,
|
@@ -29,10 +29,73 @@ req_get(struct conn *conn)
|
|
29
29
|
if (msg == NULL) {
|
30
30
|
conn->err = errno;
|
31
31
|
}
|
32
|
-
|
33
32
|
return msg;
|
34
33
|
}
|
35
34
|
|
35
|
+
static void
|
36
|
+
req_log(struct msg *req)
|
37
|
+
{
|
38
|
+
struct msg *rsp; /* peer message (response) */
|
39
|
+
int64_t req_time; /* time cost for this request */
|
40
|
+
char *peer_str; /* peer client ip:port */
|
41
|
+
uint32_t req_len, rsp_len; /* request and response length */
|
42
|
+
struct string *req_type; /* request type string */
|
43
|
+
struct keypos *kpos;
|
44
|
+
|
45
|
+
if (log_loggable(LOG_NOTICE) == 0) {
|
46
|
+
return;
|
47
|
+
}
|
48
|
+
|
49
|
+
/* a fragment? */
|
50
|
+
if (req->frag_id != 0 && req->frag_owner != req) {
|
51
|
+
return;
|
52
|
+
}
|
53
|
+
|
54
|
+
/* conn close normally? */
|
55
|
+
if (req->mlen == 0) {
|
56
|
+
return;
|
57
|
+
}
|
58
|
+
/*
|
59
|
+
* there is a race scenario where a requests comes in, the log level is not LOG_NOTICE,
|
60
|
+
* and before the response arrives you modify the log level to LOG_NOTICE
|
61
|
+
* using SIGTTIN OR SIGTTOU, then req_log() wouldn't have msg->start_ts set
|
62
|
+
*/
|
63
|
+
if (req->start_ts == 0) {
|
64
|
+
return;
|
65
|
+
}
|
66
|
+
|
67
|
+
req_time = nc_usec_now() - req->start_ts;
|
68
|
+
|
69
|
+
rsp = req->peer;
|
70
|
+
req_len = req->mlen;
|
71
|
+
rsp_len = (rsp != NULL) ? rsp->mlen : 0;
|
72
|
+
|
73
|
+
if (array_n(req->keys) < 1) {
|
74
|
+
return;
|
75
|
+
}
|
76
|
+
|
77
|
+
kpos = array_get(req->keys, 0);
|
78
|
+
if (kpos->end != NULL) {
|
79
|
+
*(kpos->end) = '\0';
|
80
|
+
}
|
81
|
+
|
82
|
+
/*
|
83
|
+
* FIXME: add backend addr here
|
84
|
+
* Maybe we can store addrstr just like server_pool in conn struct
|
85
|
+
* when connections are resolved
|
86
|
+
*/
|
87
|
+
peer_str = nc_unresolve_peer_desc(req->owner->sd);
|
88
|
+
|
89
|
+
req_type = msg_type_string(req->type);
|
90
|
+
|
91
|
+
log_debug(LOG_NOTICE, "req %"PRIu64" done on c %d req_time %"PRIi64".%03"PRIi64
|
92
|
+
" msec type %.*s narg %"PRIu32" req_len %"PRIu32" rsp_len %"PRIu32
|
93
|
+
" key0 '%s' peer '%s' done %d error %d",
|
94
|
+
req->id, req->owner->sd, req_time / 1000, req_time % 1000,
|
95
|
+
req_type->len, req_type->data, req->narg, req_len, rsp_len,
|
96
|
+
kpos->start, peer_str, req->done, req->error);
|
97
|
+
}
|
98
|
+
|
36
99
|
void
|
37
100
|
req_put(struct msg *msg)
|
38
101
|
{
|
@@ -40,6 +103,8 @@ req_put(struct msg *msg)
|
|
40
103
|
|
41
104
|
ASSERT(msg->request);
|
42
105
|
|
106
|
+
req_log(msg);
|
107
|
+
|
43
108
|
pmsg = msg->peer;
|
44
109
|
if (pmsg != NULL) {
|
45
110
|
ASSERT(!pmsg->request && pmsg->peer == msg);
|
@@ -84,6 +149,10 @@ req_done(struct conn *conn, struct msg *msg)
|
|
84
149
|
return true;
|
85
150
|
}
|
86
151
|
|
152
|
+
if (msg->nfrag_done < msg->nfrag) {
|
153
|
+
return false;
|
154
|
+
}
|
155
|
+
|
87
156
|
/* check all fragments of the given request vector are done */
|
88
157
|
|
89
158
|
for (pmsg = msg, cmsg = TAILQ_PREV(msg, msg_tqh, c_tqe);
|
@@ -104,10 +173,6 @@ req_done(struct conn *conn, struct msg *msg)
|
|
104
173
|
}
|
105
174
|
}
|
106
175
|
|
107
|
-
if (!pmsg->last_fragment) {
|
108
|
-
return false;
|
109
|
-
}
|
110
|
-
|
111
176
|
/*
|
112
177
|
* At this point, all the fragments including the last fragment have
|
113
178
|
* been received.
|
@@ -117,7 +182,7 @@ req_done(struct conn *conn, struct msg *msg)
|
|
117
182
|
*/
|
118
183
|
|
119
184
|
msg->fdone = 1;
|
120
|
-
nfragment =
|
185
|
+
nfragment = 0;
|
121
186
|
|
122
187
|
for (pmsg = msg, cmsg = TAILQ_PREV(msg, msg_tqh, c_tqe);
|
123
188
|
cmsg != NULL && cmsg->frag_id == id;
|
@@ -143,6 +208,7 @@ req_done(struct conn *conn, struct msg *msg)
|
|
143
208
|
return true;
|
144
209
|
}
|
145
210
|
|
211
|
+
|
146
212
|
/*
|
147
213
|
* Return true if request is in error, false otherwise
|
148
214
|
*
|
@@ -360,6 +426,26 @@ req_recv_next(struct context *ctx, struct conn *conn, bool alloc)
|
|
360
426
|
return msg;
|
361
427
|
}
|
362
428
|
|
429
|
+
static rstatus_t
|
430
|
+
req_make_reply(struct context *ctx, struct conn *conn, struct msg *req)
|
431
|
+
{
|
432
|
+
struct msg *msg;
|
433
|
+
|
434
|
+
msg = msg_get(conn, true, conn->redis); /* replay */
|
435
|
+
if (msg == NULL) {
|
436
|
+
conn->err = errno;
|
437
|
+
return NC_ENOMEM;
|
438
|
+
}
|
439
|
+
|
440
|
+
req->peer = msg;
|
441
|
+
msg->peer = req;
|
442
|
+
msg->request = 0;
|
443
|
+
|
444
|
+
req->done = 1;
|
445
|
+
conn->enqueue_outq(ctx, conn, req);
|
446
|
+
return NC_OK;
|
447
|
+
}
|
448
|
+
|
363
449
|
static bool
|
364
450
|
req_filter(struct context *ctx, struct conn *conn, struct msg *msg)
|
365
451
|
{
|
@@ -436,6 +522,7 @@ req_forward(struct context *ctx, struct conn *c_conn, struct msg *msg)
|
|
436
522
|
struct server_pool *pool;
|
437
523
|
uint8_t *key;
|
438
524
|
uint32_t keylen;
|
525
|
+
struct keypos *kpos;
|
439
526
|
|
440
527
|
ASSERT(c_conn->client && !c_conn->proxy);
|
441
528
|
|
@@ -445,32 +532,11 @@ req_forward(struct context *ctx, struct conn *c_conn, struct msg *msg)
|
|
445
532
|
}
|
446
533
|
|
447
534
|
pool = c_conn->owner;
|
448
|
-
key = NULL;
|
449
|
-
keylen = 0;
|
450
535
|
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
*/
|
456
|
-
if (!string_empty(&pool->hash_tag)) {
|
457
|
-
struct string *tag = &pool->hash_tag;
|
458
|
-
uint8_t *tag_start, *tag_end;
|
459
|
-
|
460
|
-
tag_start = nc_strchr(msg->key_start, msg->key_end, tag->data[0]);
|
461
|
-
if (tag_start != NULL) {
|
462
|
-
tag_end = nc_strchr(tag_start + 1, msg->key_end, tag->data[1]);
|
463
|
-
if (tag_end != NULL) {
|
464
|
-
key = tag_start + 1;
|
465
|
-
keylen = (uint32_t)(tag_end - key);
|
466
|
-
}
|
467
|
-
}
|
468
|
-
}
|
469
|
-
|
470
|
-
if (keylen == 0) {
|
471
|
-
key = msg->key_start;
|
472
|
-
keylen = (uint32_t)(msg->key_end - msg->key_start);
|
473
|
-
}
|
536
|
+
ASSERT(array_n(msg->keys) > 0);
|
537
|
+
kpos = array_get(msg->keys, 0);
|
538
|
+
key = kpos->start;
|
539
|
+
keylen = (uint32_t)(kpos->end - kpos->start);
|
474
540
|
|
475
541
|
s_conn = server_pool_conn(ctx, c_conn->owner, key, keylen);
|
476
542
|
if (s_conn == NULL) {
|
@@ -501,6 +567,12 @@ void
|
|
501
567
|
req_recv_done(struct context *ctx, struct conn *conn, struct msg *msg,
|
502
568
|
struct msg *nmsg)
|
503
569
|
{
|
570
|
+
rstatus_t status;
|
571
|
+
struct server_pool *pool;
|
572
|
+
struct msg_tqh frag_msgq;
|
573
|
+
struct msg *sub_msg;
|
574
|
+
struct msg *tmsg; /* tmp next message */
|
575
|
+
|
504
576
|
ASSERT(conn->client && !conn->proxy);
|
505
577
|
ASSERT(msg->request);
|
506
578
|
ASSERT(msg->owner == conn);
|
@@ -514,7 +586,61 @@ req_recv_done(struct context *ctx, struct conn *conn, struct msg *msg,
|
|
514
586
|
return;
|
515
587
|
}
|
516
588
|
|
517
|
-
|
589
|
+
if (msg->noforward) {
|
590
|
+
status = req_make_reply(ctx, conn, msg);
|
591
|
+
if (status != NC_OK) {
|
592
|
+
conn->err = errno;
|
593
|
+
return;
|
594
|
+
}
|
595
|
+
|
596
|
+
status = msg->reply(msg);
|
597
|
+
if (status != NC_OK) {
|
598
|
+
conn->err = errno;
|
599
|
+
return;
|
600
|
+
}
|
601
|
+
|
602
|
+
status = event_add_out(ctx->evb, conn);
|
603
|
+
if (status != NC_OK) {
|
604
|
+
conn->err = errno;
|
605
|
+
}
|
606
|
+
|
607
|
+
return;
|
608
|
+
}
|
609
|
+
|
610
|
+
/* do fragment */
|
611
|
+
pool = conn->owner;
|
612
|
+
TAILQ_INIT(&frag_msgq);
|
613
|
+
status = msg->fragment(msg, pool->ncontinuum, &frag_msgq);
|
614
|
+
if (status != NC_OK) {
|
615
|
+
if (!msg->noreply) {
|
616
|
+
conn->enqueue_outq(ctx, conn, msg);
|
617
|
+
}
|
618
|
+
req_forward_error(ctx, conn, msg);
|
619
|
+
}
|
620
|
+
|
621
|
+
/* if no fragment happened */
|
622
|
+
if (TAILQ_EMPTY(&frag_msgq)) {
|
623
|
+
req_forward(ctx, conn, msg);
|
624
|
+
return;
|
625
|
+
}
|
626
|
+
|
627
|
+
status = req_make_reply(ctx, conn, msg);
|
628
|
+
if (status != NC_OK) {
|
629
|
+
if (!msg->noreply) {
|
630
|
+
conn->enqueue_outq(ctx, conn, msg);
|
631
|
+
}
|
632
|
+
req_forward_error(ctx, conn, msg);
|
633
|
+
}
|
634
|
+
|
635
|
+
for (sub_msg = TAILQ_FIRST(&frag_msgq); sub_msg != NULL; sub_msg = tmsg) {
|
636
|
+
tmsg = TAILQ_NEXT(sub_msg, m_tqe);
|
637
|
+
|
638
|
+
TAILQ_REMOVE(&frag_msgq, sub_msg, m_tqe);
|
639
|
+
req_forward(ctx, conn, sub_msg);
|
640
|
+
}
|
641
|
+
|
642
|
+
ASSERT(TAILQ_EMPTY(&frag_msgq));
|
643
|
+
return;
|
518
644
|
}
|
519
645
|
|
520
646
|
struct msg *
|