riak-client 2.3.0 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.document +5 -5
  3. data/Gemfile +17 -17
  4. data/Guardfile +20 -20
  5. data/LICENSE.md +16 -16
  6. data/README.markdown +1 -1
  7. data/RELEASE_NOTES.md +9 -0
  8. data/lib/riak/client/beefcake/crdt/counter_loader.rb +18 -18
  9. data/lib/riak/client/beefcake/crdt/map_loader.rb +64 -64
  10. data/lib/riak/client/beefcake/footer +4 -4
  11. data/lib/riak/client/beefcake/header +6 -6
  12. data/lib/riak/client/beefcake/messages.rb +0 -16
  13. data/lib/riak/client/decaying.rb +36 -36
  14. data/lib/riak/client/feature_detection.rb +120 -120
  15. data/lib/riak/client/instrumentation.rb +19 -19
  16. data/lib/riak/client/node.rb +49 -49
  17. data/lib/riak/client/search.rb +27 -27
  18. data/lib/riak/conflict.rb +13 -13
  19. data/lib/riak/core_ext.rb +7 -7
  20. data/lib/riak/core_ext/blank.rb +53 -53
  21. data/lib/riak/core_ext/extract_options.rb +7 -7
  22. data/lib/riak/core_ext/json.rb +15 -15
  23. data/lib/riak/core_ext/slice.rb +18 -18
  24. data/lib/riak/core_ext/stringify_keys.rb +10 -10
  25. data/lib/riak/core_ext/symbolize_keys.rb +10 -10
  26. data/lib/riak/core_ext/to_param.rb +31 -31
  27. data/lib/riak/crdt.rb +21 -21
  28. data/lib/riak/crdt/operation.rb +19 -19
  29. data/lib/riak/encoding.rb +6 -6
  30. data/lib/riak/errors/backend_creation.rb +9 -9
  31. data/lib/riak/errors/connection_error.rb +50 -50
  32. data/lib/riak/errors/protobuffs_error.rb +11 -11
  33. data/lib/riak/i18n.rb +7 -7
  34. data/lib/riak/instrumentation.rb +6 -6
  35. data/lib/riak/json.rb +52 -52
  36. data/lib/riak/list_buckets.rb +28 -28
  37. data/lib/riak/locale/fr.yml +51 -51
  38. data/lib/riak/map_reduce/results.rb +49 -49
  39. data/lib/riak/map_reduce_error.rb +7 -7
  40. data/lib/riak/multiget.rb +122 -122
  41. data/lib/riak/stamp.rb +77 -77
  42. data/lib/riak/util/tcp_socket_extensions.rb +58 -58
  43. data/lib/riak/version.rb +1 -1
  44. data/spec/failover/failover.rb +59 -59
  45. data/spec/fixtures/bitcask.txt +25 -25
  46. data/spec/fixtures/multipart-basic-conflict.txt +15 -15
  47. data/spec/fixtures/multipart-blank.txt +7 -7
  48. data/spec/fixtures/multipart-mapreduce.txt +10 -10
  49. data/spec/fixtures/multipart-with-body.txt +16 -16
  50. data/spec/fixtures/multipart-with-marked-tombstones.txt +17 -17
  51. data/spec/fixtures/multipart-with-unmarked-tombstone.txt +16 -16
  52. data/spec/fixtures/server.cert.crt +15 -15
  53. data/spec/fixtures/server.cert.key +15 -15
  54. data/spec/fixtures/test.pem +1 -1
  55. data/spec/integration/riak/threading_spec.rb +150 -150
  56. data/spec/integration/yokozuna/index_spec.rb +61 -61
  57. data/spec/integration/yokozuna/schema_spec.rb +49 -49
  58. data/spec/riak/core_ext/to_param_spec.rb +15 -15
  59. data/spec/riak/crdt/inner_counter_spec.rb +21 -21
  60. data/spec/riak/crdt/inner_set_spec.rb +33 -33
  61. data/spec/riak/crdt/set_spec.rb +61 -61
  62. data/spec/riak/escape_spec.rb +72 -72
  63. data/spec/riak/feature_detection_spec.rb +77 -77
  64. data/spec/riak/index_collection_spec.rb +53 -53
  65. data/spec/riak/instrumentation_spec.rb +124 -124
  66. data/spec/riak/link_spec.rb +85 -85
  67. data/spec/riak/list_buckets_spec.rb +41 -41
  68. data/spec/riak/node_spec.rb +26 -26
  69. data/spec/riak/stamp_spec.rb +54 -54
  70. data/spec/support/certs/README.md +12 -12
  71. data/spec/support/certs/ca.crt +21 -21
  72. data/spec/support/certs/client.crl +13 -13
  73. data/spec/support/certs/client.crt +94 -94
  74. data/spec/support/certs/client.csr +18 -18
  75. data/spec/support/certs/client.key +27 -27
  76. data/spec/support/certs/empty_ca.crt +21 -21
  77. data/spec/support/certs/server.crl +13 -13
  78. data/spec/support/certs/server.crt +94 -94
  79. data/spec/support/certs/server.key +27 -27
  80. data/spec/support/integration_setup.rb +10 -10
  81. data/spec/support/test_client.yml.example +9 -9
  82. metadata +3 -3
