iron_response 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -2,17 +2,16 @@
2
2
 
3
3
  # iron_response
4
4
 
5
- Glues together IronWorker and AWS S3 to provide a response object to remote worker scripts. This allows you to write massively concurrent Ruby programs without worrying about threads.
5
+ Provides a response object to remote worker scripts. This allows you to write massively concurrent Ruby programs without worrying about threads.
6
6
 
7
7
  ```ruby
8
8
  require "iron_response"
9
9
 
10
- config = {...}
10
+ config = {token: "123", project_id: "456"}
11
11
  batch = IronResponse::Batch.new
12
12
 
13
13
  batch.auto_update_worker = true
14
14
  batch.config[:iron_io] = config[:iron_io]
15
- batch.config[:aws_s3] = config[:aws_s3]
16
15
  batch.worker = "test/workers/is_prime.rb"
17
16
  batch.params_array = Array(1..10).map {|i| {number: i}}
18
17
 
@@ -48,16 +47,16 @@ client = IronWorkerNG::Client.new
48
47
  end
49
48
  ```
50
49
 
51
- For many use cases, this is fine. But what if I want to know the result of `do_something`? A simple way to get the result would be for your worker to POST the final result somewhere, then have the client it. This gem simply abstracts that process away, allowing the developer to avoid boilerplate and to keep worker code elegant.
50
+ For many use cases, this is fine. But what if I want to know the result of `do_something`? A simple way to get the result would be for your worker to POST the final result somewhere, then have the client retrieve it. This gem simply abstracts that process away, allowing the developer to avoid boilerplate and to keep worker code elegant.
52
51
 
53
52
  On top of all this, another benefit to using this gem is that it makes it much easier to test workers.
54
53
 
55
- Under the hood, `iron_response` uses some functional and meta-programming to capture the final expression of a worker file, convert it to JSON, and then POST it to Amazon S3. When all the workers in an `IronResponse::Batch` have finished, the gem retrieves the file and converts the JSON string back to Ruby.
54
+ Under the hood, `iron_response` uses some functional and meta-programming to capture the final expression of a worker file, convert it to JSON, and then POST it to either IronCache or Amazon S3. When all the workers in an `IronResponse::Batch` have finished, the gem retrieves the file and converts the JSON string back to Ruby.
56
55
 
57
56
  This process means there a few important implications:
58
57
 
59
58
  - Response objects "sent" from workers should be JSON-parseable. This means sticking to basic Ruby objects and data structures such as `String`, `Fixnum`, `Hash`, and `Array`.
60
- - Though these objects must be parseable, they can be fairly large. Though I haven't figured out exactly what the limit is, you really are only constrained by IronWorkers RAM and HD limits, and the bandwidth between the client (your computer/server), IronWorker servers, and S3. In an ideal setup, all three of these components are inside of Amazon's cloud, allowing you to get very fast throughput.
59
+ - If you're using IronCache (and not S3) for storage, response objects must be 1 MB or small.
61
60
 
62
61
  ## Usage
63
62
 
@@ -102,6 +101,8 @@ class Configuration
102
101
  end
103
102
  ```
104
103
 
104
+ Of course, if you don't want to use S3, just leave that part out of the `Hash`. You can specify `:bucket` for S3 and `:cache` for for IronCache. Otherwise they both default to `"iron_response".`
105
+
105
106
  Obviously, fill in the appropriate API keys. It is highly recommended that you do not use your AWS master keys. Instead, go to the AWS Console, click on "IAM", and create a user with a policy that allows it to edit the bucket named in the configuration file. Here's an example policy:
106
107
 
107
108
  ```json
@@ -17,6 +17,7 @@ Gem::Specification.new do |gem|
17
17
 
18
18
  gem.add_dependency "iron_worker_ng"
19
19
  gem.add_dependency "aws-s3"
20
+ gem.add_dependency "iron_cache"
20
21
  gem.add_development_dependency "minitest", "~> 4.7.3"
21
22
  gem.add_development_dependency "pry"
22
23
  gem.add_development_dependency "pry-rescue"
data/lib/iron_response.rb CHANGED
@@ -1,31 +1,72 @@
1
1
  require "iron_response/version"
2
2
  require "iron_worker_ng"
3
3
  require "aws/s3"
4
+ require "iron_cache"
4
5
  require "json"
5
6
 
6
7
  module IronResponse
7
- module Protocol
8
+ module Common
8
9
  S3_PATH = "tasks"
9
10
 
10
- def Protocol.s3_path(task_id)
11
+ DEFAULT_S3_BUCKET = "iron_response"
12
+ DEFAULT_IRON_CACHE_CACHE_NAME = "iron_response"
13
+
14
+ def Common.s3_path(task_id)
11
15
  "#{S3_PATH}/#{task_id}.json"
