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 +7 -6
- data/iron_response.gemspec +1 -0
- data/lib/iron_response.rb +77 -15
- data/lib/iron_response/version.rb +1 -1
- data/test/gem_dependency_test.rb +4 -2
- data/test/synopsis_test.rb +21 -5
- data/test/workers/hello.rb +7 -0
- data/test/workers/is_prime.rb +1 -1
- metadata +20 -2
data/README.md
CHANGED
@@ -2,17 +2,16 @@
|
|
2
2
|
|
3
3
|
# iron_response
|
4
4
|
|
5
|
-
|
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
|
-
-
|
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
|
data/iron_response.gemspec
CHANGED
@@ -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
|
8
|
+
module Common
|
8
9
|
S3_PATH = "tasks"
|
9
10
|
|
10
|
-
|
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
|
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
|
-
|
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 =
|
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
|
-
|
27
|
-
|
28
|
-
|
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[:
|
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
|
118
|
+
bucket_name = IronResponse::Common.s3_bucket_name(@config)
|
69
119
|
bucket = AWS::S3::Bucket.find(bucket_name)
|
70
|
-
path = IronResponse::
|
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
|
78
|
-
|
79
|
-
|
80
|
-
|
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
|
data/test/gem_dependency_test.rb
CHANGED
@@ -8,8 +8,10 @@ class GemDependencyTest < MiniTest::Unit::TestCase
|
|
8
8
|
|
9
9
|
batch.auto_update_worker = true
|
10
10
|
|
11
|
-
batch.config
|
12
|
-
|
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
|
data/test/synopsis_test.rb
CHANGED
@@ -1,20 +1,36 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
|
3
3
|
class SynopsisTest < MiniTest::Unit::TestCase
|
4
|
-
def
|
5
|
-
|
4
|
+
def test_synopsis_with_s3
|
6
5
|
config = Configuration.keys
|
7
|
-
batch
|
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/
|
13
|
-
batch.params_array = Array(1..
|
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
|
data/test/workers/is_prime.rb
CHANGED
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
|
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-
|
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:
|