data/lib/riak/stamp.rb CHANGED
@@ -1,77 +1,77 @@
1
- require 'riak/client'
2
- require 'riak/util/translation'
3
- require 'thread'
4
-
5
- module Riak
6
- # Implements a client-side form of monotonically-increasing k-sorted
7
- # unique identifiers. These are useful for key generation if your
8
- # data is time-sequential and needs to be sorted by key, perhaps in
9
- # Riak Search. Inspired by Twitter's Snowflake project.
10
- class Stamp
11
- attr_reader :client
12
-
13
- CLIENT_ID_MASK = (1 << 10) - 1
14
- SEQUENCE_MASK = (1 << 12) - 1
15
- TIMESTAMP_MASK = (1 << 41) - 1
16
- SEQUENCE_SHIFT = 10
17
- TIMESTAMP_SHIFT = 22
18
-
19
- # @param [Client] client a {Riak::Client} which will be used for
20
- # the "worker ID" component of the stamp.
21
- # @see Client#stamp
22
- def initialize(client)
23
- @client = client
24
- @mutex = Mutex.new
25
- @timestamp = time_gen
26
- @sequence = 0
27
- end
28
-
29
- # Generates a k-sorted unique ID for use as a key or other
30
- # disambiguation purposes.
31
- def next
32
- @mutex.synchronize do
33
- now = time_gen
34
- if @timestamp == now
35
- @sequence = (@sequence + 1) & SEQUENCE_MASK
36
- now = wait_for_next_ms(@timestamp) if @sequence == 0
37
- else
38
- @sequence = 0
39
- end
40
-
41
- raise BackwardsClockError.new(@timestamp - now) if now < @timestamp
42
-
43
- @timestamp = now
44
- @timestamp << TIMESTAMP_SHIFT | @sequence << SEQUENCE_SHIFT | client_id
45
- end
46
- end
47
-
48
- private
49
- def client_id
50
- case id = @client.client_id
51
- when Integer
52
- id & CLIENT_ID_MASK
53
- else
54
- id.hash & CLIENT_ID_MASK
55
- end
56
- end
57
-
58
- def time_gen
59
- (Time.now.to_f * 1000).floor & TIMESTAMP_MASK
60
- end
61
-
62
- def wait_for_next_ms(start)
63
- now = time_gen
64
- now = time_gen while now <= start
65
- now
66
- end
67
- end
68
-
69
- # Raised when calling {Stamp#next} and NTP or some other external
70
- # event has moved the system clock backwards.
71
- class BackwardsClockError < StandardError
72
- include Util::Translation
73
- def initialize(delay)
74
- super t('backwards_clock', :delay => delay)
75
- end
76
- end
77
- end
1
+ require 'riak/client'
2
+ require 'riak/util/translation'
3
+ require 'thread'
4
+
5
+ module Riak
6
+ # Implements a client-side form of monotonically-increasing k-sorted
7
+ # unique identifiers. These are useful for key generation if your
8
+ # data is time-sequential and needs to be sorted by key, perhaps in
9
+ # Riak Search. Inspired by Twitter's Snowflake project.
10
+ class Stamp
11
+ attr_reader :client
12
+
13
+ CLIENT_ID_MASK = (1 << 10) - 1
14
+ SEQUENCE_MASK = (1 << 12) - 1
15
+ TIMESTAMP_MASK = (1 << 41) - 1
16
+ SEQUENCE_SHIFT = 10
17
+ TIMESTAMP_SHIFT = 22
18
+
19
+ # @param [Client] client a {Riak::Client} which will be used for
20
+ # the "worker ID" component of the stamp.
21
+ # @see Client#stamp
22
+ def initialize(client)
23
+ @client = client
24
+ @mutex = Mutex.new
25
+ @timestamp = time_gen
26
+ @sequence = 0
27
+ end
28
+
29
+ # Generates a k-sorted unique ID for use as a key or other
30
+ # disambiguation purposes.
31
+ def next
32
+ @mutex.synchronize do
33
+ now = time_gen
34
+ if @timestamp == now
35
+ @sequence = (@sequence + 1) & SEQUENCE_MASK
36
+ now = wait_for_next_ms(@timestamp) if @sequence == 0
37
+ else
38
+ @sequence = 0
39
+ end
40
+
41
+ raise BackwardsClockError.new(@timestamp - now) if now < @timestamp
42
+
43
+ @timestamp = now
44
+ @timestamp << TIMESTAMP_SHIFT | @sequence << SEQUENCE_SHIFT | client_id
45
+ end
46
+ end
47
+
48
+ private
49
+ def client_id
50
+ case id = @client.client_id
51
+ when Integer
52
+ id & CLIENT_ID_MASK
53
+ else
54
+ id.hash & CLIENT_ID_MASK
55
+ end
56
+ end
57
+
58
+ def time_gen
59
+ (Time.now.to_f * 1000).floor & TIMESTAMP_MASK
60
+ end
61
+
62
+ def wait_for_next_ms(start)
63
+ now = time_gen
64
+ now = time_gen while now <= start
65
+ now
66
+ end
67
+ end
68
+
69
+ # Raised when calling {Stamp#next} and NTP or some other external
70
+ # event has moved the system clock backwards.
71
+ class BackwardsClockError < StandardError
72
+ include Util::Translation
73
+ def initialize(delay)
74
+ super t('backwards_clock', :delay => delay)
75
+ end
76
+ end
77
+ end
@@ -1,58 +1,58 @@
1
- require 'time'
2
- require 'timeout'
3
- require 'socket'
4
-
5
- # Borrowed from Webrat and Selenium client, watches for TCP port
6
- # liveness of the spawned server.
7
- # @private
8
- class TCPSocket
9
- def self.wait_for_service(options)
10
- verbose_wait until listening_service?(options)
11
- end
12
-
13
- def self.wait_for_service_termination(options)
14
- verbose_wait while listening_service?(options)
15
- end
16
-
17
- def self.listening_service?(options)
18
- Timeout::timeout(options[:timeout] || 20) do
19
- begin
20
- socket = TCPSocket.new(options[:host], options[:port])
21
- socket.close unless socket.nil?
22
- true
23
- rescue Errno::ECONNREFUSED,
24
- Errno::EBADF # Windows
25
- false
26
- end
27
- end
28
- end
29
-
30
- def self.verbose_wait
31
- # Removed the puts call so as not to clutter up test output.
32
- sleep 2
33
- end
34
-
35
- def self.wait_for_service_with_timeout(options)
36
- start_time = Time.now
37
-
38
- until listening_service?(options)
39
- verbose_wait
40
-
41
- if options[:timeout] && (Time.now > start_time + options[:timeout])
42
- raise SocketError.new("Socket did not open within #{options[:timeout]} seconds")
43
- end
44
- end
45
- end
46
-
47
- def self.wait_for_service_termination_with_timeout(options)
48
- start_time = Time.now
49
-
50
- while listening_service?(options)
51
- verbose_wait
52
-
53
- if options[:timeout] && (Time.now > start_time + options[:timeout])
54
- raise SocketError.new("Socket did not terminate within #{options[:timeout]} seconds")
55
- end
56
- end
57
- end
58
- end
1
+ require 'time'
2
+ require 'timeout'
3
+ require 'socket'
4
+
5
+ # Borrowed from Webrat and Selenium client, watches for TCP port
6
+ # liveness of the spawned server.
7
+ # @private
8
+ class TCPSocket
9
+ def self.wait_for_service(options)
10
+ verbose_wait until listening_service?(options)
11
+ end
12
+
13
+ def self.wait_for_service_termination(options)
14
+ verbose_wait while listening_service?(options)
15
+ end
16
+
17
+ def self.listening_service?(options)
18
+ Timeout::timeout(options[:timeout] || 20) do
19
+ begin
20
+ socket = TCPSocket.new(options[:host], options[:port])
21
+ socket.close unless socket.nil?
22
+ true
23
+ rescue Errno::ECONNREFUSED,
24
+ Errno::EBADF # Windows
25
+ false
26
+ end
27
+ end
28
+ end
29
+
30
+ def self.verbose_wait
31
+ # Removed the puts call so as not to clutter up test output.
32
+ sleep 2
33
+ end
34
+
35
+ def self.wait_for_service_with_timeout(options)
36
+ start_time = Time.now
37
+
38
+ until listening_service?(options)
39
+ verbose_wait
40
+
41
+ if options[:timeout] && (Time.now > start_time + options[:timeout])
42
+ raise SocketError.new("Socket did not open within #{options[:timeout]} seconds")
43
+ end
44
+ end
45
+ end
46
+
47
+ def self.wait_for_service_termination_with_timeout(options)
48
+ start_time = Time.now
49
+
50
+ while listening_service?(options)
51
+ verbose_wait
52
+
53
+ if options[:timeout] && (Time.now > start_time + options[:timeout])
54
+ raise SocketError.new("Socket did not terminate within #{options[:timeout]} seconds")
55
+ end
56
+ end
57
+ end
58
+ end
data/lib/riak/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Riak
2
- VERSION = "2.3.0"
2
+ VERSION = "2.3.1"
3
3
  end
