libcouchbase 0.0.9 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -4
- data/README.md +4 -0
- data/ext/libcouchbase/CMakeLists.txt +1 -1
- data/ext/libcouchbase/RELEASE_NOTES.markdown +42 -0
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/source_files.cmake +1 -0
- data/ext/libcouchbase/include/libcouchbase/cntl.h +27 -1
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +0 -10
- data/ext/libcouchbase/include/libcouchbase/error.h +8 -1
- data/ext/libcouchbase/include/memcached/protocol_binary.h +12 -3
- data/ext/libcouchbase/src/auth.cc +0 -4
- data/ext/libcouchbase/src/cntl.cc +11 -1
- data/ext/libcouchbase/src/connspec.cc +18 -0
- data/ext/libcouchbase/src/connspec.h +10 -0
- data/ext/libcouchbase/src/dns-srv.cc +13 -14
- data/ext/libcouchbase/src/errmap.cc +107 -0
- data/ext/libcouchbase/src/errmap.h +113 -0
- data/ext/libcouchbase/src/hostlist.cc +0 -35
- data/ext/libcouchbase/src/hostlist.h +38 -64
- data/ext/libcouchbase/src/http/http.cc +6 -1
- data/ext/libcouchbase/src/instance.cc +1 -1
- data/ext/libcouchbase/src/internal.h +10 -0
- data/ext/libcouchbase/src/mcserver/mcserver.cc +119 -3
- data/ext/libcouchbase/src/mcserver/mcserver.h +3 -1
- data/ext/libcouchbase/src/mcserver/negotiate.cc +130 -37
- data/ext/libcouchbase/src/nodeinfo.cc +1 -1
- data/ext/libcouchbase/src/settings.c +3 -0
- data/ext/libcouchbase/src/settings.h +5 -0
- data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
- data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
- data/ext/libcouchbase/tests/iotests/mock-environment.h +2 -1
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +3 -4
- data/ext/libcouchbase/tests/iotests/t_errmap.cc +97 -0
- data/lib/libcouchbase/bucket.rb +27 -12
- data/lib/libcouchbase/callbacks.rb +1 -1
- data/lib/libcouchbase/connection.rb +18 -5
- data/lib/libcouchbase/version.rb +1 -1
- data/spec/connection_spec.rb +1 -1
- metadata +5 -2
@@ -141,14 +141,13 @@ TEST_F(ConfmonTest, testCycle)
|
|
141
141
|
Provider *cccp = mon->get_provider(CLCONFIG_CCCP);
|
142
142
|
Provider *http = mon->get_provider(CLCONFIG_HTTP);
|
143
143
|
|
144
|
-
|
145
|
-
|
144
|
+
lcb::Hostlist hl;
|
145
|
+
hl.add(cropts.v.v2.mchosts, 11210);
|
146
146
|
cccp->enable(instance);
|
147
|
-
cccp->configure_nodes(
|
147
|
+
cccp->configure_nodes(hl);
|
148
148
|
|
149
149
|
http->enable();
|
150
150
|
http->configure_nodes(*instance->ht_nodes);
|
151
|
-
hostlist_destroy(hl);
|
152
151
|
|
153
152
|
mon->prepare();
|
154
153
|
mon->start();
|
@@ -0,0 +1,97 @@
|
|
1
|
+
#include "config.h"
|
2
|
+
#include "iotests.h"
|
3
|
+
#include "internal.h"
|
4
|
+
#include <map>
|
5
|
+
|
6
|
+
class ErrmapUnitTest : public MockUnitTest {
|
7
|
+
protected:
|
8
|
+
virtual void createErrmapConnection(HandleWrap& hw, lcb_t& instance) {
|
9
|
+
MockEnvironment::getInstance()->createConnection(hw, instance);
|
10
|
+
ASSERT_EQ(LCB_SUCCESS, lcb_cntl_string(instance, "enable_errmap", "true"));
|
11
|
+
ASSERT_EQ(LCB_SUCCESS, lcb_connect(instance));
|
12
|
+
lcb_wait(instance);
|
13
|
+
ASSERT_EQ(LCB_SUCCESS, lcb_get_bootstrap_status(instance));
|
14
|
+
}
|
15
|
+
};
|
16
|
+
|
17
|
+
struct ResultCookie {
|
18
|
+
lcb_error_t rc;
|
19
|
+
bool called;
|
20
|
+
|
21
|
+
void reset() {
|
22
|
+
rc = LCB_SUCCESS;
|
23
|
+
called = false;
|
24
|
+
}
|
25
|
+
ResultCookie() : rc(LCB_SUCCESS), called(false) {
|
26
|
+
}
|
27
|
+
};
|
28
|
+
|
29
|
+
extern "C" {
|
30
|
+
static void opcb(lcb_t,int,const lcb_RESPBASE* rb) {
|
31
|
+
ResultCookie *cookie = reinterpret_cast<ResultCookie*>(rb->cookie);
|
32
|
+
cookie->called = true;
|
33
|
+
cookie->rc = rb->rc;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
TEST_F(ErrmapUnitTest, hasRecognizedErrors) {
|
38
|
+
SKIP_UNLESS_MOCK();
|
39
|
+
HandleWrap hw;
|
40
|
+
lcb_t instance;
|
41
|
+
|
42
|
+
createErrmapConnection(hw, instance);
|
43
|
+
|
44
|
+
// Test the actual error map..
|
45
|
+
using namespace lcb;
|
46
|
+
const errmap::ErrorMap& em = *instance->settings->errmap;
|
47
|
+
const errmap::Error& err = em.getError(PROTOCOL_BINARY_RESPONSE_KEY_ENOENT);
|
48
|
+
ASSERT_TRUE(err.isValid());
|
49
|
+
ASSERT_TRUE(err.hasAttribute(errmap::CONSTRAINT_FAILURE));
|
50
|
+
}
|
51
|
+
|
52
|
+
TEST_F(ErrmapUnitTest, closesOnUnrecognizedError) {
|
53
|
+
// For now, EINTERNAL is an error code we don't know!
|
54
|
+
SKIP_UNLESS_MOCK();
|
55
|
+
HandleWrap hw;
|
56
|
+
lcb_t instance;
|
57
|
+
createErrmapConnection(hw, instance);
|
58
|
+
|
59
|
+
const char *key = "key";
|
60
|
+
lcb_CMDSTORE scmd = { 0 };
|
61
|
+
LCB_CMD_SET_KEY(&scmd, key, strlen(key));
|
62
|
+
LCB_CMD_SET_VALUE(&scmd, "val", 3);
|
63
|
+
|
64
|
+
ResultCookie cookie;
|
65
|
+
lcb_install_callback3(instance, LCB_CALLBACK_STORE, opcb);
|
66
|
+
ASSERT_EQ(LCB_SUCCESS, lcb_store3(instance, &cookie, &scmd));
|
67
|
+
lcb_wait(instance);
|
68
|
+
ASSERT_EQ(LCB_SUCCESS, cookie.rc);
|
69
|
+
|
70
|
+
MockCommand cmd(MockCommand::OPFAIL);
|
71
|
+
|
72
|
+
// Determine the server
|
73
|
+
int srvix = instance->map_key(key);
|
74
|
+
|
75
|
+
cmd.set("server", srvix);
|
76
|
+
cmd.set("code", PROTOCOL_BINARY_RESPONSE_EINTERNAL); // Invalidate the connection!
|
77
|
+
cmd.set("count", 1);
|
78
|
+
doMockTxn(cmd);
|
79
|
+
|
80
|
+
cookie.reset();
|
81
|
+
ASSERT_EQ(LCB_SUCCESS, lcb_store3(instance, &cookie, &scmd));
|
82
|
+
lcb_wait(instance);
|
83
|
+
|
84
|
+
ASSERT_TRUE(cookie.called);
|
85
|
+
ASSERT_NE(LCB_SUCCESS, cookie.rc);
|
86
|
+
|
87
|
+
cookie.reset();
|
88
|
+
ASSERT_EQ(LCB_SUCCESS, lcb_store3(instance, &cookie, &scmd));
|
89
|
+
lcb_wait(instance);
|
90
|
+
ASSERT_TRUE(cookie.called);
|
91
|
+
|
92
|
+
// Note, we can't determine what the actual error here is. It would be nice
|
93
|
+
// if we were able to reconnect and retry the other commands, but right now
|
94
|
+
// detecting a failed connection is better than having no detection at all:
|
95
|
+
//
|
96
|
+
// ASSERT_EQ(LCB_SUCCESS, cookie.rc);
|
97
|
+
}
|
data/lib/libcouchbase/bucket.rb
CHANGED
@@ -24,7 +24,7 @@ module Libcouchbase
|
|
24
24
|
|
25
25
|
# This obtains the connections reactor
|
26
26
|
@reactor = reactor
|
27
|
-
@quiet =
|
27
|
+
@quiet = false
|
28
28
|
|
29
29
|
# clean up the connection once this object is garbage collected
|
30
30
|
ObjectSpace.define_finalizer( self, self.class.finalize(@connection) )
|
@@ -157,7 +157,11 @@ module Libcouchbase
|
|
157
157
|
}), async)
|
158
158
|
end
|
159
159
|
end
|
160
|
-
|
160
|
+
|
161
|
+
# Quietly obtain an object stored in Couchbase by given key.
|
162
|
+
def [](key)
|
163
|
+
get(key, quiet: true)
|
164
|
+
end
|
161
165
|
|
162
166
|
# Add the item to the database, but fail if the object exists already
|
163
167
|
#
|
@@ -495,7 +499,7 @@ module Libcouchbase
|
|
495
499
|
# res = c.set("foo", "bar") #=> #<struct Libcouchbase::Response callback=:callback_set, key="foo", cas=1975457268957184, value="bar", metadata={:format=>:document, :flags=>0}>
|
496
500
|
# c.delete("foo", cas: 123456) #=> will raise Libcouchbase::Error::KeyExists
|
497
501
|
# c.delete("foo", cas: res.cas) #=> true
|
498
|
-
def delete(key, async: false, quiet:
|
502
|
+
def delete(key, async: false, quiet: true, **opts)
|
499
503
|
promise = @connection.remove(key, **opts).then { true }
|
500
504
|
if quiet
|
501
505
|
promise = promise.catch { |error|
|
@@ -654,7 +658,7 @@ module Libcouchbase
|
|
654
658
|
# @param [String, Symbol] key
|
655
659
|
#
|
656
660
|
# @param [Hash] options the options for "swap" part
|
657
|
-
# @option options [
|
661
|
+
# @option options [Integer] :retry (0) maximum number of times to autmatically retry upon update collision
|
658
662
|
#
|
659
663
|
# @yieldparam [Object] value existing value
|
660
664
|
# @yieldreturn [Object] new value.
|
@@ -727,7 +731,7 @@ module Libcouchbase
|
|
727
731
|
@connection.reactor.next_tick do
|
728
732
|
begin
|
729
733
|
response = co(promise)
|
730
|
-
rescue => e
|
734
|
+
rescue Exception => e
|
731
735
|
error = e
|
732
736
|
end
|
733
737
|
|
@@ -738,7 +742,7 @@ module Libcouchbase
|
|
738
742
|
|
739
743
|
Fiber.yield
|
740
744
|
|
741
|
-
|
745
|
+
update_backtrace(error) if error
|
742
746
|
response
|
743
747
|
else
|
744
748
|
request = Mutex.new
|
@@ -750,7 +754,7 @@ module Libcouchbase
|
|
750
754
|
@connection.reactor.next_tick do
|
751
755
|
begin
|
752
756
|
response = co(promise)
|
753
|
-
rescue => e
|
757
|
+
rescue Exception => e
|
754
758
|
error = e
|
755
759
|
end
|
756
760
|
|
@@ -762,7 +766,7 @@ module Libcouchbase
|
|
762
766
|
result.wait(request)
|
763
767
|
}
|
764
768
|
|
765
|
-
|
769
|
+
update_backtrace(error) if error
|
766
770
|
response
|
767
771
|
end
|
768
772
|
end
|
@@ -801,7 +805,7 @@ module Libcouchbase
|
|
801
805
|
retry
|
802
806
|
end
|
803
807
|
error = e
|
804
|
-
rescue => e
|
808
|
+
rescue Exception => e
|
805
809
|
error = e
|
806
810
|
end
|
807
811
|
|
@@ -814,7 +818,7 @@ module Libcouchbase
|
|
814
818
|
result.wait(connecting)
|
815
819
|
}
|
816
820
|
|
817
|
-
|
821
|
+
update_backtrace(error) if error
|
818
822
|
end
|
819
823
|
|
820
824
|
# Assume this is being run in em-synchrony
|
@@ -838,7 +842,7 @@ module Libcouchbase
|
|
838
842
|
retry
|
839
843
|
end
|
840
844
|
error = e
|
841
|
-
rescue => e
|
845
|
+
rescue Exception => e
|
842
846
|
error = e
|
843
847
|
end
|
844
848
|
|
@@ -850,7 +854,18 @@ module Libcouchbase
|
|
850
854
|
|
851
855
|
Fiber.yield
|
852
856
|
|
853
|
-
|
857
|
+
update_backtrace(error) if error
|
858
|
+
end
|
859
|
+
|
860
|
+
def update_backtrace(error)
|
861
|
+
backtrace = caller
|
862
|
+
backtrace.shift(2)
|
863
|
+
if error.respond_to?(:backtrace) && error.backtrace
|
864
|
+
backtrace << '---- continuation ----'
|
865
|
+
backtrace.concat(error.backtrace)
|
866
|
+
end
|
867
|
+
error.set_backtrace(backtrace)
|
868
|
+
raise error
|
854
869
|
end
|
855
870
|
end
|
856
871
|
end
|
@@ -47,7 +47,7 @@ module Libcouchbase
|
|
47
47
|
|
48
48
|
def self.included(base)
|
49
49
|
base.instance_variable_set(:@callback_funcs, {})
|
50
|
-
base.instance_variable_set(:@callback_lookup, ::Concurrent::
|
50
|
+
base.instance_variable_set(:@callback_lookup, ::Concurrent::Hash.new)
|
51
51
|
base.instance_variable_set(:@callback_lock, ::Mutex.new)
|
52
52
|
base.extend(ClassMethods)
|
53
53
|
end
|
@@ -3,6 +3,15 @@
|
|
3
3
|
require 'json'
|
4
4
|
|
5
5
|
|
6
|
+
at_exit do
|
7
|
+
ObjectSpace.each_object(::Libcouchbase::Connection).each do |connection|
|
8
|
+
connection.destroy.finally do
|
9
|
+
connection.reactor.stop
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
|
6
15
|
module Libcouchbase
|
7
16
|
Response = Struct.new(:callback, :key, :cas, :value, :metadata)
|
8
17
|
HttpResponse = Struct.new(:callback, :status, :headers, :body, :request)
|
@@ -176,12 +185,16 @@ module Libcouchbase
|
|
176
185
|
# Ensure it is thread safe
|
177
186
|
@reactor.schedule {
|
178
187
|
if @handle
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
188
|
+
nodes = Ext.get_num_nodes(@handle)
|
189
|
+
list = []
|
190
|
+
count = 0
|
191
|
+
|
192
|
+
while count <= nodes
|
193
|
+
list << Ext.get_node(@handle, :node_data, count)
|
194
|
+
count += 1
|
184
195
|
end
|
196
|
+
|
197
|
+
defer.resolve(list.uniq)
|
185
198
|
else
|
186
199
|
defer.reject(RuntimeError.new('not connected'))
|
187
200
|
end
|
data/lib/libcouchbase/version.rb
CHANGED
data/spec/connection_spec.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: libcouchbase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen von Takach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -404,6 +404,8 @@ files:
|
|
404
404
|
- ext/libcouchbase/src/ctx-log-inl.h
|
405
405
|
- ext/libcouchbase/src/dns-srv.cc
|
406
406
|
- ext/libcouchbase/src/dump.cc
|
407
|
+
- ext/libcouchbase/src/errmap.cc
|
408
|
+
- ext/libcouchbase/src/errmap.h
|
407
409
|
- ext/libcouchbase/src/getconfig.cc
|
408
410
|
- ext/libcouchbase/src/gethrtime.c
|
409
411
|
- ext/libcouchbase/src/handler.cc
|
@@ -566,6 +568,7 @@ files:
|
|
566
568
|
- ext/libcouchbase/tests/iotests/t_configcache.cc
|
567
569
|
- ext/libcouchbase/tests/iotests/t_confmon.cc
|
568
570
|
- ext/libcouchbase/tests/iotests/t_durability.cc
|
571
|
+
- ext/libcouchbase/tests/iotests/t_errmap.cc
|
569
572
|
- ext/libcouchbase/tests/iotests/t_forward.cc
|
570
573
|
- ext/libcouchbase/tests/iotests/t_get.cc
|
571
574
|
- ext/libcouchbase/tests/iotests/t_http.cc
|