aerospike 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9637e861d9aa3e0f0a4f7291877deabb198f7390
4
- data.tar.gz: cd148fc3d987d2976a1a977b7212c113dd626dc8
3
+ metadata.gz: 29590c28263bbb25b84e0856deaa101c53e6e1b1
4
+ data.tar.gz: c737c8347a770a959c53d9677346761d0c6f0fcc
5
5
  SHA512:
6
- metadata.gz: 6598cb2fc4b8f5d4cfa1c8f052b1694314d32330bea1a98735310a28be4e71eef1e8f93973e85bdf795ccd734e1d94d44642376dab7fbf0b2bb02a57649af3da
7
- data.tar.gz: 479790b6ffdbeccc639ebf7b33b84ff120bfb0a9dc8e5ff11b96a2acf26f4dcee4586c542cf3f30de280fc7c8920b31f531eb4fb39afdee2d08ff18a7d32e594
6
+ metadata.gz: d06e1e14657badf69828cffa141a967ae02423572b29f107e635b754308c701d3bc9c153ad93c01ea7bd36294fcc84e87cc1b6e50e44bab5b6460add94035992
7
+ data.tar.gz: 5c8e4f46c757aec7d7b4c1f9fcb8ac815016d80aadb218d095cabb127e5af5c061635d08b17b8d42c6b784f40520223d94ae7a27b9f0f9c2fa101f285a1233d9
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## March 25 2015 (1.0.5)
2
+
3
+ Minor improvements.
4
+
5
+ * **New Features**:
6
+
7
+ * Added `:execute_udf_on_query` method to `Aerospike::Client`
8
+
1
9
  ## March 24 2015 (1.0.4)
2
10
 
3
11
  Hot fix.
data/lib/aerospike.rb CHANGED
@@ -71,6 +71,7 @@ require 'aerospike/aerospike_exception'
71
71
  require 'aerospike/user_role'
72
72
 
73
73
  require 'aerospike/task/index_task'
74
+ require 'aerospike/task/execute_task'
74
75
  require 'aerospike/task/udf_remove_task'
75
76
  require 'aerospike/task/udf_register_task'
76
77
  require 'aerospike/task/task'
@@ -525,6 +525,43 @@ module Aerospike
525
525
  raise Aerospike::Exceptions::Aerospike.new(UDF_BAD_RESPONSE, "Invalid UDF return value")
526
526
  end
527
527
 
528
+ # execute_udf_on_query applies user defined function on records that match the statement filter.
529
+ # Records are not returned to the client.
530
+ # This asynchronous server call will return before command is complete.
531
+ # The user can optionally wait for command completion by using the returned
532
+ # ExecuteTask instance.
533
+ #
534
+ # This method is only supported by Aerospike 3 servers.
535
+ # If the policy is nil, the default relevant policy will be used.
536
+ def execute_udf_on_query(statement, package_name, function_name, function_args=[], options={})
537
+ policy = opt_to_query_policy(options)
538
+
539
+ nodes = @cluster.nodes
540
+ if nodes.length == 0
541
+ raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::SERVER_NOT_AVAILABLE, "Executing UDF failed because cluster is empty.")
542
+ end
543
+
544
+ # TODO: wait until all migrations are finished
545
+ statement.set_aggregate_function(package_name, function_name, function_args, false)
546
+
547
+ # Use a thread per node
548
+ nodes.each do |node|
549
+ Thread.new do
550
+ abort_on_exception = true
551
+ begin
552
+ command = QueryCommand.new(node, policy, statement, nil)
553
+ command.execute
554
+ rescue => e
555
+ Aerospike.logger.error(e)
556
+ raise e
557
+ end
558
+ end
559
+ end
560
+
561
+ ExecuteTask.new(@cluster, statement)
562
+ end
563
+
564
+
528
565
  # Create secondary index.
529
566
  # This asynchronous server call will return before command is complete.
530
567
  # The user can optionally wait for command completion by using the returned
@@ -29,7 +29,7 @@ module Aerospike
29
29
  READ_WRITE = 'read-write'
30
30
 