12
16
  end
17
+
18
+ def Common.s3_bucket_name(config)
19
+ config[:aws_s3][:bucket].nil? ? DEFAULT_S3_BUCKET : @config[:aws_s3][:bucket]
20
+ end
21
+
22
+ def Common.iron_cache_key(task_id)
23
+ task_id
24
+ end
25
+
26
+ def Common.iron_cache_cache_name(config)
27
+ config[:iron_io][:cache].nil? ? DEFAULT_IRON_CACHE_CACHE_NAME : @config[:iron_io][:cache]
28
+ end
29
+
30
+ def Common.response_provider(config)
31
+ config[:aws_s3].nil? ? :iron_cache : :aws_s3
32
+ end
13
33
  end
14
34
 
15
- class Responder
35
+ class Worker
16
36
  def initialize(binding, &block)
17
37
  task_id = eval("@iron_task_id", binding)
18
38
  params = eval("params", binding)
19
- send_data_to_s3(params, task_id, block.call)
39
+ @config = params[:config]
40
+
41
+ case IronResponse::Common.response_provider(@config)
42
+ when :iron_cache
43
+ send_data_to_iron_cache(params, task_id, block.call)
44
+ when :aws_s3
45
+ send_data_to_s3(params, task_id, block.call)
46
+ end
47
+ end
48
+
49
+ def send_data_to_iron_cache(params, task_id, data)
50
+ cache_client = IronCache::Client.new(@config[:iron_io])
51
+ cache_name = IronResponse::Common.iron_cache_cache_name(@config)
52
+ cache = cache_client.cache(cache_name)
53
+
54
+ key = IronResponse::Common.iron_cache_key(task_id)
55
+ value = data.to_json
56
+
57
+ cache.put(key, value)
20
58
  end
21
59
 
22
60
  def send_data_to_s3(params, task_id, data)
23
- aws_s3 = params[:aws_s3]
61
+ aws_s3 = @config[:aws_s3]
24
62
  AWS::S3::Base.establish_connection! access_key_id: aws_s3[:access_key_id],
25
63
  secret_access_key: aws_s3[:secret_access_key]
26
- path = IronResponse::Protocol.s3_path(task_id)
27
- bucket_name = params[:aws_s3][:bucket]
28
- AWS::S3::S3Object.store(path, data.to_json, bucket_name)
64
+
65
+ path = IronResponse::Common.s3_path(task_id)
66
+ bucket_name = IronResponse::Common.s3_bucket_name(@config)
67
+ value = data.to_json
68
+
69
+ AWS::S3::S3Object.store(path, value, bucket_name)
29
70
  end
30
71
  end
31
72
 
@@ -51,7 +92,7 @@ module IronResponse
51
92
  end
52
93
 
53
94
  task_ids = params_array.map do |params|
54
- params[:aws_s3] = @config[:aws_s3]
95
+ params[:config] = @config
55
96
  @client.tasks.create(worker_name, params)._id
56
97
  end
57
98
 
@@ -61,23 +102,44 @@ module IronResponse
61
102
  end
62
103
 
63
104
  def get_response_from_task_id(task_id)
105
+ case IronResponse::Common.response_provider(@config)
106
+ when :iron_cache
107
+ get_iron_cache_response(task_id)
108
+ when :aws_s3
109
+ get_aws_s3_response(task_id)
110
+ end
111
+ end
112
+
113
+ def get_aws_s3_response(task_id)
64
114
  aws_s3 = @config[:aws_s3]
65
115
  AWS::S3::Base.establish_connection! access_key_id: aws_s3[:access_key_id],
66
116
  secret_access_key: aws_s3[:secret_access_key]
67
117
 
68
- bucket_name = @config[:aws_s3][:bucket]
118
+ bucket_name = IronResponse::Common.s3_bucket_name(@config)
69
119
  bucket = AWS::S3::Bucket.find(bucket_name)
70
- path = IronResponse::Protocol.s3_path(task_id)
120
+ path = IronResponse::Common.s3_path(task_id)
71
121
  response = bucket[path].value
72
122
 
73
123
  JSON.parse(response)
74
124
  end
75
125
 
126
+ def get_iron_cache_response(task_id)
127
+ cache_client = IronCache::Client.new(@config[:iron_io])
128
+ cache_name = IronResponse::Common.iron_cache_cache_name(@config)
129
+ cache = cache_client.cache(cache_name)
130
+
131
+ key = IronResponse::Common.iron_cache_key(task_id)
132
+ value = cache.get(key).value
133
+
134
+ JSON.parse(value)
135
+ end
136
+
76
137
  def code