@@ -1,59 +1,59 @@
1
- $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../../lib')
2
- require 'riak'
3
-
4
- # This is not a formal spec yet. It's designed to be run agains a local dev
5
- # cluster while you bring nodes up and down.
6
- [
7
- {:protocol => 'pbc', :protobuffs_backend => :Beefcake},
8
- {:protocol => 'http', :http_backend => :NetHTTP},
9
- {:protocol => 'http', :http_backend => :Excon}
10
- ].each do |opts|
11
- @client = Riak::Client.new(
12
- {
13
- :nodes => (1..3).map { |i|
14
- {
15
- :http_port => 8090 + i,
16
- :pb_port => 8080 + i
17
- }
18
- }
19
- }.merge(opts)
20
- )
21
-
22
- errors = []
23
- p opts
24
-
25
- n = 10
26
- c = 1000
27
-
28
- (0...n).map do |t|
29
- Thread.new do
30
- # Generate a stream of put reqs. Put a . for each success, an X for
31
- # each failure.
32
- c.times do |i|
33
- begin
34
- o = @client['test'].new("#{t}:#{i}")
35
- o.content_type = 'text/plain'
36
- o.data = i.to_s
37
- o.store
38
- o2 = @client['test'].get("#{t}:#{i}")
39
- o2.data == i.to_s or raise "wrong data"
40
- print '.'
41
- rescue => e
42
- print 'X'
43
- errors << e
44
- end
45
- end
46
- end
47
- end.each do |thread|
48
- thread.join
49
- end
50
-
51
- # Put errors
52
- puts
53
- errors.each do |e|
54
- puts e.inspect
55
- puts e.backtrace.map { |x| " #{x}" }.join("\n")
56
- end
57
-
58
- puts "\n\n"
59
- end
1
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../../lib')
2
+ require 'riak'
3
+
4
+ # This is not a formal spec yet. It's designed to be run agains a local dev
5
+ # cluster while you bring nodes up and down.
6
+ [
7
+ {:protocol => 'pbc', :protobuffs_backend => :Beefcake},
8
+ {:protocol => 'http', :http_backend => :NetHTTP},
9
+ {:protocol => 'http', :http_backend => :Excon}
10
+ ].each do |opts|
11
+ @client = Riak::Client.new(
12
+ {
13
+ :nodes => (1..3).map { |i|
14
+ {
15
+ :http_port => 8090 + i,
16
+ :pb_port => 8080 + i
17
+ }
18
+ }
19
+ }.merge(opts)
20
+ )
21
+
22
+ errors = []
23
+ p opts
24
+
25
+ n = 10
26
+ c = 1000
27
+
28
+ (0...n).map do |t|
29
+ Thread.new do
30
+ # Generate a stream of put reqs. Put a . for each success, an X for
31
+ # each failure.
32
+ c.times do |i|
33
+ begin
34
+ o = @client['test'].new("#{t}:#{i}")
35
+ o.content_type = 'text/plain'
36
+ o.data = i.to_s
37
+ o.store
38
+ o2 = @client['test'].get("#{t}:#{i}")
39
+ o2.data == i.to_s or raise "wrong data"
40
+ print '.'
41
+ rescue => e
42
+ print 'X'
43
+ errors << e
44
+ end
45
+ end
46
+ end
47
+ end.each do |thread|
48
+ thread.join
49
+ end
50
+
51
+ # Put errors
52
+ puts
53
+ errors.each do |e|
54
+ puts e.inspect
55
+ puts e.backtrace.map { |x| " #{x}" }.join("\n")
56
+ end
57
+
58
+ puts "\n\n"
59
+ end
@@ -1,25 +1,25 @@
1
- Bitcask is an Erlang application that provides an API for storing and retrieving key/value data into a log-structured hash table that provides very fast access. The design owes a lot to the principles found in log-structured file systems and draws inspiration from a number of designs that involve log file merging.
2
-
3
- Strengths
4
- Low latency per item read or written
5
- This is due to the write-once, append-only nature of the Bitcask database files. High throughput, especially when writing an incoming stream of random items Because the data being written doesn't need to be ordered on disk and because the log structured design allows for minimal disk head movement during writes these operations generally saturate the I/O and disk bandwidth.
6
-
7
- Ability to handle datasets larger than RAM w/o degradation
8
- Because access to data in Bitcask is direct lookup from an in-memory hash table finding data on disk is very efficient, even when data sets are very large.
9
-
10
- Single Seek to Retrieve Any Value
11
- Bitcask's in-memory hash-table of keys point directly to locations on disk where the data lives. Bitcask never uses more than one disk seek to read a value and sometimes, due to file-system caching done by the operating system, even that isn't necessary.
12
-
13
- Predictable Lookup and Insert Performance
14
- As you might expect from the description above, read operations have a fixed, predictable behavior. What you might not expect is that this is also true for writes. Write operations are at most a seek to the end of the current file open writing and an append to that file.
15
-
16
- Fast, bounded Crash Recovery
17
- Due to the append-only write once nature of Bitcask files, recovery is easy and fast. The only items that might be lost are partially written records at the tail of the file last opened for writes. Recovery need only review the last record or two written and verify CRC data to ensure that the data is consistent.
18
-
19
- Easy Backup
20
- In most systems backup can be very complicated but here again Bitcask simplifies this process due to its append-only write once disk format. Any utility that archives or copies files in disk-block order will properly backup or copy a Bitcask database.
21
-
22
- Weakness
23
- Keys Must Fit In Memory
24
- Bitcask keeps all keys in memory at all times, this means that your system must have enough memory to contain your entire keyspace with room for other operational components and operating system resident filesystem buffer space.
25
-
1
+ Bitcask is an Erlang application that provides an API for storing and retrieving key/value data into a log-structured hash table that provides very fast access. The design owes a lot to the principles found in log-structured file systems and draws inspiration from a number of designs that involve log file merging.
2
+
3
+ Strengths
4
+ Low latency per item read or written
5
+ This is due to the write-once, append-only nature of the Bitcask database files. High throughput, especially when writing an incoming stream of random items Because the data being written doesn't need to be ordered on disk and because the log structured design allows for minimal disk head movement during writes these operations generally saturate the I/O and disk bandwidth.
6
+
7
+ Ability to handle datasets larger than RAM w/o degradation
8
+ Because access to data in Bitcask is direct lookup from an in-memory hash table finding data on disk is very efficient, even when data sets are very large.
9
+
10
+ Single Seek to Retrieve Any Value
11
+ Bitcask's in-memory hash-table of keys point directly to locations on disk where the data lives. Bitcask never uses more than one disk seek to read a value and sometimes, due to file-system caching done by the operating system, even that isn't necessary.
12
+
13
+ Predictable Lookup and Insert Performance
14
+ As you might expect from the description above, read operations have a fixed, predictable behavior. What you might not expect is that this is also true for writes. Write operations are at most a seek to the end of the current file open writing and an append to that file.
15
+
16
+ Fast, bounded Crash Recovery
17
+ Due to the append-only write once nature of Bitcask files, recovery is easy and fast. The only items that might be lost are partially written records at the tail of the file last opened for writes. Recovery need only review the last record or two written and verify CRC data to ensure that the data is consistent.
18
+
19
+ Easy Backup
20
+ In most systems backup can be very complicated but here again Bitcask simplifies this process due to its append-only write once disk format. Any utility that archives or copies files in disk-block order will properly backup or copy a Bitcask database.
21
+
22
+ Weakness
23
+ Keys Must Fit In Memory
24
+ Bitcask keeps all keys in memory at all times, this means that your system must have enough memory to contain your entire keyspace with room for other operational components and operating system resident filesystem buffer space.
25
+
@@ -1,15 +1,15 @@
1
- --8XZD3w6ttFTHIz6LCmhVxn9Ex0K
2
- Content-Type: text/plain
3
- Link: </buckets/test>; rel="up"
4
- Etag: 2baUwethOoLrVkwnMqzBRW
5
- Last-Modified: Mon, 15 Oct 2012 19:36:06 GMT
6
-
7
- bar
8
- --8XZD3w6ttFTHIz6LCmhVxn9Ex0K
9
- Content-Type: text/plain
10
- Link: </buckets/test>; rel="up"
11
- Etag: 6NtlHf8Lc3TEcCTKOVqEkl
12
- Last-Modified: Mon, 15 Oct 2012 19:35:57 GMT
13
-
14
- foo
15
- --8XZD3w6ttFTHIz6LCmhVxn9Ex0K--
1
+ --8XZD3w6ttFTHIz6LCmhVxn9Ex0K
2
+ Content-Type: text/plain
3
+ Link: </buckets/test>; rel="up"
4
+ Etag: 2baUwethOoLrVkwnMqzBRW
5
+ Last-Modified: Mon, 15 Oct 2012 19:36:06 GMT
6
+
7
+ bar
8
+ --8XZD3w6ttFTHIz6LCmhVxn9Ex0K
9
+ Content-Type: text/plain
10
+ Link: </buckets/test>; rel="up"
11
+ Etag: 6NtlHf8Lc3TEcCTKOVqEkl
12
+ Last-Modified: Mon, 15 Oct 2012 19:35:57 GMT
13
+
14
+ foo
15
+ --8XZD3w6ttFTHIz6LCmhVxn9Ex0K--