aerospike 0.1.3 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,7 +14,7 @@
14
14
  # License for the specific language governing permissions and limitations under
15
15
  # the License.
16
16
 
17
- require 'atomic'
17
+ require 'aerospike/atomic/atomic'
18
18
 
19
19
  module Aerospike
20
20
 
@@ -63,6 +63,8 @@ module Aerospike
63
63
  begin
64
64
  info_map = Info.request(conn, "node", "partition-generation", "services")
65
65
  rescue => e
66
+ Aerospike.logger.error(e)
67
+
66
68
  conn.close
67
69
  decrease_health
68
70
 
@@ -31,7 +31,6 @@ module Aerospike
31
31
 
32
32
  @valid = true
33
33
  @mutex = Mutex.new
34
- @records = Queue.new
35
34
 
36
35
  self
37
36
  end
@@ -79,13 +78,82 @@ module Aerospike
79
78
  when Aerospike::FieldType::TABLE
80
79
  set_name = @data_buffer.read(1, size).force_encoding('utf-8')
81
80
  when Aerospike::FieldType::KEY
82
- user_key = Value.bytes_to_key_value(@data_buffer.read(1).ord, @data_buffer, 2, size-1)
81
+ user_key = Aerospike::bytes_to_key_value(@data_buffer.read(1).ord, @data_buffer, 2, size-1)
83
82
  end
84
83
  end
85
84
 
86
85
  Aerospike::Key.new(namespace, set_name, user_key, digest)
87
86
  end
88
87
 
88
+ # Parses the given byte buffer and populate the result object.
89
+ # Returns the number of bytes that were parsed from the given buffer.
90
+ def parse_record(key, op_count, generation, expiration)
91
+ bins = nil
92
+ duplicates = nil
93
+
94
+ for i in 0...op_count
95
+ raise Aerospike::Exceptions::QueryTerminated.new unless valid?
96
+
97
+ read_bytes(8)
98
+
99
+ op_size = @data_buffer.read_int32(0).ord
100
+ particle_type = @data_buffer.read(5).ord
101
+ version = @data_buffer.read(6).ord
102
+ name_size = @data_buffer.read(7).ord
103
+
104
+ read_bytes(name_size)
105
+ name = @data_buffer.read(0, name_size).force_encoding('utf-8')
106
+
107
+ particle_bytes_size = op_size - (4 + name_size)
108
+ read_bytes(particle_bytes_size)
109
+ value = Aerospike.bytes_to_particle(particle_type, @data_buffer, 0, particle_bytes_size)
110
+
111
+ # Currently, the batch command returns all the bins even if a subset of
112
+ # the bins are requested. We have to filter it on the client side.
113
+ # TODO: Filter batch bins on server!
114
+ # if !@bin_names || @bin_names.any?{|bn| bn == name}
115
+ # if !@bin_names || (@bin_names == []) || @bin_names.any?{|bn| bn == name}
116
+ if !@bin_names || (@bin_names.empty?) || @bin_names.any?{|bn| bn == name}
117
+
118
+ vmap = nil
119
+
120
+ if version > 0 || duplicates
121
+ unless duplicates
122
+ duplicates = []
123
+ duplicates << bins
124
+ bins = nil
125
+
126
+ for j in 0...version
127
+ duplicates << nil
128
+ end
129
+ else
130
+ for j in duplicates.length..version
131
+ duplicates << nil
132
+ end
133
+ end
134
+
135
+ vmap = duplicates[version]
136
+ unless vmap
137
+ vmap = {}
138
+ duplicates[version] = vmap
139
+ end
140
+ else
141
+ unless bins
142
+ bins = {}
143
+ end
144
+ vmap = bins
145
+ end
146
+ vmap[name] = value
147
+ end
148
+ end
149
+
150
+ # Remove nil duplicates just in case there were holes in the version number space.
151
+ # TODO: this seems to be a bad idea; O(n) algorithm after another O(n) algorithm
152
+ duplicates.compact! if duplicates
153
+
154
+ Record.new(@node, key, bins, duplicates, generation, expiration)
155
+ end
156
+
89
157
  def read_bytes(length)
90
158
  if length > @data_buffer.length
