couchbase 1.3.6-x86-mingw32 → 1.3.7-x86-mingw32
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/RELEASE_NOTES.markdown +53 -0
- data/couchbase.gemspec +2 -1
- data/ext/couchbase_ext/bucket.c +72 -8
- data/ext/couchbase_ext/couchbase_ext.c +6 -0
- data/ext/couchbase_ext/couchbase_ext.h +4 -0
- data/ext/couchbase_ext/eventmachine_plugin.c +14 -2
- data/ext/couchbase_ext/extconf.rb +2 -2
- data/ext/couchbase_ext/utils.c +1 -1
- data/lib/couchbase/dns.rb +76 -0
- data/lib/couchbase/version.rb +1 -1
- data/tasks/compile.rake +1 -1
- data/test/test_bucket.rb +12 -0
- data/test/test_couchbase_rails_cache_store.rb +3 -6
- data/test/test_eventmachine.rb +8 -0
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5bb5fe7908b2151f5898c39f1176ef58f13590be
|
4
|
+
data.tar.gz: 646c7379acfe8c0bf26a654659bc1cb9328b19b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77548600a47604c8b366d685dffd0aa3fa2c4cd6051fa065b91a18a625c37bf9aae277abdbec759f1e219f715e51ccb30c76e80899e42dd43bae847d41f0b7c5
|
7
|
+
data.tar.gz: 3649bbe28a65eb21ac3fe9f3b52a5daf98686eb083f03dc53bfa37b0b3c5d81dc3c2fbb46a1b80209978610219d07d69b28fcb52e13f976134a1cc0e18988393
|
data/RELEASE_NOTES.markdown
CHANGED
@@ -3,6 +3,59 @@
|
|
3
3
|
This document is a list of user visible feature changes and important
|
4
4
|
bugfixes. Do not forget to update this doc in every important patch.
|
5
5
|
|
6
|
+
## 1.3.7 (2014-04-18)
|
7
|
+
|
8
|
+
* [major] Allow the selection of bootstrap providers. Since libcouchbase
|
9
|
+
2.3.0 there is a new bootstrapping transport available: Cluster
|
10
|
+
Configuration Carrier Publication (CCCP). It is more efficient way
|
11
|
+
to keep cluster configuration up to date using Carrier Publication
|
12
|
+
instead of HTTP connection.
|
13
|
+
|
14
|
+
nodes = ["example.com", "example.org"]
|
15
|
+
Couchbase.connect(node_list: nodes, bootstrap_transports: [:cccp, :http])
|
16
|
+
|
17
|
+
Read more about it here:
|
18
|
+
http://www.couchbase.com/wiki/display/couchbase/Cluster+Configuration+Carrier+Publication
|
19
|
+
|
20
|
+
* [major] RCBC-168 An experimental DNS SRV helper for connection
|
21
|
+
constructor. The DNS SRV records need to be configured on a reachable
|
22
|
+
DNS server. An example configuration could look like the following
|
23
|
+
(note that the service ids might change):
|
24
|
+
|
25
|
+
_cbmcd._tcp.example.com. 0 IN SRV 20 0 11210 node2.example.com.
|
26
|
+
_cbmcd._tcp.example.com. 0 IN SRV 10 0 11210 node1.example.com.
|
27
|
+
_cbmcd._tcp.example.com. 0 IN SRV 30 0 11210 node3.example.com.
|
28
|
+
|
29
|
+
_cbhttp._tcp.example.com. 0 IN SRV 20 0 8091 node2.example.com.
|
30
|
+
_cbhttp._tcp.example.com. 0 IN SRV 10 0 8091 node1.example.com.
|
31
|
+
_cbhttp._tcp.example.com. 0 IN SRV 30 0 8091 node3.example.com.
|
32
|
+
|
33
|
+
Now if "example.com" is passed in as the argument, the three nodes
|
34
|
+
configured will be parsed and put in the returned URI list. Note
|
35
|
+
that the priority is respected (in this example, node1 will be the
|
36
|
+
first one in the list, followed by node2 and node3). As of now,
|
37
|
+
weighting is not supported. This is how it could be used to
|
38
|
+
bootstrap the connection:
|
39
|
+
|
40
|
+
transport = :http
|
41
|
+
nodes = Couchbase::DNS.locate('example.com', transport)
|
42
|
+
if nodes.empty?
|
43
|
+
nodes = ["example.com:8091"]
|
44
|
+
end
|
45
|
+
Couchbase.connect(node_list: nodes, bootstrap_transports: [transport])
|
46
|
+
|
47
|
+
NOTE: This is experiemental and subject to change at any time. Watch
|
48
|
+
the release notes for changes in future releases.
|
49
|
+
|
50
|
+
* [major] RCBC-166 Fix a crash with eventmachine. In eventmachine event
|
51
|
+
handlers are separated and run seprately and in the following order:
|
52
|
+
[READ, WRITE]. So it was possible to cancel WRITE event handler from
|
53
|
+
the READ handler which cause crash when the reactor run it in next
|
54
|
+
turn.
|
55
|
+
|
56
|
+
* [minor] Fixed a typo which doesn't allow to use bundler in the project
|
57
|
+
directory.
|
58
|
+
|
6
59
|
## 1.3.6 (2014-02-17)
|
7
60
|
|
8
61
|
* [major] Fix linkage issue which blocks library installation on
|
data/couchbase.gemspec
CHANGED
@@ -44,6 +44,7 @@ Gem::Specification.new do |s|
|
|
44
44
|
s.add_development_dependency 'rake-compiler', '~> 0.7', '>= 0.7.5'
|
45
45
|
s.add_development_dependency 'mini_portile', '~> 0.5', '>= 0.5.2'
|
46
46
|
s.add_development_dependency 'yajl-ruby', '~> 1.1', '>= 1.1.0'
|
47
|
-
s.add_development_dependency '
|
47
|
+
s.add_development_dependency 'activesupport'
|
48
48
|
s.add_development_dependency 'eventmachine'
|
49
|
+
s.add_development_dependency 'em-synchrony'
|
49
50
|
end
|
data/ext/couchbase_ext/bucket.c
CHANGED
@@ -99,6 +99,8 @@ cb_bucket_mark(void *ptr)
|
|
99
99
|
rb_gc_mark(bucket->on_error_proc);
|
100
100
|
rb_gc_mark(bucket->on_connect_proc);
|
101
101
|
rb_gc_mark(bucket->key_prefix_val);
|
102
|
+
rb_gc_mark(bucket->node_list);
|
103
|
+
rb_gc_mark(bucket->bootstrap_transports);
|
102
104
|
if (bucket->object_space) {
|
103
105
|
st_foreach(bucket->object_space, cb_bucket_mark_object_i, (st_data_t)bucket);
|
104
106
|
}
|
@@ -172,6 +174,11 @@ do_scan_connection_options(struct cb_bucket_st *bucket, int argc, VALUE *argv)
|
|
172
174
|
bucket->node_list = rb_ary_join(arg, STR_NEW_CSTR(";"));
|
173
175
|
rb_str_freeze(bucket->node_list);
|
174
176
|
}
|
177
|
+
arg = rb_hash_aref(opts, cb_sym_bootstrap_transports);
|
178
|
+
if (arg != Qnil) {
|
179
|
+
Check_Type(arg, T_ARRAY);
|
180
|
+
bucket->bootstrap_transports = arg;
|
181
|
+
}
|
175
182
|
arg = rb_hash_aref(opts, cb_sym_hostname);
|
176
183
|
if (arg != Qnil) {
|
177
184
|
bucket->hostname = rb_str_dup_frozen(StringValue(arg));
|
@@ -325,6 +332,11 @@ do_connect(struct cb_bucket_st *bucket)
|
|
325
332
|
{
|
326
333
|
lcb_error_t err;
|
327
334
|
struct lcb_create_st create_opts;
|
335
|
+
lcb_config_transport_t transports[3] = {
|
336
|
+
LCB_CONFIG_TRANSPORT_HTTP,
|
337
|
+
LCB_CONFIG_TRANSPORT_LIST_END,
|
338
|
+
LCB_CONFIG_TRANSPORT_LIST_END
|
339
|
+
};
|
328
340
|
|
329
341
|
if (bucket->handle) {
|
330
342
|
cb_bucket_disconnect(bucket->self);
|
@@ -367,13 +379,28 @@ do_connect(struct cb_bucket_st *bucket)
|
|
367
379
|
}
|
368
380
|
|
369
381
|
memset(&create_opts, 0, sizeof(struct lcb_create_st));
|
370
|
-
create_opts.version =
|
371
|
-
create_opts.v.
|
372
|
-
create_opts.v.
|
373
|
-
create_opts.v.
|
374
|
-
create_opts.v.
|
375
|
-
create_opts.v.
|
376
|
-
create_opts.v.
|
382
|
+
create_opts.version = 2;
|
383
|
+
create_opts.v.v2.type = bucket->type;
|
384
|
+
create_opts.v.v2.host = RTEST(bucket->node_list) ? RSTRING_PTR(bucket-> node_list) : RSTRING_PTR(bucket->authority);
|
385
|
+
create_opts.v.v2.user = RTEST(bucket->username) ? RSTRING_PTR(bucket->username) : NULL;
|
386
|
+
create_opts.v.v2.passwd = RTEST(bucket->password) ? RSTRING_PTR(bucket->password) : NULL;
|
387
|
+
create_opts.v.v2.bucket = RSTRING_PTR(bucket->bucket);
|
388
|
+
create_opts.v.v2.io = bucket->io;
|
389
|
+
if (RTEST(bucket->bootstrap_transports) && RARRAY_LEN(bucket->bootstrap_transports) > 0) {
|
390
|
+
int i;
|
391
|
+
for (i = 0; i < 2 && i < RARRAY_LEN(bucket->bootstrap_transports); ++i) {
|
392
|
+
VALUE transport_sym = rb_ary_entry(bucket->bootstrap_transports, i);
|
393
|
+
if (transport_sym == cb_sym_cccp) {
|
394
|
+
transports[i] = LCB_CONFIG_TRANSPORT_CCCP;
|
395
|
+
} else if (transport_sym == cb_sym_http) {
|
396
|
+
transports[i] = LCB_CONFIG_TRANSPORT_HTTP;
|
397
|
+
} else {
|
398
|
+
transports[i] = LCB_CONFIG_TRANSPORT_LIST_END;
|
399
|
+
break;
|
400
|
+
}
|
401
|
+
}
|
402
|
+
}
|
403
|
+
create_opts.v.v2.transports = transports;
|
377
404
|
err = lcb_create(&bucket->handle, &create_opts);
|
378
405
|
if (err != LCB_SUCCESS) {
|
379
406
|
bucket->handle = NULL;
|
@@ -501,6 +528,17 @@ cb_bucket_alloc(VALUE klass)
|
|
501
528
|
* IO interaction will be occured only when {Couchbase::Bucket#run}
|
502
529
|
* called. See {Couchbase::Bucket#on_connect} to hook your code
|
503
530
|
* after the instance will be connected.
|
531
|
+
* @option options [Array] :bootstrap_transports (nil) the list of
|
532
|
+
* bootrap transport mechanisms the library should try during
|
533
|
+
* initial connection and also when cluster changes its
|
534
|
+
* topology. When +nil+ passed it will fallback to best accessible
|
535
|
+
* option. The order of the array elements does not matter at the
|
536
|
+
* momemnt. Currently following values are supported:
|
537
|
+
* :http :: Previous default protocol, which involves open HTTP stream
|
538
|
+
* :cccp :: Cluster Configutration Carrier Publication: new binary
|
539
|
+
* protocol for efficient delivery of cluster
|
540
|
+
* configuration changes to the clients. Read more at
|
541
|
+
* http://www.couchbase.com/wiki/display/couchbase/Cluster+Configuration+Carrier+Publication
|
504
542
|
*
|
505
543
|
* @example Initialize connection using default options
|
506
544
|
* Couchbase.new
|
@@ -551,6 +589,7 @@ cb_bucket_init(int argc, VALUE *argv, VALUE self)
|
|
551
589
|
bucket->environment = cb_sym_production;
|
552
590
|
bucket->key_prefix_val = Qnil;
|
553
591
|
bucket->node_list = Qnil;
|
592
|
+
bucket->bootstrap_transports = Qnil;
|
554
593
|
bucket->object_space = st_init_numtable();
|
555
594
|
bucket->destroying = 0;
|
556
595
|
bucket->connected = 0;
|
@@ -589,7 +628,7 @@ cb_bucket_init_copy(VALUE copy, VALUE orig)
|
|
589
628
|
copy_b = DATA_PTR(copy);
|
590
629
|
orig_b = DATA_PTR(orig);
|
591
630
|
|
592
|
-
copy_b->self =
|
631
|
+
copy_b->self = copy;
|
593
632
|
copy_b->port = orig_b->port;
|
594
633
|
copy_b->authority = orig_b->authority;
|
595
634
|
copy_b->hostname = orig_b->hostname;
|
@@ -613,6 +652,15 @@ cb_bucket_init_copy(VALUE copy, VALUE orig)
|
|
613
652
|
if (orig_b->on_connect_proc != Qnil) {
|
614
653
|
copy_b->on_connect_proc = rb_funcall(orig_b->on_connect_proc, cb_id_dup, 0);
|
615
654
|
}
|
655
|
+
if (orig_b->key_prefix_val != Qnil) {
|
656
|
+
copy_b->key_prefix_val = rb_funcall(orig_b->key_prefix_val, cb_id_dup, 0);
|
657
|
+
}
|
658
|
+
if (orig_b->node_list != Qnil) {
|
659
|
+
copy_b->node_list = rb_funcall(orig_b->node_list, cb_id_dup, 0);
|
660
|
+
}
|
661
|
+
if (orig_b->bootstrap_transports != Qnil) {
|
662
|
+
copy_b->bootstrap_transports = rb_funcall(orig_b->bootstrap_transports, cb_id_dup, 0);
|
663
|
+
}
|
616
664
|
copy_b->key_prefix_val = orig_b->key_prefix_val;
|
617
665
|
copy_b->object_space = st_init_numtable();
|
618
666
|
copy_b->destroying = 0;
|
@@ -1164,6 +1212,22 @@ cb_bucket_inspect(VALUE self)
|
|
1164
1212
|
(bucket->handle && bucket->connected) ? "true" : "false",
|
1165
1213
|
bucket->timeout);
|
1166
1214
|
rb_str_buf_cat2(str, buf);
|
1215
|
+
if (bucket->handle && bucket->connected) {
|
1216
|
+
lcb_config_transport_t type;
|
1217
|
+
rb_str_buf_cat2(str, ", bootstrap_transport=");
|
1218
|
+
lcb_cntl(bucket->handle, LCB_CNTL_GET, LCB_CNTL_CONFIG_TRANSPORT, &type);
|
1219
|
+
switch (type) {
|
1220
|
+
case LCB_CONFIG_TRANSPORT_HTTP:
|
1221
|
+
rb_str_buf_cat2(str, ":http");
|
1222
|
+
break;
|
1223
|
+
case LCB_CONFIG_TRANSPORT_CCCP:
|
1224
|
+
rb_str_buf_cat2(str, ":cccp");
|
1225
|
+
break;
|
1226
|
+
default:
|
1227
|
+
rb_str_buf_cat2(str, "<unknown>");
|
1228
|
+
break;
|
1229
|
+
}
|
1230
|
+
}
|
1167
1231
|
if (RTEST(bucket->key_prefix_val)) {
|
1168
1232
|
rb_str_buf_cat2(str, ", key_prefix=");
|
1169
1233
|
rb_str_append(str, rb_inspect(bucket->key_prefix_val));
|
@@ -41,8 +41,10 @@ ID cb_sym_append;
|
|
41
41
|
ID cb_sym_assemble_hash;
|
42
42
|
ID cb_sym_async;
|
43
43
|
ID cb_sym_body;
|
44
|
+
ID cb_sym_bootstrap_transports;
|
44
45
|
ID cb_sym_bucket;
|
45
46
|
ID cb_sym_cas;
|
47
|
+
ID cb_sym_cccp;
|
46
48
|
ID cb_sym_chunked;
|
47
49
|
ID cb_sym_cluster;
|
48
50
|
ID cb_sym_connect;
|
@@ -70,6 +72,7 @@ ID cb_sym_format;
|
|
70
72
|
ID cb_sym_found;
|
71
73
|
ID cb_sym_get;
|
72
74
|
ID cb_sym_hostname;
|
75
|
+
ID cb_sym_http;
|
73
76
|
ID cb_sym_http_request;
|
74
77
|
ID cb_sym_increment;
|
75
78
|
ID cb_sym_initial;
|
@@ -1286,8 +1289,10 @@ Init_couchbase_ext(void)
|
|
1286
1289
|
cb_sym_assemble_hash = ID2SYM(rb_intern("assemble_hash"));
|
1287
1290
|
cb_sym_async = ID2SYM(rb_intern("async"));
|
1288
1291
|
cb_sym_body = ID2SYM(rb_intern("body"));
|
1292
|
+
cb_sym_bootstrap_transports = ID2SYM(rb_intern("bootstrap_transports"));
|
1289
1293
|
cb_sym_bucket = ID2SYM(rb_intern("bucket"));
|
1290
1294
|
cb_sym_cas = ID2SYM(rb_intern("cas"));
|
1295
|
+
cb_sym_cccp = ID2SYM(rb_intern("cccp"));
|
1291
1296
|
cb_sym_chunked = ID2SYM(rb_intern("chunked"));
|
1292
1297
|
cb_sym_cluster = ID2SYM(rb_intern("cluster"));
|
1293
1298
|
cb_sym_connect = ID2SYM(rb_intern("connect"));
|
@@ -1314,6 +1319,7 @@ Init_couchbase_ext(void)
|
|
1314
1319
|
cb_sym_found = ID2SYM(rb_intern("found"));
|
1315
1320
|
cb_sym_get = ID2SYM(rb_intern("get"));
|
1316
1321
|
cb_sym_hostname = ID2SYM(rb_intern("hostname"));
|
1322
|
+
cb_sym_http = ID2SYM(rb_intern("http"));
|
1317
1323
|
cb_sym_http_request = ID2SYM(rb_intern("http_request"));
|
1318
1324
|
cb_sym_increment = ID2SYM(rb_intern("increment"));
|
1319
1325
|
cb_sym_initial = ID2SYM(rb_intern("initial"));
|
@@ -116,6 +116,7 @@ struct cb_bucket_st
|
|
116
116
|
VALUE environment; /* sym_development or sym_production */
|
117
117
|
VALUE key_prefix_val;
|
118
118
|
VALUE node_list;
|
119
|
+
VALUE bootstrap_transports;
|
119
120
|
st_table *object_space;
|
120
121
|
char destroying;
|
121
122
|
char async_disconnect_hook_set;
|
@@ -189,8 +190,10 @@ extern ID cb_sym_append;
|
|
189
190
|
extern ID cb_sym_assemble_hash;
|
190
191
|
extern ID cb_sym_async;
|
191
192
|
extern ID cb_sym_body;
|
193
|
+
extern ID cb_sym_bootstrap_transports;
|
192
194
|
extern ID cb_sym_bucket;
|
193
195
|
extern ID cb_sym_cas;
|
196
|
+
extern ID cb_sym_cccp;
|
194
197
|
extern ID cb_sym_chunked;
|
195
198
|
extern ID cb_sym_cluster;
|
196
199
|
extern ID cb_sym_connect;
|
@@ -218,6 +221,7 @@ extern ID cb_sym_format;
|
|
218
221
|
extern ID cb_sym_found;
|
219
222
|
extern ID cb_sym_get;
|
220
223
|
extern ID cb_sym_hostname;
|
224
|
+
extern ID cb_sym_http;
|
221
225
|
extern ID cb_sym_http_request;
|
222
226
|
extern ID cb_sym_increment;
|
223
227
|
extern ID cb_sym_initial;
|
@@ -51,6 +51,8 @@ struct rb_em_event {
|
|
51
51
|
lcb_uint32_t usec;
|
52
52
|
short canceled;
|
53
53
|
short current_flags;
|
54
|
+
short in_read_handler;
|
55
|
+
short deferred_write_reset;
|
54
56
|
VALUE self;
|
55
57
|
rb_em_loop *loop;
|
56
58
|
};
|
@@ -140,7 +142,9 @@ rb_em_socket_notify_readable(VALUE self)
|
|
140
142
|
|
141
143
|
if (RTEST(event)) {
|
142
144
|
Data_Get_Struct(event, rb_em_event, ev);
|
145
|
+
ev->in_read_handler = 1;
|
143
146
|
rb_em_event_run_callback(ev, LCB_READ_EVENT);
|
147
|
+
ev->in_read_handler = 0;
|
144
148
|
} else {
|
145
149
|
rb_funcall_0(self, cb_id_detach);
|
146
150
|
}
|
@@ -157,6 +161,10 @@ rb_em_socket_notify_writable(VALUE self)
|
|
157
161
|
if (RTEST(event)) {
|
158
162
|
Data_Get_Struct(event, rb_em_event, ev);
|
159
163
|
rb_em_event_run_callback(ev, LCB_WRITE_EVENT);
|
164
|
+
if (ev->deferred_write_reset) {
|
165
|
+
ev->deferred_write_reset = 0;
|
166
|
+
rb_funcall_1(ev->holder, cb_id_set_notify_writable, Qfalse);
|
167
|
+
}
|
160
168
|
} else {
|
161
169
|
rb_funcall_0(self, cb_id_detach);
|
162
170
|
}
|
@@ -278,8 +286,12 @@ lcb_io_update_event(struct lcb_io_opt_st *iops,
|
|
278
286
|
ev->handler = handler;
|
279
287
|
|
280
288
|
rb_funcall_1(ev->holder, cb_id_set_notify_readable, (flags & LCB_READ_EVENT) ? Qtrue : Qfalse);
|
281
|
-
|
282
|
-
|
289
|
+
/* it is safe to reset WRITE event only from WRITE handler */
|
290
|
+
if (ev->in_read_handler && (flags & LCB_WRITE_EVENT) == 0 && RTEST(rb_funcall_0(ev->holder, cb_id_notify_writable_p))) {
|
291
|
+
ev->deferred_write_reset = 1;
|
292
|
+
} else {
|
293
|
+
rb_funcall_1(ev->holder, cb_id_set_notify_writable, (flags & LCB_WRITE_EVENT) ? Qtrue : Qfalse);
|
294
|
+
}
|
283
295
|
(void)iops;
|
284
296
|
return 0;
|
285
297
|
}
|
@@ -132,14 +132,14 @@ def die(message)
|
|
132
132
|
abort
|
133
133
|
end
|
134
134
|
|
135
|
-
install_notice = "You must install libcouchbase >= 2.
|
135
|
+
install_notice = "You must install libcouchbase >= 2.3.0\nSee http://www.couchbase.com/communities/c/ for more details"
|
136
136
|
|
137
137
|
unless try_compile(<<-SRC)
|
138
138
|
#include <libcouchbase/couchbase.h>
|
139
139
|
#include <stdio.h>
|
140
140
|
|
141
141
|
int main() {
|
142
|
-
printf("
|
142
|
+
printf("CCCP transport flag is: %d\\n", LCB_CONFIG_TRANSPORT_CCCP);
|
143
143
|
return 0;
|
144
144
|
}
|
145
145
|
SRC
|
data/ext/couchbase_ext/utils.c
CHANGED
@@ -254,7 +254,7 @@ cb_check_error_with_status(lcb_error_t rc, const char *msg, VALUE key,
|
|
254
254
|
klass = cb_eDuplicateCommands;
|
255
255
|
break;
|
256
256
|
case LCB_NO_MATCHING_SERVER:
|
257
|
-
klass =
|
257
|
+
klass = cb_eNoMatchingServer;
|
258
258
|
break;
|
259
259
|
case LCB_BAD_ENVIRONMENT:
|
260
260
|
klass = cb_eBadEnvironment;
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# Author:: Couchbase <info@couchbase.com>
|
2
|
+
# Copyright:: 2014 Couchbase, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
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
|
+
require 'resolv'
|
19
|
+
|
20
|
+
module Couchbase
|
21
|
+
module DNS
|
22
|
+
# Locate bootstrap nodes from a DNS SRV record.
|
23
|
+
#
|
24
|
+
# @note This is experimental interface. It might change in future
|
25
|
+
# (e.g. service identifiers)
|
26
|
+
#
|
27
|
+
# The DNS SRV records need to be configured on a reachable DNS server. An
|
28
|
+
# example configuration could look like the following:
|
29
|
+
#
|
30
|
+
# _cbmcd._tcp.example.com. 0 IN SRV 20 0 11210 node2.example.com.
|
31
|
+
# _cbmcd._tcp.example.com. 0 IN SRV 10 0 11210 node1.example.com.
|
32
|
+
# _cbmcd._tcp.example.com. 0 IN SRV 30 0 11210 node3.example.com.
|
33
|
+
#
|
34
|
+
# _cbhttp._tcp.example.com. 0 IN SRV 20 0 8091 node2.example.com.
|
35
|
+
# _cbhttp._tcp.example.com. 0 IN SRV 10 0 8091 node1.example.com.
|
36
|
+
# _cbhttp._tcp.example.com. 0 IN SRV 30 0 8091 node3.example.com.
|
37
|
+
#
|
38
|
+
# Now if "example.com" is passed in as the argument, the three
|
39
|
+
# nodes configured will be parsed and put in the returned URI list. Note that
|
40
|
+
# the priority is respected (in this example, node1 will be the first one
|
41
|
+
# in the list, followed by node2 and node3). As of now, weighting is not
|
42
|
+
# supported.
|
43
|
+
#
|
44
|
+
# @param name the DNS name where SRV records configured
|
45
|
+
# @param bootstrap_protocol (Symbol) the desired protocol for
|
46
|
+
# bootstrapping. See +bootstrap_protocols+ option to
|
47
|
+
# {Couchbase::Bucket#new}. Allowed values +:http, :cccp+
|
48
|
+
# @return a list of ordered boostrap URIs by their weight.
|
49
|
+
#
|
50
|
+
# @example Initialize connection using DNS SRV records
|
51
|
+
#
|
52
|
+
# nodes = Couchbase::DNS.locate('example.com', :http)
|
53
|
+
# if nodes.empty?
|
54
|
+
# nodes = ["example.com:8091"]
|
55
|
+
# end
|
56
|
+
# Couchbase.connect(:node_list => nodes)
|
57
|
+
def locate(name, bootstrap_protocol = :http)
|
58
|
+
service = case bootstrap_protocol
|
59
|
+
when :http
|
60
|
+
"_cbhttp"
|
61
|
+
when :cccp
|
62
|
+
"_cbmcd"
|
63
|
+
else
|
64
|
+
raise ArgumentError, "unknown bootstrap protocol: #{bootstrap_transports}"
|
65
|
+
end
|
66
|
+
hosts = []
|
67
|
+
Resolv::DNS.open do |dns|
|
68
|
+
resources = dns.getresources("#{service}._tcp.#{name}", Resolv::DNS::Resource::IN::SRV)
|
69
|
+
hosts = resources.sort_by(&:priority).map { |res| "#{res.target}:#{res.port}" }
|
70
|
+
end
|
71
|
+
hosts
|
72
|
+
end
|
73
|
+
|
74
|
+
module_function :locate
|
75
|
+
end
|
76
|
+
end
|
data/lib/couchbase/version.rb
CHANGED
data/tasks/compile.rake
CHANGED
@@ -137,7 +137,7 @@ task "package:windows" => ["package", "lib/couchbase_ext.rb"] do
|
|
137
137
|
ENV['TARGET'] = platform.name
|
138
138
|
rm_rf("tmp/ ports/")
|
139
139
|
mkdir_p("ports")
|
140
|
-
recipe = MiniPortile.new("libcouchbase", "2.
|
140
|
+
recipe = MiniPortile.new("libcouchbase", "2.3.0")
|
141
141
|
recipe.host = platform.host
|
142
142
|
recipe.files << "http://packages.couchbase.com/clients/c/libcouchbase-#{recipe.version}.tar.gz"
|
143
143
|
recipe.configure_options.push("--disable-debug",
|
data/test/test_bucket.rb
CHANGED
@@ -273,4 +273,16 @@ class TestBucket < MiniTest::Test
|
|
273
273
|
end
|
274
274
|
end
|
275
275
|
|
276
|
+
def test_it_can_duplicate_the_connection_creating_new_one
|
277
|
+
with_mock do |mock|
|
278
|
+
connection = Couchbase.new(:hostname => mock.host,
|
279
|
+
:port => mock.port)
|
280
|
+
double = connection.dup
|
281
|
+
assert_equal double.hostname, connection.hostname
|
282
|
+
assert_equal double.port, connection.port
|
283
|
+
connection.disconnect
|
284
|
+
refute connection.connected?, "original connection should be closed"
|
285
|
+
assert double.connected?, "duplicate connection should be alive"
|
286
|
+
end
|
287
|
+
end
|
276
288
|
end
|
@@ -92,13 +92,10 @@ class TestCouchbaseRailsCacheStore < MiniTest::Test
|
|
92
92
|
|
93
93
|
def test_it_reads_raw_data
|
94
94
|
store.write uniq_id, @foo
|
95
|
-
expected =
|
96
|
-
when /^2\.0/
|
97
|
-
"\x04\bU:\x0FOpenStruct{\x06:\fpayloadI\"\bfoo\x06:\x06ET"
|
98
|
-
when /^1\.9/
|
99
|
-
"\x04\bU:\x0FOpenStruct{\x06:\fpayloadI\"\bfoo\x06:\x06EF"
|
100
|
-
else
|
95
|
+
expected = if RUBY_VERSION =~ /^1\.8/
|
101
96
|
"\004\bU:\017OpenStruct{\006:\fpayload\"\bfoo"
|
97
|
+
else
|
98
|
+
"\x04\bU:\x0FOpenStruct{\x06:\fpayloadI\"\bfoo\x06:\x06ET"
|
102
99
|
end
|
103
100
|
assert_equal expected, store.read(uniq_id, :raw => true)
|
104
101
|
end
|
data/test/test_eventmachine.rb
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
|
18
18
|
require File.join(File.dirname(__FILE__), 'setup')
|
19
19
|
require 'eventmachine'
|
20
|
+
require 'em-synchrony'
|
20
21
|
|
21
22
|
class TestEventmachine < MiniTest::Test
|
22
23
|
|
@@ -65,6 +66,13 @@ class TestEventmachine < MiniTest::Test
|
|
65
66
|
end
|
66
67
|
end
|
67
68
|
|
69
|
+
def test_integration_with_em_synchrony
|
70
|
+
EM.epoll
|
71
|
+
EM.synchrony do
|
72
|
+
Couchbase::Bucket.new(:engine => :eventmachine, bucket: "default", :node_list => ["localhost:8091"])
|
73
|
+
EventMachine.stop
|
74
|
+
end
|
75
|
+
end
|
68
76
|
end
|
69
77
|
|
70
78
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: couchbase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.7
|
5
5
|
platform: x86-mingw32
|
6
6
|
authors:
|
7
7
|
- Couchbase
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: yaji
|
@@ -159,7 +159,7 @@ dependencies:
|
|
159
159
|
- !ruby/object:Gem::Version
|
160
160
|
version: 1.1.0
|
161
161
|
- !ruby/object:Gem::Dependency
|
162
|
-
name:
|
162
|
+
name: activesupport
|
163
163
|
requirement: !ruby/object:Gem::Requirement
|
164
164
|
requirements:
|
165
165
|
- - '>='
|
@@ -186,6 +186,20 @@ dependencies:
|
|
186
186
|
- - '>='
|
187
187
|
- !ruby/object:Gem::Version
|
188
188
|
version: '0'
|
189
|
+
- !ruby/object:Gem::Dependency
|
190
|
+
name: em-synchrony
|
191
|
+
requirement: !ruby/object:Gem::Requirement
|
192
|
+
requirements:
|
193
|
+
- - '>='
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
version: '0'
|
196
|
+
type: :development
|
197
|
+
prerelease: false
|
198
|
+
version_requirements: !ruby/object:Gem::Requirement
|
199
|
+
requirements:
|
200
|
+
- - '>='
|
201
|
+
- !ruby/object:Gem::Version
|
202
|
+
version: '0'
|
189
203
|
description: The official client library for use with Couchbase Server.
|
190
204
|
email: support@couchbase.com
|
191
205
|
executables: []
|
@@ -247,6 +261,7 @@ files:
|
|
247
261
|
- lib/couchbase/cluster.rb
|
248
262
|
- lib/couchbase/connection_pool.rb
|
249
263
|
- lib/couchbase/constants.rb
|
264
|
+
- lib/couchbase/dns.rb
|
250
265
|
- lib/couchbase/result.rb
|
251
266
|
- lib/couchbase/transcoder.rb
|
252
267
|
- lib/couchbase/utils.rb
|