libcouchbase 0.3.3 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/libcouchbase/CMakeLists.txt +6 -8
- data/ext/libcouchbase/README.markdown +2 -2
- data/ext/libcouchbase/RELEASE_NOTES.markdown +229 -2
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +18 -0
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +3 -2
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +4 -0
- data/ext/libcouchbase/cmake/defs.mk.in +0 -2
- data/ext/libcouchbase/cmake/source_files.cmake +21 -5
- data/ext/libcouchbase/contrib/cJSON/cJSON.c +1 -1
- data/ext/libcouchbase/contrib/cbsasl/src/client.c +2 -0
- data/ext/libcouchbase/example/users/README +48 -0
- data/ext/libcouchbase/example/users/users.c +147 -0
- data/ext/libcouchbase/include/libcouchbase/auth.h +175 -31
- data/ext/libcouchbase/include/libcouchbase/cntl.h +82 -1
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +45 -3
- data/ext/libcouchbase/include/libcouchbase/error.h +19 -1
- data/ext/libcouchbase/include/libcouchbase/iops.h +3 -0
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +31 -1
- data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +4 -1
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +36 -2
- data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
- data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
- data/ext/libcouchbase/include/memcached/protocol_binary.h +24 -1146
- data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
- data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
- data/ext/libcouchbase/src/README.md +0 -2
- data/ext/libcouchbase/src/auth-priv.h +23 -4
- data/ext/libcouchbase/src/auth.cc +51 -43
- data/ext/libcouchbase/src/bootstrap.cc +244 -0
- data/ext/libcouchbase/src/bootstrap.h +58 -38
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +120 -158
- data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +526 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
- data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +410 -386
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +393 -0
- data/ext/libcouchbase/src/cbft.cc +22 -27
- data/ext/libcouchbase/src/cntl.cc +56 -22
- data/ext/libcouchbase/src/connspec.cc +47 -6
- data/ext/libcouchbase/src/connspec.h +27 -0
- data/ext/libcouchbase/src/dns-srv.cc +147 -0
- data/ext/libcouchbase/src/dump.cc +3 -3
- data/ext/libcouchbase/src/errmap.cc +173 -0
- data/ext/libcouchbase/src/errmap.h +198 -0
- data/ext/libcouchbase/src/getconfig.cc +7 -33
- data/ext/libcouchbase/src/handler.cc +118 -7
- data/ext/libcouchbase/src/hostlist.cc +0 -36
- data/ext/libcouchbase/src/hostlist.h +44 -62
- data/ext/libcouchbase/src/http/http-priv.h +125 -112
- data/ext/libcouchbase/src/http/http.cc +27 -35
- data/ext/libcouchbase/src/http/http.h +1 -34
- data/ext/libcouchbase/src/http/http_io.cc +28 -36
- data/ext/libcouchbase/src/instance.cc +131 -34
- data/ext/libcouchbase/src/internal.h +58 -26
- data/ext/libcouchbase/src/jsparse/parser.cc +136 -210
- data/ext/libcouchbase/src/jsparse/parser.h +84 -98
- data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
- data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
- data/ext/libcouchbase/src/lcbio/connect.cc +569 -0
- data/ext/libcouchbase/src/lcbio/connect.h +16 -7
- data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
- data/ext/libcouchbase/src/lcbio/iotable.h +101 -16
- data/ext/libcouchbase/src/lcbio/{ioutils.c → ioutils.cc} +30 -51
- data/ext/libcouchbase/src/lcbio/ioutils.h +29 -90
- data/ext/libcouchbase/src/lcbio/manager.cc +543 -0
- data/ext/libcouchbase/src/lcbio/manager.h +133 -96
- data/ext/libcouchbase/src/lcbio/protoctx.c +2 -2
- data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
- data/ext/libcouchbase/src/mc/mcreq.c +11 -2
- data/ext/libcouchbase/src/mc/mcreq.h +9 -2
- data/ext/libcouchbase/src/mcserver/mcserver.cc +175 -43
- data/ext/libcouchbase/src/mcserver/mcserver.h +9 -13
- data/ext/libcouchbase/src/mcserver/negotiate.cc +181 -62
- data/ext/libcouchbase/src/mcserver/negotiate.h +1 -3
- data/ext/libcouchbase/src/mctx-helper.h +51 -0
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
- data/ext/libcouchbase/src/n1ql/n1ql.cc +74 -42
- data/ext/libcouchbase/src/netbuf/netbuf.c +4 -4
- data/ext/libcouchbase/src/newconfig.cc +6 -6
- data/ext/libcouchbase/src/nodeinfo.cc +2 -2
- data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
- data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
- data/ext/libcouchbase/src/operations/durability.cc +6 -26
- data/ext/libcouchbase/src/operations/durability_internal.h +6 -3
- data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
- data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +68 -93
- data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
- data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
- data/ext/libcouchbase/src/operations/stats.cc +3 -8
- data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
- data/ext/libcouchbase/src/operations/subdoc.cc +129 -42
- data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
- data/ext/libcouchbase/src/packetutils.h +30 -2
- data/ext/libcouchbase/src/probes.d +1 -1
- data/ext/libcouchbase/src/rdb/rope.c +1 -1
- data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +2 -3
- data/ext/libcouchbase/src/retryq.cc +52 -14
- data/ext/libcouchbase/src/retryq.h +3 -3
- data/ext/libcouchbase/src/settings.c +5 -0
- data/ext/libcouchbase/src/settings.h +11 -0
- data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
- data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
- data/ext/libcouchbase/src/strcodecs/strcodecs.h +1 -1
- data/ext/libcouchbase/src/trace.h +4 -4
- data/ext/libcouchbase/src/vbucket/vbucket.c +6 -10
- data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
- data/ext/libcouchbase/src/views/docreq.h +24 -30
- data/ext/libcouchbase/src/views/viewreq.cc +318 -0
- data/ext/libcouchbase/src/views/viewreq.h +43 -13
- data/ext/libcouchbase/tests/basic/t_connstr.cc +88 -50
- data/ext/libcouchbase/tests/basic/t_creds.cc +47 -5
- data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
- data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -82
- data/ext/libcouchbase/tests/basic/t_misc.cc +1 -1
- data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +0 -1
- data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
- data/ext/libcouchbase/tests/ioserver/connection.cc +1 -1
- data/ext/libcouchbase/tests/ioserver/ioserver.cc +19 -6
- data/ext/libcouchbase/tests/iotests/mock-environment.cc +28 -2
- data/ext/libcouchbase/tests/iotests/mock-environment.h +51 -1
- data/ext/libcouchbase/tests/iotests/t_behavior.cc +1 -7
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +97 -115
- data/ext/libcouchbase/tests/iotests/t_durability.cc +0 -1
- data/ext/libcouchbase/tests/iotests/t_eerrs.cc +119 -0
- data/ext/libcouchbase/tests/iotests/t_errmap.cc +178 -0
- data/ext/libcouchbase/tests/iotests/t_misc.cc +3 -3
- data/ext/libcouchbase/tests/iotests/t_netfail.cc +1 -1
- data/ext/libcouchbase/tests/iotests/t_obseqno.cc +0 -1
- data/ext/libcouchbase/tests/iotests/t_subdoc.cc +18 -11
- data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
- data/ext/libcouchbase/tests/socktests/socktest.cc +7 -10
- data/ext/libcouchbase/tests/socktests/socktest.h +2 -3
- data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
- data/ext/libcouchbase/tests/socktests/t_manager.cc +5 -6
- data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
- data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
- data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
- data/ext/libcouchbase/tests/vbucket/t_config.cc +35 -5
- data/ext/libcouchbase/tools/CMakeLists.txt +2 -2
- data/ext/libcouchbase/tools/cbc-handlers.h +128 -0
- data/ext/libcouchbase/tools/cbc-n1qlback.cc +64 -10
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +2 -2
- data/ext/libcouchbase/tools/cbc.cc +143 -10
- data/ext/libcouchbase/tools/docgen/loc.h +1 -1
- data/lib/libcouchbase/connection.rb +4 -3
- data/lib/libcouchbase/version.rb +1 -1
- metadata +37 -28
- data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
- data/ext/libcouchbase/src/bootstrap.c +0 -269
- data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
- data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
- data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
- data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
- data/ext/libcouchbase/src/lcbio/connect.c +0 -557
- data/ext/libcouchbase/src/lcbio/manager.c +0 -584
- data/ext/libcouchbase/src/packetutils.c +0 -37
- data/ext/libcouchbase/src/simplestring.c +0 -211
- data/ext/libcouchbase/src/simplestring.h +0 -228
- data/ext/libcouchbase/src/ssobuf.h +0 -82
- data/ext/libcouchbase/src/views/viewreq.c +0 -358
- data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
|
@@ -1,584 +0,0 @@
|
|
|
1
|
-
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
-
/*
|
|
3
|
-
* Copyright 2014 Couchbase, 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 "manager.h"
|
|
19
|
-
#include "hostlist.h"
|
|
20
|
-
#include "iotable.h"
|
|
21
|
-
#include "timer-ng.h"
|
|
22
|
-
#include "internal.h"
|
|
23
|
-
|
|
24
|
-
#define LOGARGS(mgr, lvl) mgr->settings, "lcbio_mgr", LCB_LOG_##lvl, __FILE__, __LINE__
|
|
25
|
-
|
|
26
|
-
typedef enum {
|
|
27
|
-
CS_PENDING,
|
|
28
|
-
CS_IDLE,
|
|
29
|
-
CS_LEASED
|
|
30
|
-
} cinfo_state;
|
|
31
|
-
|
|
32
|
-
typedef enum {
|
|
33
|
-
RS_PENDING,
|
|
34
|
-
RS_ASSIGNED
|
|
35
|
-
} request_state;
|
|
36
|
-
|
|
37
|
-
typedef char mgr_KEY[NI_MAXSERV + NI_MAXHOST + 2];
|
|
38
|
-
|
|
39
|
-
typedef struct lcbio_MGRHOST {
|
|
40
|
-
lcb_clist_t ll_idle; /* idle connections */
|
|
41
|
-
lcb_clist_t ll_pending; /* pending cinfo */
|
|
42
|
-
lcb_clist_t requests; /* pending requests */
|
|
43
|
-
mgr_KEY key; /* host:port */
|
|
44
|
-
struct lcbio_MGR *parent;
|
|
45
|
-
lcbio_pASYNC async;
|
|
46
|
-
unsigned n_total; /* number of total connections */
|
|
47
|
-
unsigned refcount;
|
|
48
|
-
} mgr_HOST;
|
|
49
|
-
|
|
50
|
-
typedef struct mgr_CINFO_st {
|
|
51
|
-
lcbio_PROTOCTX base;
|
|
52
|
-
lcb_list_t llnode;
|
|
53
|
-
mgr_HOST *parent;
|
|
54
|
-
lcbio_SOCKET *sock;
|
|
55
|
-
struct lcbio_CONNSTART *cs;
|
|
56
|
-
lcbio_pTIMER idle_timer;
|
|
57
|
-
int state;
|
|
58
|
-
} mgr_CINFO;
|
|
59
|
-
|
|
60
|
-
typedef struct lcbio_MGRREQ {
|
|
61
|
-
lcb_list_t llnode;
|
|
62
|
-
lcbio_CONNDONE_cb callback;
|
|
63
|
-
void *arg;
|
|
64
|
-
mgr_HOST *host;
|
|
65
|
-
lcbio_pTIMER timer;
|
|
66
|
-
int state;
|
|
67
|
-
lcbio_SOCKET *sock;
|
|
68
|
-
lcb_error_t err;
|
|
69
|
-
} mgr_REQ;
|
|
70
|
-
|
|
71
|
-
#define HE_NPEND(he) LCB_CLIST_SIZE(&(he)->ll_pending)
|
|
72
|
-
#define HE_NIDLE(he) LCB_CLIST_SIZE(&(he)->ll_idle)
|
|
73
|
-
#define HE_NREQS(he) LCB_CLIST_SIZE(&(he)->requests)
|
|
74
|
-
#define HE_NLEASED(he) ((he)->n_total - (HE_NIDLE(he) + HE_NPEND(he)))
|
|
75
|
-
|
|
76
|
-
static void on_idle_timeout(void *cookie);
|
|
77
|
-
static void he_available_notify(void *cookie);
|
|
78
|
-
static void he_dump(mgr_HOST *he, FILE *out);
|
|
79
|
-
static void he_unref(mgr_HOST *he);
|
|
80
|
-
static void mgr_unref(lcbio_MGR *mgr);
|
|
81
|
-
|
|
82
|
-
#define he_ref(he) (he)->refcount++
|
|
83
|
-
#define mgr_ref(mgr) (mgr)->refcount++
|
|
84
|
-
|
|
85
|
-
static const char *get_hehost(mgr_HOST *h) {
|
|
86
|
-
if (!h) { return "NOHOST:NOPORT"; }
|
|
87
|
-
return h->key;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/** Format string arguments for %p%s:%s */
|
|
91
|
-
#define HE_LOGID(h) get_hehost(h), (void*)h
|
|
92
|
-
#define HE_LOGFMT "<%s> (HE=%p) "
|
|
93
|
-
|
|
94
|
-
static mgr_CINFO *
|
|
95
|
-
cinfo_from_sock(lcbio_SOCKET *sock)
|
|
96
|
-
{
|
|
97
|
-
lcbio_PROTOCTX *ctx = lcbio_protoctx_get(sock, LCBIO_PROTOCTX_POOL);
|
|
98
|
-
return (mgr_CINFO *)ctx;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
static void
|
|
102
|
-
destroy_cinfo(mgr_CINFO *info)
|
|
103
|
-
{
|
|
104
|
-
info->parent->n_total--;
|
|
105
|
-
if (info->state == CS_IDLE) {
|
|
106
|
-
lcb_clist_delete(&info->parent->ll_idle, &info->llnode);
|
|
107
|
-
|
|
108
|
-
} else if (info->state == CS_PENDING && info->cs) {
|
|
109
|
-
lcbio_connect_cancel(info->cs);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (info->sock) {
|
|
113
|
-
lcbio_SOCKET *s = info->sock;
|
|
114
|
-
info->sock = NULL;
|
|
115
|
-
lcbio_protoctx_delptr(s, &info->base, 0);
|
|
116
|
-
lcbio_unref(s);
|
|
117
|
-
}
|
|
118
|
-
lcbio_timer_destroy(info->idle_timer);
|
|
119
|
-
he_unref(info->parent);
|
|
120
|
-
free(info);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
static void
|
|
124
|
-
cinfo_protoctx_dtor(lcbio_PROTOCTX *ctx)
|
|
125
|
-
{
|
|
126
|
-
mgr_CINFO *info = (void *)ctx;
|
|
127
|
-
info->sock = NULL;
|
|
128
|
-
destroy_cinfo(info);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
lcbio_MGR *
|
|
132
|
-
lcbio_mgr_create(lcb_settings *settings, lcbio_TABLE *io)
|
|
133
|
-
{
|
|
134
|
-
lcbio_MGR *pool = calloc(1, sizeof(*pool));
|
|
135
|
-
if (!pool) {
|
|
136
|
-
return NULL;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if ((pool->ht = lcb_hashtable_nc_new(32)) == NULL) {
|
|
140
|
-
free(pool);
|
|
141
|
-
return NULL;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
pool->settings = settings;
|
|
145
|
-
pool->io = io;
|
|
146
|
-
mgr_ref(pool);
|
|
147
|
-
return pool;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
static void
|
|
151
|
-
iterfunc(const void *k, lcb_size_t nk, const void *v, lcb_size_t nv, void *arg)
|
|
152
|
-
{
|
|
153
|
-
lcb_clist_t *he_list = (lcb_clist_t *)arg;
|
|
154
|
-
mgr_HOST *he = (mgr_HOST *)v;
|
|
155
|
-
lcb_list_t *cur, *next;
|
|
156
|
-
|
|
157
|
-
LCB_LIST_SAFE_FOR(cur, next, (lcb_list_t *)&he->ll_idle) {
|
|
158
|
-
mgr_CINFO *info = LCB_LIST_ITEM(cur, mgr_CINFO, llnode);
|
|
159
|
-
destroy_cinfo(info);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
LCB_LIST_SAFE_FOR(cur, next, (lcb_list_t *)&he->ll_pending) {
|
|
163
|
-
mgr_CINFO *info = LCB_LIST_ITEM(cur, mgr_CINFO, llnode);
|
|
164
|
-
destroy_cinfo(info);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
memset(&he->ll_idle, 0, sizeof(he->ll_idle));
|
|
168
|
-
lcb_clist_append(he_list, (lcb_list_t *)&he->ll_idle);
|
|
169
|
-
|
|
170
|
-
(void)k; (void)nk; (void)nv;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
static void
|
|
174
|
-
he_unref(mgr_HOST *host)
|
|
175
|
-
{
|
|
176
|
-
if (--host->refcount) {
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
mgr_unref(host->parent);
|
|
181
|
-
free(host);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
static void
|
|
185
|
-
mgr_unref(lcbio_MGR *mgr)
|
|
186
|
-
{
|
|
187
|
-
if (--mgr->refcount) {
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
genhash_free(mgr->ht);
|
|
191
|
-
free(mgr);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
void
|
|
195
|
-
lcbio_mgr_destroy(lcbio_MGR *mgr)
|
|
196
|
-
{
|
|
197
|
-
lcb_clist_t hes;
|
|
198
|
-
lcb_list_t *cur, *next;
|
|
199
|
-
lcb_clist_init(&hes);
|
|
200
|
-
|
|
201
|
-
genhash_iter(mgr->ht, iterfunc, &hes);
|
|
202
|
-
|
|
203
|
-
LCB_LIST_SAFE_FOR(cur, next, (lcb_list_t*)&hes) {
|
|
204
|
-
mgr_HOST *he = LCB_LIST_ITEM(cur, mgr_HOST, ll_idle);
|
|
205
|
-
genhash_delete(mgr->ht, he->key, strlen(he->key));
|
|
206
|
-
lcb_clist_delete(&hes, (lcb_list_t *)&he->ll_idle);
|
|
207
|
-
lcbio_timer_destroy(he->async);
|
|
208
|
-
he->async = NULL;
|
|
209
|
-
he_unref(he);
|
|
210
|
-
}
|
|
211
|
-
mgr_unref(mgr);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
static void
|
|
215
|
-
invoke_request(mgr_REQ *req)
|
|
216
|
-
{
|
|
217
|
-
if (req->sock) {
|
|
218
|
-
mgr_CINFO *info = cinfo_from_sock(req->sock);
|
|
219
|
-
lcb_assert(info->state == CS_IDLE);
|
|
220
|
-
info->state = CS_LEASED;
|
|
221
|
-
req->state = RS_ASSIGNED;
|
|
222
|
-
lcbio_timer_disarm(info->idle_timer);
|
|
223
|
-
lcb_log(LOGARGS(info->parent->parent, DEBUG), HE_LOGFMT "Assigning R=%p SOCKET=%p",HE_LOGID(info->parent), (void*)req, (void*)req->sock);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
if (req->timer) {
|
|
227
|
-
lcbio_timer_destroy(req->timer);
|
|
228
|
-
req->timer = NULL;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
req->callback(req->sock, req->arg, req->err, 0);
|
|
232
|
-
if (req->sock) {
|
|
233
|
-
lcbio_unref(req->sock);
|
|
234
|
-
}
|
|
235
|
-
free(req);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Called to notify that a connection has become available.
|
|
240
|
-
*/
|
|
241
|
-
static void
|
|
242
|
-
connection_available(mgr_HOST *he)
|
|
243
|
-
{
|
|
244
|
-
while (LCB_CLIST_SIZE(&he->requests) && LCB_CLIST_SIZE(&he->ll_idle)) {
|
|
245
|
-
mgr_REQ *req;
|
|
246
|
-
mgr_CINFO *info;
|
|
247
|
-
lcb_list_t *reqitem, *connitem;
|
|
248
|
-
|
|
249
|
-
reqitem = lcb_clist_shift(&he->requests);
|
|
250
|
-
connitem = lcb_clist_pop(&he->ll_idle);
|
|
251
|
-
|
|
252
|
-
req = LCB_LIST_ITEM(reqitem, mgr_REQ, llnode);
|
|
253
|
-
info = LCB_LIST_ITEM(connitem, mgr_CINFO, llnode);
|
|
254
|
-
req->sock = info->sock;
|
|
255
|
-
req->err = LCB_SUCCESS;
|
|
256
|
-
invoke_request(req);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Connection callback invoked from lcbio_connect() when a result is received
|
|
262
|
-
*/
|
|
263
|
-
static void
|
|
264
|
-
on_connected(lcbio_SOCKET *sock, void *arg, lcb_error_t err, lcbio_OSERR oserr)
|
|
265
|
-
{
|
|
266
|
-
mgr_CINFO *info = arg;
|
|
267
|
-
mgr_HOST *he = info->parent;
|
|
268
|
-
lcb_assert(info->state == CS_PENDING);
|
|
269
|
-
info->cs = NULL;
|
|
270
|
-
|
|
271
|
-
lcb_log(LOGARGS(he->parent, DEBUG), HE_LOGFMT "Received result for I=%p,C=%p; E=0x%x", HE_LOGID(he), (void*)info, (void*)sock, err);
|
|
272
|
-
lcb_clist_delete(&he->ll_pending, &info->llnode);
|
|
273
|
-
|
|
274
|
-
if (err != LCB_SUCCESS) {
|
|
275
|
-
/** If the connection failed, fail out all remaining requests */
|
|
276
|
-
lcb_list_t *cur, *next;
|
|
277
|
-
LCB_LIST_SAFE_FOR(cur, next, (lcb_list_t *)&he->requests) {
|
|
278
|
-
mgr_REQ *req = LCB_LIST_ITEM(cur, mgr_REQ, llnode);
|
|
279
|
-
lcb_clist_delete(&he->requests, &req->llnode);
|
|
280
|
-
req->sock = NULL;
|
|
281
|
-
req->err = err;
|
|
282
|
-
invoke_request(req);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
destroy_cinfo(info);
|
|
286
|
-
|
|
287
|
-
} else {
|
|
288
|
-
info->state = CS_IDLE;
|
|
289
|
-
info->sock = sock;
|
|
290
|
-
lcbio_ref(info->sock);
|
|
291
|
-
lcbio_protoctx_add(sock, &info->base);
|
|
292
|
-
|
|
293
|
-
lcb_clist_append(&he->ll_idle, &info->llnode);
|
|
294
|
-
lcbio_timer_rearm(info->idle_timer, he->parent->tmoidle);
|
|
295
|
-
connection_available(info->parent);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
(void)oserr;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
static void
|
|
302
|
-
start_new_connection(mgr_HOST *he, uint32_t tmo)
|
|
303
|
-
{
|
|
304
|
-
lcb_host_t tmphost;
|
|
305
|
-
lcb_error_t err;
|
|
306
|
-
|
|
307
|
-
mgr_CINFO *info = calloc(1, sizeof(*info));
|
|
308
|
-
info->state = CS_PENDING;
|
|
309
|
-
info->parent = he;
|
|
310
|
-
|
|
311
|
-
info->base.id = LCBIO_PROTOCTX_POOL;
|
|
312
|
-
info->base.dtor = cinfo_protoctx_dtor;
|
|
313
|
-
info->idle_timer = lcbio_timer_new(he->parent->io, info, on_idle_timeout);
|
|
314
|
-
|
|
315
|
-
err = lcb_host_parsez(&tmphost, he->key, 80);
|
|
316
|
-
if (err != LCB_SUCCESS) {
|
|
317
|
-
lcb_log(LOGARGS(he->parent, ERROR), HE_LOGFMT "Could not parse host! Will supply dummy host", HE_LOGID(he));
|
|
318
|
-
strcpy(tmphost.host, "BADHOST");
|
|
319
|
-
strcpy(tmphost.port, "BADPORT");
|
|
320
|
-
}
|
|
321
|
-
lcb_log(LOGARGS(he->parent, DEBUG), HE_LOGFMT "Starting connection on I=%p", HE_LOGID(he), (void*)info);
|
|
322
|
-
|
|
323
|
-
info->cs = lcbio_connect(he->parent->io, he->parent->settings, &tmphost,
|
|
324
|
-
tmo, on_connected, info);
|
|
325
|
-
|
|
326
|
-
lcb_clist_append(&he->ll_pending, &info->llnode);
|
|
327
|
-
he->n_total++;
|
|
328
|
-
he_ref(he);
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
static void
|
|
332
|
-
on_request_timeout(void *cookie)
|
|
333
|
-
{
|
|
334
|
-
mgr_REQ *req = cookie;
|
|
335
|
-
lcb_clist_delete(&req->host->requests, &req->llnode);
|
|
336
|
-
req->err = LCB_ETIMEDOUT;
|
|
337
|
-
invoke_request(req);
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
static void
|
|
341
|
-
async_invoke_request(void *cookie)
|
|
342
|
-
{
|
|
343
|
-
|
|
344
|
-
mgr_REQ *req = cookie;
|
|
345
|
-
mgr_CINFO *cinfo = cinfo_from_sock(req->sock);
|
|
346
|
-
cinfo->state = CS_IDLE;
|
|
347
|
-
invoke_request(req);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
mgr_REQ *
|
|
351
|
-
lcbio_mgr_get(lcbio_MGR *pool, lcb_host_t *dest, uint32_t timeout,
|
|
352
|
-
lcbio_CONNDONE_cb handler, void *arg)
|
|
353
|
-
{
|
|
354
|
-
mgr_HOST *he;
|
|
355
|
-
lcb_list_t *cur;
|
|
356
|
-
mgr_REQ *req = calloc(1, sizeof(*req));
|
|
357
|
-
mgr_KEY key = { 0 };
|
|
358
|
-
|
|
359
|
-
sprintf(key, "%s:%s", dest->host, dest->port);
|
|
360
|
-
|
|
361
|
-
req->callback = handler;
|
|
362
|
-
req->arg = arg;
|
|
363
|
-
|
|
364
|
-
he = genhash_find(pool->ht, key, strlen(key));
|
|
365
|
-
if (!he) {
|
|
366
|
-
he = calloc(1, sizeof(*he));
|
|
367
|
-
he->parent = pool;
|
|
368
|
-
he->async = lcbio_timer_new(pool->io, he, he_available_notify);
|
|
369
|
-
strcpy(he->key, key);
|
|
370
|
-
|
|
371
|
-
lcb_clist_init(&he->ll_idle);
|
|
372
|
-
lcb_clist_init(&he->ll_pending);
|
|
373
|
-
lcb_clist_init(&he->requests);
|
|
374
|
-
|
|
375
|
-
/** Not copied */
|
|
376
|
-
genhash_store(pool->ht, he->key, strlen(he->key), he, 0);
|
|
377
|
-
he_ref(he);
|
|
378
|
-
mgr_ref(pool);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
req->host = he;
|
|
382
|
-
|
|
383
|
-
GT_POPAGAIN:
|
|
384
|
-
|
|
385
|
-
cur = lcb_clist_pop(&he->ll_idle);
|
|
386
|
-
if (cur) {
|
|
387
|
-
int clstatus;
|
|
388
|
-
mgr_CINFO *info = LCB_LIST_ITEM(cur, mgr_CINFO, llnode);
|
|
389
|
-
|
|
390
|
-
clstatus = lcbio_is_netclosed(info->sock, LCB_IO_SOCKCHECK_PEND_IS_ERROR);
|
|
391
|
-
|
|
392
|
-
if (clstatus == LCB_IO_SOCKCHECK_STATUS_CLOSED) {
|
|
393
|
-
lcb_log(LOGARGS(pool, WARN), HE_LOGFMT "Pooled socket is dead. Continuing to next one", HE_LOGID(he));
|
|
394
|
-
|
|
395
|
-
/* Set to CS_LEASED, since it's not inside any of our lists */
|
|
396
|
-
info->state = CS_LEASED;
|
|
397
|
-
destroy_cinfo(info);
|
|
398
|
-
goto GT_POPAGAIN;
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
lcbio_timer_disarm(info->idle_timer);
|
|
402
|
-
req->sock = info->sock;
|
|
403
|
-
req->state = RS_ASSIGNED;
|
|
404
|
-
req->timer = lcbio_timer_new(pool->io, req, async_invoke_request);
|
|
405
|
-
info->state = CS_LEASED;
|
|
406
|
-
lcbio_async_signal(req->timer);
|
|
407
|
-
lcb_log(LOGARGS(pool, INFO), HE_LOGFMT "Found ready connection in pool. Reusing socket and not creating new connection", HE_LOGID(he));
|
|
408
|
-
|
|
409
|
-
} else {
|
|
410
|
-
req->state = RS_PENDING;
|
|
411
|
-
req->timer = lcbio_timer_new(pool->io, req, on_request_timeout);
|
|
412
|
-
lcbio_timer_rearm(req->timer, timeout);
|
|
413
|
-
|
|
414
|
-
lcb_clist_append(&he->requests, &req->llnode);
|
|
415
|
-
if (HE_NPEND(he) < HE_NREQS(he)) {
|
|
416
|
-
lcb_log(LOGARGS(pool, DEBUG), HE_LOGFMT "Creating new connection because none are available in the pool", HE_LOGID(he));
|
|
417
|
-
start_new_connection(he, timeout);
|
|
418
|
-
|
|
419
|
-
} else {
|
|
420
|
-
lcb_log(LOGARGS(pool, DEBUG), HE_LOGFMT "Not creating a new connection. There are still pending ones", HE_LOGID(he));
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
return req;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
/**
|
|
428
|
-
* Invoked when a new socket is available for allocation within the
|
|
429
|
-
* request queue.
|
|
430
|
-
*/
|
|
431
|
-
static void
|
|
432
|
-
he_available_notify(void *cookie)
|
|
433
|
-
{
|
|
434
|
-
connection_available((mgr_HOST *)cookie);
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
void
|
|
438
|
-
lcbio_mgr_cancel(mgr_REQ *req)
|
|
439
|
-
{
|
|
440
|
-
mgr_HOST *he = req->host;
|
|
441
|
-
lcbio_MGR *mgr = he->parent;
|
|
442
|
-
if (req->timer) {
|
|
443
|
-
lcbio_timer_destroy(req->timer);
|
|
444
|
-
req->timer = NULL;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
if (req->sock) {
|
|
448
|
-
lcb_log(LOGARGS(mgr, DEBUG), HE_LOGFMT "Cancelling request=%p with existing connection", HE_LOGID(he), (void*)req);
|
|
449
|
-
lcbio_mgr_put(req->sock);
|
|
450
|
-
lcbio_async_signal(he->async);
|
|
451
|
-
|
|
452
|
-
} else {
|
|
453
|
-
lcb_log(LOGARGS(mgr, DEBUG), HE_LOGFMT "Request=%p has no connection.. yet", HE_LOGID(he), (void*)req);
|
|
454
|
-
lcb_clist_delete(&he->requests, &req->llnode);
|
|
455
|
-
}
|
|
456
|
-
free(req);
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
static void
|
|
460
|
-
on_idle_timeout(void *cookie)
|
|
461
|
-
{
|
|
462
|
-
mgr_CINFO *info = cookie;
|
|
463
|
-
|
|
464
|
-
lcb_log(LOGARGS(info->parent->parent, DEBUG), HE_LOGFMT "Idle connection expired", HE_LOGID(info->parent));
|
|
465
|
-
|
|
466
|
-
lcbio_unref(info->sock);
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
void
|
|
470
|
-
lcbio_mgr_put(lcbio_SOCKET *sock)
|
|
471
|
-
{
|
|
472
|
-
mgr_HOST *he;
|
|
473
|
-
lcbio_MGR *mgr;
|
|
474
|
-
mgr_CINFO *info = cinfo_from_sock(sock);
|
|
475
|
-
|
|
476
|
-
if (!info) {
|
|
477
|
-
fprintf(stderr, "Requested put() for non-pooled (or detached) socket=%p\n", (void *)sock);
|
|
478
|
-
lcbio_unref(sock);
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
he = info->parent;
|
|
483
|
-
mgr = he->parent;
|
|
484
|
-
|
|
485
|
-
if (HE_NIDLE(he) >= mgr->maxidle) {
|
|
486
|
-
lcb_log(LOGARGS(mgr, INFO), HE_LOGFMT "Closing idle connection. Too many in quota", HE_LOGID(he));
|
|
487
|
-
lcbio_unref(info->sock);
|
|
488
|
-
return;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
lcb_log(LOGARGS(mgr, INFO), HE_LOGFMT "Placing socket back into the pool. I=%p,C=%p", HE_LOGID(he), (void*)info, (void*)sock);
|
|
492
|
-
lcbio_timer_rearm(info->idle_timer, mgr->tmoidle);
|
|
493
|
-
lcb_clist_append(&he->ll_idle, &info->llnode);
|
|
494
|
-
info->state = CS_IDLE;
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
void
|
|
498
|
-
lcbio_mgr_discard(lcbio_SOCKET *sock)
|
|
499
|
-
{
|
|
500
|
-
lcbio_unref(sock);
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
void
|
|
504
|
-
lcbio_mgr_detach(lcbio_SOCKET *sock)
|
|
505
|
-
{
|
|
506
|
-
lcbio_protoctx_delid(sock, LCBIO_PROTOCTX_POOL, 1);
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
#define CONN_INDENT " "
|
|
511
|
-
|
|
512
|
-
static void
|
|
513
|
-
write_he_list(lcb_clist_t *ll, FILE *out)
|
|
514
|
-
{
|
|
515
|
-
lcb_list_t *llcur;
|
|
516
|
-
LCB_LIST_FOR(llcur, (lcb_list_t *)ll) {
|
|
517
|
-
mgr_CINFO *info = LCB_LIST_ITEM(llcur, mgr_CINFO, llnode);
|
|
518
|
-
fprintf(out, "%sCONN [I=%p,C=%p ",
|
|
519
|
-
CONN_INDENT, (void *)info, (void *)&info->sock);
|
|
520
|
-
|
|
521
|
-
if (info->sock->io->model == LCB_IOMODEL_EVENT) {
|
|
522
|
-
fprintf(out, "SOCKFD=%d", (int)info->sock->u.fd);
|
|
523
|
-
} else {
|
|
524
|
-
fprintf(out, "SOCKDATA=%p", (void *)info->sock->u.sd);
|
|
525
|
-
}
|
|
526
|
-
fprintf(out, " STATE=0x%x", info->state);
|
|
527
|
-
fprintf(out, "]\n");
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
static void
|
|
533
|
-
he_dump(mgr_HOST *he, FILE *out)
|
|
534
|
-
{
|
|
535
|
-
lcb_list_t *llcur;
|
|
536
|
-
fprintf(out, "HOST=%s", he->key);
|
|
537
|
-
fprintf(out, "Requests=%d, Idle=%d, Pending=%d, Leased=%d\n",
|
|
538
|
-
(int)HE_NREQS(he), (int)HE_NIDLE(he), (int)HE_NPEND(he), (int)HE_NLEASED(he));
|
|
539
|
-
|
|
540
|
-
fprintf(out, CONN_INDENT "Idle Connections:\n");
|
|
541
|
-
write_he_list(&he->ll_idle, out);
|
|
542
|
-
fprintf(out, CONN_INDENT "Pending Connections: \n");
|
|
543
|
-
write_he_list(&he->ll_pending, out);
|
|
544
|
-
fprintf(out, CONN_INDENT "Pending Requests:\n");
|
|
545
|
-
|
|
546
|
-
LCB_LIST_FOR(llcur, (lcb_list_t *)&he->requests) {
|
|
547
|
-
mgr_REQ *req = LCB_LIST_ITEM(llcur, mgr_REQ, llnode);
|
|
548
|
-
union {
|
|
549
|
-
lcbio_CONNDONE_cb cb;
|
|
550
|
-
void *ptr;
|
|
551
|
-
} u_cb;
|
|
552
|
-
|
|
553
|
-
u_cb.cb = req->callback;
|
|
554
|
-
|
|
555
|
-
fprintf(out, "%sREQ [R=%p, Callback=%p, Data=%p, State=0x%x]\n",
|
|
556
|
-
CONN_INDENT, (void *)req, u_cb.ptr, (void *)req->arg,
|
|
557
|
-
req->state);
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
fprintf(out, "\n");
|
|
561
|
-
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
static void
|
|
565
|
-
dumpfunc(const void *k, lcb_size_t nk, const void *v, lcb_size_t nv, void *arg)
|
|
566
|
-
{
|
|
567
|
-
FILE *out = (FILE *)arg;
|
|
568
|
-
mgr_HOST *he = (void *)v;
|
|
569
|
-
he_dump(he, out);
|
|
570
|
-
(void)nk;(void)k;(void)nv;
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
/**
|
|
574
|
-
* Dumps the connection manager state to stderr
|
|
575
|
-
*/
|
|
576
|
-
LCB_INTERNAL_API
|
|
577
|
-
void lcbio_mgr_dump(lcbio_MGR *mgr, FILE *out)
|
|
578
|
-
{
|
|
579
|
-
if (out == NULL) {
|
|
580
|
-
out = stderr;
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
genhash_iter(mgr->ht, dumpfunc, out);
|
|
584
|
-
}
|