77
- @code ||= IronWorkerNG::Code::Ruby.new(exec: @worker).tap do |c|
78
- c.name = worker_name
79
- c.merge_gem("iron_response")
80
- c.runtime = "ruby"
138
+ if @code.nil?
139
+ @code = IronWorkerNG::Code::Ruby.new(exec: @worker)
140
+ @code.name = worker_name
141
+ @code.merge_gem("iron_response")
142
+ @code.runtime = "ruby"
81
143
  end
82
144
 
83
145
  @code
@@ -1,3 +1,3 @@
1
1
  module IronResponse
2
- VERSION = "0.0.3"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -8,8 +8,10 @@ class GemDependencyTest < MiniTest::Unit::TestCase
8
8
 
9
9
  batch.auto_update_worker = true
10
10
 
11
- batch.config[:iron_io] = config[:iron_io]
12
- batch.config[:aws_s3] = config[:aws_s3]
11
+ batch.config = config
12
+
13
+ #batch.config[:iron_io] = config[:iron_io]
14
+ #batch.config[:aws_s3] = config[:aws_s3]
13
15
  batch.worker = "test/workers/fcc_filings_counter.rb"
14
16
 
15
17
  batch.code.merge_gem("nokogiri", "< 1.6.0") # keeps the build times low
@@ -1,20 +1,36 @@
1
1
  require "test_helper"
2
2
 
3
3
  class SynopsisTest < MiniTest::Unit::TestCase
4
- def test_synopsis
5
-
4
+ def test_synopsis_with_s3
6
5
  config = Configuration.keys
7
- batch = IronResponse::Batch.new
6
+ batch = IronResponse::Batch.new
8
7
 
9
8
  batch.auto_update_worker = true
10
9
  batch.config[:iron_io] = config[:iron_io]
11
10
  batch.config[:aws_s3] = config[:aws_s3]
12
- batch.worker = "test/workers/is_prime.rb"
13
- batch.params_array = Array(1..20).map {|i| {number: i}}
11
+ batch.worker = "test/workers/hello.rb"
12
+ batch.params_array = Array(1..4).map {|i| {number: i}}
13
+
14
+ results = batch.run!
15
+
16
+ assert_equal Array, results.class
17
+ assert_equal batch.params_array.length, results.length
18
+ assert_equal true, results.select {|r| r.nil?}.length == 0
19
+ end
20
+
21
+ def test_synopsis_with_iron_cache
22
+ config = Configuration.keys
23
+ batch = IronResponse::Batch.new
24
+
25
+ batch.auto_update_worker = true
26
+ batch.config[:iron_io] = config[:iron_io]
27
+ batch.worker = "test/workers/hello.rb"
28
+ batch.params_array = Array(1..4).map {|i| {number: i}}
14
29
 
15
30
  results = batch.run!
16
31
 
17
32
  assert_equal Array, results.class
18
33
  assert_equal batch.params_array.length, results.length
34
+ assert_equal true, results.select {|r| r.nil?}.length == 0
19
35
  end
20
36
  end
@@ -0,0 +1,7 @@
1
+ require "iron_response"
2
+
3
+ IronResponse::Worker.new(binding) do
4
+ {
5
+ "result" => params
6
+ }
7
+ end
@@ -1,6 +1,6 @@
1
1
  require "iron_response"
2
2
 
3
- IronResponse::Responder.new(binding) do
3
+ IronResponse::Worker.new(binding) do
4
4
  def is_prime?(n)
5
5
  ("1" * n =~ /^1?$|^(11+?)\1+$/) == 0 ? false : true
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iron_response
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-10 00:00:00.000000000 Z
12
+ date: 2013-08-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: iron_worker_ng
@@ -43,6 +43,22 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: iron_cache
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
46
62
  - !ruby/object:Gem::Dependency
47
63
  name: minitest
48
64
  requirement: !ruby/object:Gem::Requirement
@@ -111,6 +127,7 @@ files:
111
127
  - test/synopsis_test.rb
112
128
  - test/test_helper.rb
113
129
  - test/workers/fcc_filings_counter.rb
130
+ - test/workers/hello.rb
114
131
  - test/workers/is_prime.rb
115
132
  homepage: ''
116
133
  licenses: []
@@ -142,5 +159,6 @@ test_files:
142
159
  - test/synopsis_test.rb
143
160
  - test/test_helper.rb
144
161
  - test/workers/fcc_filings_counter.rb
162
+ - test/workers/hello.rb
145
163
  - test/workers/is_prime.rb
146
164
  has_rdoc: