libcouchbase 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -4
  3. data/README.md +4 -0
  4. data/ext/libcouchbase/CMakeLists.txt +1 -1
  5. data/ext/libcouchbase/RELEASE_NOTES.markdown +42 -0
  6. data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
  7. data/ext/libcouchbase/cmake/source_files.cmake +1 -0
  8. data/ext/libcouchbase/include/libcouchbase/cntl.h +27 -1
  9. data/ext/libcouchbase/include/libcouchbase/couchbase.h +0 -10
  10. data/ext/libcouchbase/include/libcouchbase/error.h +8 -1
  11. data/ext/libcouchbase/include/memcached/protocol_binary.h +12 -3
  12. data/ext/libcouchbase/src/auth.cc +0 -4
  13. data/ext/libcouchbase/src/cntl.cc +11 -1
  14. data/ext/libcouchbase/src/connspec.cc +18 -0
  15. data/ext/libcouchbase/src/connspec.h +10 -0
  16. data/ext/libcouchbase/src/dns-srv.cc +13 -14
  17. data/ext/libcouchbase/src/errmap.cc +107 -0
  18. data/ext/libcouchbase/src/errmap.h +113 -0
  19. data/ext/libcouchbase/src/hostlist.cc +0 -35
  20. data/ext/libcouchbase/src/hostlist.h +38 -64
  21. data/ext/libcouchbase/src/http/http.cc +6 -1
  22. data/ext/libcouchbase/src/instance.cc +1 -1
  23. data/ext/libcouchbase/src/internal.h +10 -0
  24. data/ext/libcouchbase/src/mcserver/mcserver.cc +119 -3
  25. data/ext/libcouchbase/src/mcserver/mcserver.h +3 -1
  26. data/ext/libcouchbase/src/mcserver/negotiate.cc +130 -37
  27. data/ext/libcouchbase/src/nodeinfo.cc +1 -1
  28. data/ext/libcouchbase/src/settings.c +3 -0
  29. data/ext/libcouchbase/src/settings.h +5 -0
  30. data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
  31. data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
  32. data/ext/libcouchbase/tests/iotests/mock-environment.h +2 -1
  33. data/ext/libcouchbase/tests/iotests/t_confmon.cc +3 -4
  34. data/ext/libcouchbase/tests/iotests/t_errmap.cc +97 -0
  35. data/lib/libcouchbase/bucket.rb +27 -12
  36. data/lib/libcouchbase/callbacks.rb +1 -1
  37. data/lib/libcouchbase/connection.rb +18 -5
  38. data/lib/libcouchbase/version.rb +1 -1
  39. data/spec/connection_spec.rb +1 -1
  40. metadata +5 -2
@@ -71,7 +71,8 @@ class MockCommand
71
71
  X(GET_MCPORTS) \
72
72
  X(SET_CCCP) \
73
73
  X(REGEN_VBCOORDS) \
74
- X(RESET_QUERYSTATE)
74
+ X(RESET_QUERYSTATE) \
75
+ X(OPFAIL)
75
76
 
76
77
  public:
77
78
  enum Code {
@@ -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
- hostlist_t hl = hostlist_create();
145
- hostlist_add_stringz(hl, cropts.v.v2.mchosts, 11210);
144
+ lcb::Hostlist hl;
145
+ hl.add(cropts.v.v2.mchosts, 11210);
146
146
  cccp->enable(instance);
147
- cccp->configure_nodes(*hl);
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
+ }
@@ -24,7 +24,7 @@ module Libcouchbase
24
24
 
25
25
  # This obtains the connections reactor
26
26
  @reactor = reactor
27
- @quiet = true
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
- alias_method :[], :get
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: @quiet, **opts)
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 [Fixnum] :retry (0) maximum number of times to autmatically retry upon update collision
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
- raise error if error
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
- raise error if error
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
- raise error if error
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
- raise error if error
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::Map.new)
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
- resp = Ext.get_server_list(@handle)
180
- if resp.null?
181
- defer.reject(RuntimeError.new('not connected'))
182
- else
183
- defer.resolve(resp.get_array_of_string(0))
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true, encoding: ASCII-8BIT
2
2
 
3
3
  module Libcouchbase
4
- VERSION = '0.0.9'
4
+ VERSION = '0.1.0'
5
5
  end
@@ -157,7 +157,7 @@ describe Libcouchbase::Connection do
157
157
  end
158
158
  }
159
159
 
160
- expect(@log).to eq(['127.0.0.1:8091'])
160
+ expect(@log).to eq(['127.0.0.1:11210'])
161
161
  end
162
162
 
163
163
  it "should support counter operations" do
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.9
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-03 00:00:00.000000000 Z
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