91
159
  # Corrupted data streams can result in a huge length.
@@ -79,72 +79,6 @@ module Aerospike
79
79
  true
80
80
  end
81
81
 
82
- # Parses the given byte buffer and populate the result object.
83
- # Returns the number of bytes that were parsed from the given buffer.
84
- def parse_record(key, op_count, generation, expiration)
85
- bins = nil
86
- duplicates = nil
87
-
88
- for i in 0...op_count
89
- raise Aerospike::Exceptions::QueryTerminated.new unless valid?
90
-
91
- read_bytes(8)
92
-
93
- op_size = @data_buffer.read_int32(0).ord
94
- particle_type = @data_buffer.read(5).ord
95
- version = @data_buffer.read(6).ord
96
- name_size = @data_buffer.read(7).ord
97
-
98
- read_bytes(name_size)
99
- name = @data_buffer.read(0, name_size).force_encoding('utf-8')
100
-
101
- particle_bytes_size = op_size - (4 + name_size)
102
- read_bytes(particle_bytes_size)
103
- value = Aerospike.bytes_to_particle(particle_type, @data_buffer, 0, particle_bytes_size)
104
-
105
- # Currently, the batch command returns all the bins even if a subset of
106
- # the bins are requested. We have to filter it on the client side.
107
- # TODO: Filter batch bins on server!
108
- if !@bin_names || @bin_names.any?{|bn| bn == name}
109
- vmap = nil
110
-
111
- if version > 0 || duplicates
112
- unless duplicates
113
- duplicates = []
114
- duplicates << bins
115
- bins = nil
116
-
117
- for j in 0...version
118
- duplicates << nil
119
- end
120
- else
121
- for j in duplicates.length..version
122
- duplicates << nil
123
- end
124
- end
125
-
126
- vmap = duplicates[version]
127
- unless vmap
128
- vmap = {}
129
- duplicates[version] = vmap
130
- end
131
- else
132
- unless bins
133
- bins = {}
134
- end
135
- vmap = bins
136
- end
137
- vmap[name] = value
138
- end
139
- end
140
-
141
- # Remove nil duplicates just in case there were holes in the version number space.
142
- # TODO: this seems to be a bad idea; O(n) algorithm after another O(n) algorithm
143
- duplicates.compact! if duplicates
144
-
145
- Record.new(@node, key, bins, duplicates, generation, expiration)
146
- end
147
-
148
82
  end # class
149
83
 
150
84
  end # module
@@ -314,6 +314,75 @@ module Aerospike
314
314
  end_cmd
315
315
  end
316
316
 
317
+ def set_scan(policy, namespace, set_name, bin_names)
318
+ # Estimate buffer size
319
+ begin_cmd
320
+ field_count = 0
321
+
322
+ if namespace
323
+ @data_offset += namespace.bytesize + FIELD_HEADER_SIZE
324
+ field_count += 1
325
+ end
326
+
327
+ if set_name
328
+ @data_offset += set_name.bytesize + FIELD_HEADER_SIZE
329
+ field_count += 1
330
+ end
331
+
332
+ # Estimate scan options size.
333
+ @data_offset += 2 + FIELD_HEADER_SIZE
334
+ field_count += 1
335
+
336
+ if bin_names
337
+ bin_names.each do |bin_name|
338
+ estimate_operation_size_for_bin_name(bin_name)
339
+ end
340
+ end
341
+
342
+ size_buffer
343
+ read_attr = INFO1_READ
344
+
345
+ if !policy.include_bin_data
346
+ read_attr |= INFO1_NOBINDATA
347
+ end
348
+
349
+ operation_count = 0
350
+ if bin_names
351
+ operation_count = bin_names.length
352
+ end
353
+
354
+ write_header(read_attr, 0, field_count, operation_count)
355
+
356
+ if namespace
357
+ write_field_string(namespace, Aerospike::FieldType::NAMESPACE)
358
+ end
359
+
360
+ if set_name
361
+ write_field_string(set_name, Aerospike::FieldType::TABLE)
362
+ end
363
+
364
+ write_field_header(2, Aerospike::FieldType::SCAN_OPTIONS)
365
+
366
+ priority = policy.priority & 0xFF
367
+ priority <<= 4
368
+ if policy.fail_on_cluster_change
369
+ priority |= 0x08
370
+ end
371
+
372
+ @data_buffer.write_byte(priority, @data_offset)
373
+ @data_offset += 1
374
+ @data_buffer.write_byte(policy.scan_percent.to_i.ord, @data_offset)
375
+ @data_offset += 1
376
+
377
+ if bin_names
378
+ bin_names.each do |bin_name|
379
+ write_operation_for_bin_name(bin_name, Aerospike::Operation::READ)
380
+ end
381
+ end
382
+
383
+ end_cmd
384
+ end
385
+
317
386
  def execute