31
31
  # Allow read transactions with the database.
32
- READ = 'Read'
32
+ READ = 'read'
33
33
 
34
34
  end # module
35
35
 
@@ -92,7 +92,7 @@ module Aerospike
92
92
  @data_offset += @statement.function_name.bytesize + FIELD_HEADER_SIZE
93
93
 
94
94
  if @statement.function_args && @statement.function_args.length > 0
95
- functionArgBuffer = Value.of(@statement.function_args).bytes
95
+ functionArgBuffer = Value.of(@statement.function_args).to_bytes
96
96
  else
97
97
  functionArgBuffer = 0.ord
98
98
  end
@@ -36,6 +36,11 @@ module Aerospike
36
36
  # The only valid server return codes are "ok" and "not found".
37
37
  # If other return codes are received, then abort the batch.
38
38
  if result_code != 0
39
+ # if there is no recordset defined, it means this is an Execute UDF On Query command
40
+ # return successfully
41
+ if (@recordset == nil) && (result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR)
42
+ return nil
43
+ end
39
44
  raise Aerospike::Exceptions::Aerospike.new(result_code)
40
45
  end
41
46
 
@@ -0,0 +1,85 @@
1
+ # Copyright 2013-2014 Aerospike, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Aerospike
16
+
17
+ private
18
+
19
+ # ExecuteTask is used to poll for long running server execute job completion.
20
+ class ExecuteTask < Task
21
+
22
+ # NewExecuteTask initializes task with fields needed to query server nodes.
23
+ def initialize(cluster, statement)
24
+ super(cluster, false)
25
+
26
+ @task_id = statement.task_id
27
+ @scan = statement.is_scan?
28
+
29
+ self
30
+ end
31
+
32
+ # IsDone queries all nodes for task completion status.
33
+ def all_nodes_done?
34
+
35
+ if @scan
36
+ command = 'scan-list'
37
+ else
38
+ command = 'query-list'
39
+ end
40
+
41
+ nodes = @cluster.nodes
42
+ done = false
43
+
44
+ nodes.each do |node|
45
+ conn = node.get_connection(0)
46
+ responseMap, err = Info.request(conn, command)
47
+ node.put_connection(conn)
48
+
49
+ response = responseMap[command]
50
+ find = "job_id=#{@task_id}:"
51
+ index = response.index(find)
52
+
53
+ unless index
54
+ # don't return on first check
55
+ done = true
56
+ next
57
+ end
58
+
59
+ b = index + find.length
60
+ response = response[b, response.length]
61
+ find = 'job_status='
62
+ index = response.index(find)
63
+
64
+ next unless index
65
+
66
+ b = index + find.length
67
+ response = response[b, response.length]
68
+ e = response.index(':')
69
+ status = response[0, e]
70
+
71
+ case status
72
+ when 'ABORTED'
73
+ raise raise Aerospike::Exceptions::QueryTerminated
74
+ when 'IN PROGRESS'
75
+ return false
76
+ when 'DONE'
77
+ done = true
78
+ end
79
+ end
80
+
81
+ done
82
+ end
83
+
84
+ end
85
+ end
@@ -42,8 +42,8 @@ module Aerospike
42
42
  failures = 0
43
43
  while true
44
44
  begin
45
- break if completed?
46
45
  sleep(poll_interval.to_f)
46
+ break if completed?
47
47
  rescue => e
48
48
  Aerospike.logger.error(e)
49
49
  break if failures > allowed_failures
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Aerospike
3
- VERSION = "1.0.4"
3
+ VERSION = "1.0.5"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aerospike
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Khosrow Afroozeh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-24 00:00:00.000000000 Z
11
+ date: 2015-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -110,6 +110,7 @@ files:
110
110
  - lib/aerospike/query/stream_command.rb
111
111
  - lib/aerospike/record.rb
112
112
  - lib/aerospike/result_code.rb
113
+ - lib/aerospike/task/execute_task.rb
113
114
  - lib/aerospike/task/index_task.rb
114
115
  - lib/aerospike/task/task.rb
115
116
  - lib/aerospike/task/udf_register_task.rb