318
387
  iterations = 0
319
388
 
@@ -338,7 +407,7 @@ module Aerospike
338
407
  # Socket connection error has occurred. Decrease health and retry.
339
408
  @node.decrease_health
340
409
 
341
- Aerospike.logger.warn("Node #{@node.to_s}: #{e}")
410
+ Aerospike.logger.error("Node #{@node.to_s}: #{e}")
342
411
  next
343
412
  end
344
413
 
@@ -350,6 +419,8 @@ module Aerospike
350
419
  begin
351
420
  write_buffer
352
421
  rescue => e
422
+ Aerospike.logger.error(e)
423
+
353
424
  # All runtime exceptions are considered fatal. Do not retry.
354
425
  # Close socket to flush out possible garbage. Do not put back in pool.
355
426
  @conn.close
@@ -367,7 +438,7 @@ module Aerospike
367
438
  # Close socket to flush out possible garbage. Do not put back in pool.
368
439
  @conn.close
369
440
 
370
- Aerospike.logger.warn("Node #{@node.to_s}: #{e}")
441
+ Aerospike.logger.error("Node #{@node.to_s}: #{e}")
371
442
  # IO error means connection to server @node is unhealthy.
372
443
  # Reflect cmd status.
373
444
  @node.decrease_health
@@ -378,6 +449,8 @@ module Aerospike
378
449
  begin
379
450
  parse_result
380
451
  rescue => e
452
+ Aerospike.logger.error(e)
453
+
381
454
  # close the connection
382
455
  # cancelling/closing the batch/multi commands will return an error, which will
383
456
  # close the connection to throw away its data and signal the server about the
@@ -411,16 +484,16 @@ module Aerospike
411
484
  field_count = 0
412
485
 
413
486
  if key.namespace
414
- @data_offset += key.namespace.length + FIELD_HEADER_SIZE
487
+ @data_offset += key.namespace.bytesize + FIELD_HEADER_SIZE
415
488
  field_count += 1
416
489
  end
417
490
 
418
491
  if key.set_name
419
- @data_offset += key.set_name.length + FIELD_HEADER_SIZE
492
+ @data_offset += key.set_name.bytesize + FIELD_HEADER_SIZE
420
493
  field_count += 1
421
494
  end
422
495
 
423
- @data_offset += key.digest.length + FIELD_HEADER_SIZE
496
+ @data_offset += key.digest.bytesize + FIELD_HEADER_SIZE
424
497
  field_count += 1
425
498
 
426
499
  return field_count
@@ -434,7 +507,7 @@ module Aerospike
434
507
  end
435
508
 
436
509
  def estimate_operation_size_for_bin(bin)
437
- @data_offset += bin.name.length + OPERATION_HEADER_SIZE
510
+ @data_offset += bin.name.bytesize + OPERATION_HEADER_SIZE
438
511
  @data_offset += bin.value_object.estimate_size
439
512
  end
440
513
 
@@ -442,7 +515,7 @@ module Aerospike
442
515
  bin_len = 0
443
516
 
444
517
  if operation.bin_name
445
- bin_len = operation.bin_name.length
518
+ bin_len = operation.bin_name.bytesize
446
519
  end
447
520
 
448
521
  @data_offset += bin_len + OPERATION_HEADER_SIZE
@@ -453,7 +526,7 @@ module Aerospike
453
526
  end
454
527
 
455
528
  def estimate_operation_size_for_bin_name(bin_name)
456
- @data_offset += bin_name.length + OPERATION_HEADER_SIZE
529
+ @data_offset += bin_name.bytesize + OPERATION_HEADER_SIZE
457
530
  end
458
531
 
459
532
  def estimate_operation_size
@@ -68,7 +68,7 @@ module Aerospike
68
68
  begin
69
69
  @conn.read(@data_buffer, receive_size)
70
70
  rescue => e
71
- Aerospike.logger.warn("parse result error: #{e}")
71
+ Aerospike.logger.error("parse result error: #{e}")
72
72
  raise e
73
73
  end
74
74
 
@@ -82,7 +82,7 @@ module Aerospike
82
82
  @record = parse_record(op_count, field_count, generation, expiration)
83
83
  handle_udf_error(result_code)
84
84
  rescue => e
85
- Aerospike.logger.warn("UDF execution error: #{e}")
85
+ Aerospike.logger.error("UDF execution error: #{e}")
86
86
  raise e
87
87
  end
88
88
 
@@ -49,7 +49,7 @@ module Aerospike
49
49
  begin
50
50
  @conn.read(@data_buffer, receive_size)
51
51
  rescue => e
52
- Aerospike.logger.error("#{e}")
52
+ Aerospike.logger.error(e)
53
53
  raise e
54
54
  end
55
55
  end
@@ -42,7 +42,7 @@ module Aerospike
42
42
  begin
43
43
  @conn.read(@data_buffer, MSG_TOTAL_HEADER_SIZE)
44
44
  rescue => e
45
- Aerospike.logger.error("#{e}")
45
+ Aerospike.logger.error(e)
46
46
  raise e
47
47
  end
48
48
 
@@ -49,8 +49,6 @@ module Aerospike
49
49
  begin
50
50
  buf_length = send_command(conn, offset, buffer)
51
51
  parse_multiple_response(buf_length, buffer)
52
- rescue => e
53
- Aerospike.logger.error("#{e}")
54
52
  ensure
55
53
  Buffer.put(buffer)
56
54
  end
@@ -86,6 +84,7 @@ module Aerospike
86
84
  conn.read(buffer, length)
87
85
  return length
88
86
  rescue => e
87
+ Aerospike.logger.error(e)
89
88
  conn.close
90
89
  raise e
91
90
  end
@@ -70,6 +70,7 @@ module Aerospike
70
70
  @client.execute_udf(@key, @PACKAGE_NAME, 'find', [@bin_name, value], @policy)
71
71
  rescue Aerospike::Exceptions::Aerospike => e
72
72
  unless e.result_code == Aerospike::ResultCode::UDF_BAD_RESPONSE && e.message.index("Item Not Found")
73
+ Aerospike.logger.error(e)
73
74
  raise e
74
75
  end
75
76
  nil
@@ -54,6 +54,7 @@ module Aerospike
54
54
  @client.execute_udf(@key, @PACKAGE_NAME, 'get', [@bin_name, name, @user_module], @policy)
55
55
  rescue Aerospike::Exceptions::Aerospike => e
56
56
  unless e.result_code == Aerospike::ResultCode::UDF_BAD_RESPONSE && e.message.index("Item Not Found")
57
+ Aerospike.logger.error(e)
57
58
  raise e
58
59
  end
59
60
  nil
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ # Copyright 2014 Aerospike, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http:#www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'aerospike/policy/policy'
17
+
18
+ module Aerospike
19
+
20
+ # Container object for batch policy command.
21
+ class BatchPolicy < Policy
22
+
23
+ attr_accessor :max_concurrent_nodes, :record_queue_size,
24
+ :wait_until_migrations_are_over
25
+
26
+ def initialize(max_concurrent_nodes=nil, record_queue_size=nil, wait_until_migrations_are_over=nil)
27
+ super()
28
+
29
+ @max_concurrent_nodes = max_concurrent_nodes || 0
30
+ @record_queue_size = record_queue_size || 5000
31
+ @wait_until_migrations_are_over = wait_until_migrations_are_over.nil? ? false : wait_until_migrations_are_over
32
+
33
+ self
34
+ end
35
+
36
+ end # class
37
+
38
+ end # module