iron_worker_ng 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Iron.io, Inc
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
14
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
17
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # Basic Usage
2
+
3
+ Visit http://iron.io for more details.
4
+
5
+ ## Create Worker
6
+
7
+ You can just put any code into worker or can create class with name matching file name (e.g MyWorker class in my_worker.rb) and run method.
8
+
9
+ ```ruby
10
+ require 'active_record'
11
+
12
+ # @params hash is available here
13
+ # do something fun
14
+ ```
15
+
16
+ ## Create Runner
17
+
18
+ ```ruby
19
+ require 'iron_worker_ng'
20
+
21
+ client = IronWorkerNG::Client.new('IRON_IO_PROJECT_ID', 'IRON_IO_TOKEN')
22
+
23
+ code = IronWorkerNG::Code::Ruby.new
24
+ code.merge_worker 'path/to/my_worker.rb'
25
+ code.merge_gem 'activerecord'
26
+
27
+ # you can use hash_string to check if you need to reupload code
28
+ # note that hash_string check is fast while code upload can take a while (depends on how much things you merged)
29
+ puts code.hash_string
30
+
31
+ client.codes.create(code)
32
+
33
+ client.tasks.create('MyWorker', 'foo' => 'bar')
34
+ ```
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'time'
5
+ require 'iron_worker_ng'
6
+
7
+ if $*.size == 0 || (not ['upload', 'queue', 'schedule'].include?($*[0]))
8
+ puts 'usage: iron_worker_ng COMMAND [OPTIONS]'
9
+ puts ' COMMAND: upload, queue, schedule'
10
+ puts ' run iron_worker_ng COMMAND --help to get more information about each command'
11
+ exit 1
12
+ end
13
+
14
+ command = $*[0]
15
+ $*.shift
16
+
17
+ if ENV['IRON_IO_PROJECT_ID'].nil? || ENV['IRON_IO_TOKEN'].nil?
18
+ puts "please set $IRON_IO_PROJECT_ID and $IRON_IO_TOKEN environment variables"
19
+ exit 1
20
+ end
21
+
22
+ client = IronWorkerNG::Client.new(ENV['IRON_IO_PROJECT_ID'], ENV['IRON_IO_TOKEN'])
23
+
24
+ if command == 'upload'
25
+ runtimes = IronWorkerNG::Code::Base.registered_types
26
+ runtimes_help = runtimes[0][:name] + ' (default)' + (runtimes.size == 1 ? '' : ', ') + runtimes.map { |r| r[:name] }[1 .. -1].join(', ')
27
+
28
+ features = []
29
+
30
+ name = nil
31
+ runtime = nil
32
+ execute_features = []
33
+
34
+ opts = OptionParser.new do |opts|
35
+ opts.banner = 'usage: iron_worker_ng upload [OPTIONS]'
36
+
37
+ opts.on('-r', '--runtime RUNTIME', runtimes.map { |r| r[:name] }, "#{runtimes_help}") do |v|
38
+ runtime = v
39
+ end
40
+
41
+ opts.on('-n', '--name NAME', 'code name') do |v|
42
+ name = v
43
+ end
44
+
45
+ IronWorkerNG::Code::Base.registered_features.each do |f|
46
+ prefix = ''
47
+
48
+ if f[:for_klass] != IronWorkerNG::Code::Base
49
+ prefix = runtimes.find { |r| r[:klass] == f[:for_klass] }[:name] + '-'
50
+ end
51
+
52
+ opts.on("--#{prefix}#{f[:name].gsub('_', '-')} #{f[:args]}", Array) do |v|
53
+ execute_features << {:name => f[:name], :args => v}
54
+ end
55
+ end
56
+ end
57
+
58
+ begin
59
+ opts.parse!
60
+ rescue OptionParser::ParseError
61
+ puts $!.to_s
62
+ exit 1
63
+ end
64
+
65
+ if execute_features.size == 0
66
+ puts opts
67
+ exit 1
68
+ end
69
+
70
+ runtime = runtimes[0][:name] if runtime.nil?
71
+
72
+ code = runtimes.find { |r| r[:name] == runtime }[:klass].new(name)
73
+
74
+ execute_features.each do |f|
75
+ code.send(f[:name], *f[:args])
76
+ end
77
+
78
+ client.codes.create(code)
79
+ elsif command == 'queue' || command == 'schedule'
80
+ name = nil
81
+ params = {}
82
+
83
+ priority = nil
84
+ timeout = nil
85
+ delay = nil
86
+
87
+ start_at = nil
88
+ end_at = nil
89
+ run_times = nil
90
+ run_every = nil
91
+
92
+ opts = OptionParser.new do |opts|
93
+ opts.banner = "usage: iron_worker_ng #{command} [OPTIONS]"
94
+
95
+ opts.on('-n', '--name NAME', 'code name') do |v|
96
+ name = v
97
+ end
98
+
99
+ opts.on('-p', '--param NAME,VALUE', Array, 'parameters to pass') do |v|
100
+ params[v[0]] = v[1]
101
+ end
102
+
103
+ opts.on('--priority PRIORITY', Integer, '0 (default), 1, 2') do |v|
104
+ priority = v
105
+ end
106
+
107
+ opts.on('--timeout TIMEOUT', Integer, 'maximum run time in seconds from 0 to 3600 (default)') do |v|
108
+ timeout = v
109
+ end
110
+
111
+ opts.on('--delay DELAY', Integer, 'delay before start in seconds') do |v|
112
+ delay = v
113
+ end
114
+
115
+ if command == 'schedule'
116
+ opts.on('--start-at TIME', 'start task at specified time') do |v|
117
+ start_at = Time.parse(v)
118
+ end
119
+
120
+ opts.on('--end-at TIME', 'stop running task at specified time') do |v|
121
+ end_at = Time.parse(v)
122
+ end
123
+
124
+ opts.on('--run-times RUN_TIMES', Integer, 'run task no more times than specified') do |v|
125
+ run_times = v
126
+ end
127
+
128
+ opts.on('--run-every RUN_EVERY', Integer, 'run task every RUN_EVERY seconds') do |v|
129
+ run_every = v
130
+ end
131
+ end
132
+ end
133
+
134
+ begin
135
+ opts.parse!
136
+ rescue OptionParser::ParseError
137
+ puts $!.to_s
138
+ exit 1
139
+ end
140
+
141
+ if name.nil?
142
+ puts opts
143
+ exit 1
144
+ end
145
+
146
+ options = {}
147
+
148
+ options[:priority] = priority unless priority.nil?
149
+ options[:timeout] = timeout unless timeout.nil?
150
+ options[:delay] = delay unless delay.nil?
151
+
152
+ if command == 'schedule'
153
+ options[:start_at] = start_at unless start_at.nil?
154
+ options[:end_at] = end_at unless end_at.nil?
155
+ options[:run_times] = run_times unless run_times.nil?
156
+ options[:run_every] = run_every unless run_every.nil?
157
+ end
158
+
159
+ if command == 'queue'
160
+ client.tasks.create(name, params, options)
161
+ else
162
+ client.schedules.create(name, params, options)
163
+ end
164
+ end
@@ -0,0 +1,6 @@
1
+ require_relative 'iron_worker_ng/version'
2
+ require_relative 'iron_worker_ng/client'
3
+ require_relative 'iron_worker_ng/code/base'
4
+ require_relative 'iron_worker_ng/code/ruby'
5
+ require_relative 'iron_worker_ng/code/java'
6
+ require_relative 'iron_worker_ng/code/node'
@@ -0,0 +1,143 @@
1
+ require 'rest-client'
2
+ require 'rest'
3
+ require 'json'
4
+ require 'time'
5
+
6
+ require_relative 'api_client_error'
7
+
8
+ module IronWorkerNG
9
+ class APIClient
10
+ attr_reader :project_id
11
+ attr_reader :token
12
+
13
+ def initialize(project_id, token, params = {})
14
+ @project_id = project_id
15
+ @token = token
16
+
17
+ @user_agent = params[:user_agent] || 'iron_worker_ng-' + IronWorkerNG.version
18
+
19
+ scheme = params[:scheme] || 'https'
20
+ host = params[:host] || 'worker-aws-us-east-1.iron.io'
21
+ port = params[:port] || 443
22
+ api_version = params[:api_version] || 2
23
+
24
+ @url = "#{scheme}://#{host}:#{port}/#{api_version}/"
25
+
26
+ @rest = Rest::Client.new
27
+ end
28
+
29
+ def common_request_hash
30
+ {
31
+ 'Content-Type' => 'application/json',
32
+ 'Authorization' => "OAuth #{@token}",
33
+ 'User-Agent' => @user_agent
34
+ }
35
+ end
36
+
37
+ def get(method, params = {})
38
+ request_hash = {}
39
+ request_hash[:headers] = common_request_hash
40
+ request_hash[:params] = params
41
+
42
+ @rest.get(@url + method, request_hash)
43
+ end
44
+
45
+ def post(method, params = {})
46
+ request_hash = {}
47
+ request_hash[:headers] = common_request_hash
48
+ request_hash[:body] = params.to_json
49
+
50
+ @rest.post(@url + method, request_hash)
51
+ end
52
+
53
+ def delete(method, params = {})
54
+ request_hash = {}
55
+ request_hash[:headers] = common_request_hash
56
+ request_hash[:params] = params
57
+
58
+ @rest.delete(@url + method, request_hash)
59
+ end
60
+
61
+ def post_file(method, file, params = {})
62
+ request_hash = common_request_hash
63
+ request_hash[:data] = params.to_json
64
+ request_hash[:file] = file
65
+
66
+ RestClient.post(@url + method + "?oauth=#{@token}", request_hash)
67
+ end
68
+
69
+ def parse_response(response, parse_json = true)
70
+ raise IronWorkerNG::APIClientError.new(response.body) if response.code != 200
71
+
72
+ return response.body unless parse_json
73
+ JSON.parse(response.body)
74
+ end
75
+
76
+ def codes_list(params = {})
77
+ parse_response(get("projects/#{@project_id}/codes", params))
78
+ end
79
+
80
+ def codes_get(id)
81
+ parse_response(get("projects/#{@project_id}/codes/#{id}"))
82
+ end
83
+
84
+ def codes_create(name, file, runtime, runner)
85
+ parse_response(post_file("projects/#{@project_id}/codes", File.new(file, 'rb'), {:name => name, :runtime => runtime, :file_name => runner}))
86
+ end
87
+
88
+ def codes_delete(id)
89
+ parse_response(delete("projects/#{@project_id}/codes/#{id}"))
90
+ end
91
+
92
+ def codes_revisions(id, params = {})
93
+ parse_response(get("projects/#{@project_id}/codes/#{id}/revisions", params))
94
+ end
95
+
96
+ def codes_download(id, params = {})
97
+ parse_response(get("projects/#{@project_id}/codes/#{id}/download", params), false)
98
+ end
99
+
100
+ def tasks_list(params = {})
101
+ parse_response(get("projects/#{@project_id}/tasks", params))
102
+ end
103
+
104
+ def tasks_get(id)
105
+ parse_response(get("projects/#{@project_id}/tasks/#{id}"))
106
+ end
107
+
108
+ def tasks_create(code_name, payload, params = {})
109
+ parse_response(post("projects/#{@project_id}/tasks", {:tasks => [{:code_name => code_name, :payload => payload}.merge(params)]}))
110
+ end
111
+
112
+ def tasks_cancel(id)
113
+ parse_response(post("projects/#{@project_id}/tasks/#{id}/cancel"))
114
+ end
115
+
116
+ def tasks_log(id)
117
+ parse_response(get("projects/#{@project_id}/tasks/#{id}/log"), false)
118
+ end
119
+
120
+ def tasks_set_progress(id, params = {})
121
+ parse_response(post("projects/#{@project_id}/tasks/#{id}/progress", params))
122
+ end
123
+
124
+ def schedules_list(params = {})
125
+ parse_response(get("projects/#{@project_id}/schedules", params))
126
+ end
127
+
128
+ def schedules_get(id)
129
+ parse_response(get("projects/#{@project_id}/schedules/#{id}"))
130
+ end
131
+
132
+ def schedules_create(code_name, payload, params = {})
133
+ params[:start_at] = params[:start_at].iso8601 if (not params[:start_at].nil?) && params[:start_at].class == Time
134
+ params[:end_at] = params[:end_at].iso8601 if (not params[:end_at].nil?) && params[:end_at].class == Time
135
+
136
+ parse_response(post("projects/#{@project_id}/schedules", {:schedules => [{:code_name => code_name, :payload => payload}.merge(params)]}))
137
+ end
138
+
139
+ def schedules_cancel(id)
140
+ parse_response(post("projects/#{@project_id}/schedules/#{id}/cancel"))
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,4 @@
1
+ module IronWorkerNG
2
+ class APIClientError < Exception
3
+ end
4
+ end
@@ -0,0 +1,55 @@
1
+ require_relative 'api_client'
2
+
3
+ module IronWorkerNG
4
+ class ClientProxyCaller
5
+ def initialize(client, prefix)
6
+ @client = client
7
+ @prefix = prefix
8
+ end
9
+
10
+ def method_missing(name, *args, &block)
11
+ full_name = @prefix.to_s + '_' + name.to_s
12
+ if @client.respond_to?(full_name)
13
+ @client.send(full_name, *args, &block)
14
+ else
15
+ super
16
+ end
17
+ end
18
+ end
19
+
20
+ class Client
21
+ attr_reader :api
22
+
23
+ def initialize(project_id, token, params = {})
24
+ @api = IronWorkerNG::APIClient.new(project_id, token, params)
25
+ end
26
+
27
+ def method_missing(name, *args, &block)
28
+ if args.length == 0
29
+ IronWorkerNG::ClientProxyCaller.new(self, name)
30
+ else
31
+ super
32
+ end
33
+ end
34
+
35
+ def codes_create(code)
36
+ zip_file = code.create_zip
37
+ @api.codes_create(code.name, zip_file, code.runtime, code.runner)
38
+ File.unlink(zip_file)
39
+
40
+ true
41
+ end
42
+
43
+ def tasks_create(code_name, params = {}, options = {})
44
+ res = @api.tasks_create(code_name, {:project_id => @api.project_id, :token => @api.token, :params => params}.to_json, options)
45
+
46
+ res['tasks'][0]['id']
47
+ end
48
+
49
+ def schedules_create(code_name, params = {}, options = {})
50
+ res = @api.schedules_create(code_name, {:project_id => @api.project_id, :token => @api.token, :params => params}.to_json, options)
51
+
52
+ res['schedules'][0]['id']
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,95 @@
1
+ require 'tmpdir'
2
+ require 'zip/zip'
3
+
4
+ require_relative '../feature/base'
5
+ require_relative '../feature/common/merge_file'
6
+ require_relative '../feature/common/merge_dir'
7
+
8
+ module IronWorkerNG
9
+ module Code
10
+ class Base
11
+ attr_reader :name
12
+ attr_reader :features
13
+
14
+ @@registered_types = []
15
+
16
+ def self.registered_types
17
+ @@registered_types
18
+ end
19
+
20
+ def self.register_type(type)
21
+ @@registered_types << type
22
+ end
23
+
24
+ @@registered_features = []
25
+
26
+ def self.registered_features
27
+ @@registered_features
28
+ end
29
+
30
+ def self.register_feature(feature)
31
+ @@registered_features << feature
32
+ end
33
+
34
+ include IronWorkerNG::Feature::Common::MergeFile::InstanceMethods
35
+ include IronWorkerNG::Feature::Common::MergeDir::InstanceMethods
36
+
37
+ def initialize(name = nil)
38
+ @name = name
39
+ @features = []
40
+ end
41
+
42
+ def fixate
43
+ IronWorkerNG::Code::Base.registered_features.each do |rf|
44
+ if rf[:for_klass] == self.class && respond_to?(rf[:name] + '_fixate')
45
+ send(rf[:name] + '_fixate')
46
+ end
47
+ end
48
+ end
49
+
50
+ def hash_string
51
+ fixate
52
+
53
+ Digest::MD5.hexdigest(@features.map { |f| f.hash_string }.join)
54
+ end
55
+
56
+ def bundle(zip)
57
+ @features.each do |feature|
58
+ feature.bundle(zip)
59
+ end
60
+ end
61
+
62
+ def create_zip
63
+ fixate
64
+
65
+ init_code = ''
66
+
67
+ @features.each do |f|
68
+ if f.respond_to?(:code_for_init)
69
+ init_code += f.send(:code_for_init) + "\n"
70
+ end
71
+ end
72
+
73
+ zip_name = Dir.tmpdir + '/' + Dir::Tmpname.make_tmpname("iron-worker-ng-", "code.zip")
74
+
75
+ Zip::ZipFile.open(zip_name, Zip::ZipFile::CREATE) do |zip|
76
+ bundle(zip)
77
+ create_runner(zip, init_code)
78
+ end
79
+
80
+ zip_name
81
+ end
82
+
83
+ def create_runner(zip)
84
+ end
85
+
86
+ def runtime
87
+ nil
88
+ end
89
+
90
+ def runner
91
+ nil
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,51 @@
1
+ require_relative '../feature/java/merge_jar'
2
+ require_relative '../feature/java/merge_worker'
3
+
4
+ module IronWorkerNG
5
+ module Code
6
+ class Java < IronWorkerNG::Code::Base
7
+ include IronWorkerNG::Feature::Java::MergeJar::InstanceMethods
8
+ include IronWorkerNG::Feature::Java::MergeWorker::InstanceMethods
9
+
10
+ def create_runner(zip, init_code)
11
+ classpath_array = []
12
+
13
+ @features.each do |f|
14
+ if f.respond_to?(:code_for_classpath)
15
+ classpath_array << f.send(:code_for_classpath)
16
+ end
17
+ end
18
+
19
+ classpath = classpath_array.join(':')
20
+
21
+ zip.get_output_stream('runner.rb') do |runner|
22
+ runner.write <<RUNNER
23
+ # iron_worker_ng-#{IronWorkerNG.version}
24
+
25
+ root = nil
26
+
27
+ ($*.length - 2).downto(0) do |i|
28
+ root = $*[i + 1] if $*[i] == '-d'
29
+ end
30
+
31
+ Dir.chdir(root)
32
+
33
+ #{init_code}
34
+
35
+ puts `java -cp #{classpath} #{worker.klass} \#{$*.join(' ')}`
36
+ RUNNER
37
+ end
38
+ end
39
+
40
+ def runtime
41
+ 'ruby'
42
+ end
43
+
44
+ def runner
45
+ 'runner.rb'
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ IronWorkerNG::Code::Base.register_type(:name => 'java', :klass => IronWorkerNG::Code::Java)
@@ -0,0 +1,39 @@
1
+ require_relative '../feature/node/merge_worker'
2
+
3
+ module IronWorkerNG
4
+ module Code
5
+ class Node < IronWorkerNG::Code::Base
6
+ include IronWorkerNG::Feature::Node::MergeWorker::InstanceMethods
7
+
8
+ def create_runner(zip, init_code)
9
+ zip.get_output_stream('runner.rb') do |runner|
10
+ runner.write <<RUNNER
11
+ # iron_worker_ng-#{IronWorkerNG.version}
12
+
13
+ root = nil
14
+
15
+ ($*.length - 2).downto(0) do |i|
16
+ root = $*[i + 1] if $*[i] == '-d'
17
+ end
18
+
19
+ Dir.chdir(root)
20
+
21
+ #{init_code}
22
+
23
+ puts `node \#{worker_file_name} \#{$*.join(' ')}`
24
+ RUNNER
25
+ end
26
+ end
27
+
28
+ def runtime
29
+ 'ruby'
30
+ end
31
+
32
+ def runner
33
+ 'runner.rb'
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ IronWorkerNG::Code::Base.register_type(:name => 'node', :klass => IronWorkerNG::Code::Node)
@@ -0,0 +1,86 @@
1
+ require_relative '../feature/ruby/merge_gem'
2
+ require_relative '../feature/ruby/merge_gemfile'
3
+ require_relative '../feature/ruby/merge_worker'
4
+
5
+ module IronWorkerNG
6
+ module Code
7
+ class Ruby < IronWorkerNG::Code::Base
8
+ include IronWorkerNG::Feature::Ruby::MergeGem::InstanceMethods
9
+ include IronWorkerNG::Feature::Ruby::MergeGemfile::InstanceMethods
10
+ include IronWorkerNG::Feature::Ruby::MergeWorker::InstanceMethods
11
+
12
+ def create_runner(zip, init_code)
13
+ zip.get_output_stream('runner.rb') do |runner|
14
+ runner.write <<RUNNER
15
+ # iron_worker_ng-#{IronWorkerNG.version}
16
+
17
+ root = nil
18
+ payload_file = nil
19
+ task_id = nil
20
+
21
+ ($*.length - 2).downto(0) do |i|
22
+ root = $*[i + 1] if $*[i] == '-d'
23
+ payload_file = $*[i + 1] if $*[i] == '-payload'
24
+ task_id = $*[i + 1] if $*[i] == '-id'
25
+ end
26
+
27
+ Dir.chdir(root)
28
+
29
+ #{init_code}
30
+ $:.unshift("\#{root}")
31
+
32
+ def log(*args)
33
+ puts *args
34
+ end
35
+
36
+ require 'json'
37
+
38
+ payload = JSON.load(File.open(payload_file))
39
+
40
+ @iron_io_project_id = payload['project_id']
41
+ @iron_io_token = payload['token']
42
+ @iron_worker_task_id = task_id
43
+ @params = payload['params']
44
+
45
+ require worker_file_name
46
+
47
+ worker_class = nil
48
+
49
+ begin
50
+ worker_class = Kernel.const_get(worker_class_name)
51
+ rescue
52
+ end
53
+
54
+ unless worker_class.nil?
55
+ worker_inst = worker_class.new
56
+
57
+ class << worker_inst
58
+ attr_accessor :iron_io_project_id
59
+ attr_accessor :iron_io_token
60
+ attr_accessor :iron_worker_task_id
61
+ attr_accessor :params
62
+ end
63
+
64
+ worker_inst.iron_io_project_id = @iron_io_project_id
65
+ worker_inst.iron_io_token = @iron_io_token
66
+ worker_inst.iron_worker_task_id = @iron_worker_task_id
67
+ worker_inst.params = @params
68
+
69
+ worker_inst.run
70
+ end
71
+ RUNNER
72
+ end
73
+ end
74
+
75
+ def runtime
76
+ 'ruby'
77
+ end
78
+
79
+ def runner
80
+ 'runner.rb'
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ IronWorkerNG::Code::Base.register_type(:name => 'ruby', :klass => IronWorkerNG::Code::Ruby)
@@ -0,0 +1,12 @@
1
+ module IronWorkerNG
2
+ module Feature
3
+ class Base
4
+ def hash_string
5
+ ''
6
+ end
7
+
8
+ def bundle(zip)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,43 @@
1
+ module IronWorkerNG
2
+ module Feature
3
+ module Common
4
+ module MergeDir
5
+ class Feature < IronWorkerNG::Feature::Base
6
+ attr_reader :path
7
+ attr_reader :dest
8
+
9
+ def initialize(path, dest)
10
+ @path = File.expand_path(path)
11
+ @dest = dest
12
+ end
13
+
14
+ def hash_string
15
+ s = @path + @dest + File.mtime(@path).to_i.to_s
16
+
17
+ Dir.glob(@path + '/**/**') do |path|
18
+ s += path + File.mtime(path).to_i.to_s
19
+ end
20
+
21
+ Digest::MD5.hexdigest(s)
22
+ end
23
+
24
+ def bundle(zip)
25
+ Dir.glob(@path + '/**/**') do |path|
26
+ zip.add(@dest + '/' + File.basename(@path) + path[@path.length .. -1], path)
27
+ end
28
+ end
29
+ end
30
+
31
+ module InstanceMethods
32
+ def merge_dir(path, dest = '.')
33
+ @features << IronWorkerNG::Feature::Common::MergeDir::Feature.new(path, dest)
34
+ end
35
+
36
+ def self.included(base)
37
+ IronWorkerNG::Code::Base.register_feature(:name => 'merge_dir', :for_klass => base, :args => 'PATH[,DEST]')
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,35 @@
1
+ module IronWorkerNG
2
+ module Feature
3
+ module Common
4
+ module MergeFile
5
+ class Feature < IronWorkerNG::Feature::Base
6
+ attr_reader :path
7
+ attr_reader :dest
8
+
9
+ def initialize(path, dest)
10
+ @path = File.expand_path(path)
11
+ @dest = dest
12
+ end
13
+
14
+ def hash_string
15
+ Digest::MD5.hexdigest(@path + @dest + File.mtime(@path).to_i.to_s)
16
+ end
17
+
18
+ def bundle(zip)
19
+ zip.add(@dest + '/' + File.basename(@path), @path)
20
+ end
21
+ end
22
+
23
+ module InstanceMethods
24
+ def merge_file(path, dest = '.')
25
+ @features << IronWorkerNG::Feature::Common::MergerFile::Feature.new(path, dest)
26
+ end
27
+
28
+ def self.included(base)
29
+ IronWorkerNG::Code::Base.register_feature(:name => 'merge_file', :for_klass => base, :args => 'PATH[,DEST]')
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,37 @@
1
+ module IronWorkerNG
2
+ module Feature
3
+ module Java
4
+ module MergeJar
5
+ class Feature < IronWorkerNG::Feature::Base
6
+ attr_reader :path
7
+
8
+ def initialize(path)
9
+ @path = File.expand_path(path)
10
+ end
11
+
12
+ def hash_string
13
+ Digest::MD5.hexdigest(@path + File.mtime(@path).to_i.to_s)
14
+ end
15
+
16
+ def bundle(zip)
17
+ zip.add(File.basename(@path), @path)
18
+ end
19
+
20
+ def code_for_classpath
21
+ File.basename(@path)
22
+ end
23
+ end
24
+
25
+ module InstanceMethods
26
+ def merge_jar(path)
27
+ @features << IronWorkerNG::Feature::Java::MergeJar::Feature.new(path)
28
+ end
29
+
30
+ def self.included(base)
31
+ IronWorkerNG::Code::Base.register_feature(:name => 'merge_jar', :for_klass => base, :args => 'PATH')
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,48 @@
1
+ module IronWorkerNG
2
+ module Feature
3
+ module Java
4
+ module MergeWorker
5
+ class Feature < IronWorkerNG::Feature::Base
6
+ attr_reader :path
7
+ attr_reader :klass
8
+
9
+ def initialize(path, klass)
10
+ @path = File.expand_path(path)
11
+ @klass = klass
12
+ end
13
+
14
+ def hash_string
15
+ Digest::MD5.hexdigest(@path + @klass + File.mtime(@path).to_i.to_s)
16
+ end
17
+
18
+ def bundle(zip)
19
+ zip.add(File.basename(@path), @path)
20
+ end
21
+
22
+ def code_for_classpath
23
+ File.basename(@path)
24
+ end
25
+ end
26
+
27
+ module InstanceMethods
28
+ attr_reader :worker
29
+
30
+ def merge_worker(path, klass)
31
+ @worker ||= nil
32
+
33
+ return unless @worker.nil?
34
+
35
+ @name ||= klass.split('.')[-1]
36
+
37
+ @worker = IronWorkerNG::Feature::Java::MergeWorker::Feature.new(path, klass)
38
+ @features << @worker
39
+ end
40
+
41
+ def self.included(base)
42
+ IronWorkerNG::Code::Base.register_feature(:name => 'merge_worker', :for_klass => base, :args => 'PATH,CLASS')
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,46 @@
1
+ module IronWorkerNG
2
+ module Feature
3
+ module Node
4
+ module MergeWorker
5
+ class Feature < IronWorkerNG::Feature::Base
6
+ attr_reader :path
7
+
8
+ def initialize(path)
9
+ @path = File.expand_path(path)
10
+ end
11
+
12
+ def hash_string
13
+ Digest::MD5.hexdigest(@path + File.mtime(@path).to_i.to_s)
14
+ end
15
+
16
+ def bundle(zip)
17
+ zip.add(File.basename(@path), @path)
18
+ end
19
+
20
+ def code_for_init
21
+ "worker_file_name = '#{File.basename(@path)}'"
22
+ end
23
+ end
24
+
25
+ module InstanceMethods
26
+ attr_reader :worker
27
+
28
+ def merge_worker(path)
29
+ @worker ||= nil
30
+
31
+ return unless @worker.nil?
32
+
33
+ @name ||= File.basename(path).gsub(/\.js$/, '').capitalize.gsub(/_./) { |x| x[1].upcase }
34
+
35
+ @worker = IronWorkerNG::Feature::Node::MergeWorker::Feature.new(path)
36
+ @features << @worker
37
+ end
38
+
39
+ def self.included(base)
40
+ IronWorkerNG::Code::Base.register_feature(:name => 'merge_worker', :for_klass => base, :args => 'PATH')
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,71 @@
1
+ require 'bundler'
2
+
3
+ module IronWorkerNG
4
+ module Feature
5
+ module Ruby
6
+ module MergeGem
7
+ class Feature < IronWorkerNG::Feature::Base
8
+ attr_reader :spec
9
+
10
+ def initialize(spec)
11
+ @spec = spec
12
+ end
13
+
14
+ def hash_string
15
+ Digest::MD5.hexdigest(@spec.full_name)
16
+ end
17
+
18
+ def bundle(zip)
19
+ if @spec.extensions.length == 0
20
+ zip.add('./gems/' + @spec.full_name, @spec.full_gem_path)
21
+ Dir.glob(@spec.full_gem_path + '/**/**') do |path|
22
+ zip.add('./gems/' + @spec.full_name + path[@spec.full_gem_path.length .. -1], path)
23
+ end
24
+ end
25
+ end
26
+
27
+ def code_for_init
28
+ if @spec.extensions.length == 0
29
+ '$:.unshift("#{root}/gems/' + @spec.full_name + '/lib")'
30
+ else
31
+ '# native gem ' + @spec.full_name
32
+ end
33
+ end
34
+ end
35
+
36
+ module InstanceMethods
37
+ attr_reader :merge_gem_reqs
38
+
39
+ def merge_gem(name, version = '>= 0')
40
+ @merge_gem_reqs ||= []
41
+
42
+ @merge_gem_reqs << Bundler::Dependency.new(name, version.split(', '))
43
+ end
44
+
45
+ def merge_gem_fixate
46
+ @merge_gem_reqs ||= []
47
+
48
+ @features.reject! { |f| f.class == IronWorkerNG::Feature::Ruby::MergeGem::Feature }
49
+
50
+ if @merge_gem_reqs.length > 0
51
+ reqs = @merge_gem_reqs.map { |req| Bundler::DepProxy.new(req, Gem::Platform::RUBY) }
52
+
53
+ source = Bundler::Source::Rubygems.new
54
+ index = Bundler::Index.build { |index| index.use source.specs }
55
+
56
+ spec_set = Bundler::Resolver.resolve(reqs, index)
57
+
58
+ spec_set.to_a.each do |spec|
59
+ @features << IronWorkerNG::Feature::Ruby::MergeGem::Feature.new(spec.__materialize__)
60
+ end
61
+ end
62
+ end
63
+
64
+ def self.included(base)
65
+ IronWorkerNG::Code::Base.register_feature(:name => 'merge_gem', :for_klass => base, :args => 'NAME[,VERSION]')
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,42 @@
1
+ require 'bundler'
2
+
3
+ module IronWorkerNG
4
+ module Feature
5
+ module Ruby
6
+ module MergeGemfile
7
+ class Feature < IronWorkerNG::Feature::Base
8
+ attr_reader :path
9
+ attr_reader :groups
10
+
11
+ def initialize(path, groups)
12
+ @path = File.expand_path(path)
13
+ @groups = groups
14
+ end
15
+
16
+ def hash_string
17
+ Digest::MD5.hexdigest(@path + File.mtime(@path).to_i.to_s + (File.exists?(@path + '.lock') ? File.mtime(@path + '.lock').to_i.to_s : '') + @groups.join)
18
+ end
19
+ end
20
+
21
+ module InstanceMethods
22
+ def merge_gemfile(path, *groups)
23
+ groups = groups.map { |g| g.to_sym }
24
+ groups << :default if groups.length == 0
25
+
26
+ specs = Bundler::Definition.build(path, path + '.lock', nil).specs_for(groups)
27
+
28
+ specs.each do |spec|
29
+ merge_gem(spec.name, spec.version.to_s)
30
+ end
31
+
32
+ @features << IronWorkerNG::Feature::Ruby::MergeGemfile::Feature.new(path, groups)
33
+ end
34
+
35
+ def self.included(base)
36
+ IronWorkerNG::Code::Base.register_feature(:name => 'merge_gemfile', :for_klass => base, :args => 'PATH[,GROUP...]')
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,52 @@
1
+ module IronWorkerNG
2
+ module Feature
3
+ module Ruby
4
+ module MergeWorker
5
+ class Feature < IronWorkerNG::Feature::Base
6
+ attr_reader :path
7
+ attr_reader :klass
8
+
9
+ def initialize(path, klass)
10
+ @path = File.expand_path(path)
11
+ @klass = klass
12
+ end
13
+
14
+ def hash_string
15
+ Digest::MD5.hexdigest(@path + @klass)
16
+ end
17
+
18
+ def bundle(zip)
19
+ zip.add('./' + File.basename(@path), @path)
20
+ end
21
+
22
+ def code_for_init
23
+ "worker_file_name = '#{File.basename(@path)}'\nworker_class_name='#{@klass}'"
24
+ end
25
+ end
26
+
27
+ module InstanceMethods
28
+ attr_reader :worker
29
+
30
+ def merge_worker(path, klass = nil)
31
+ @worker ||= nil
32
+
33
+ return unless @worker.nil?
34
+
35
+ if klass == nil
36
+ klass = File.basename(path).gsub(/\.rb$/, '').capitalize.gsub(/_./) { |x| x[1].upcase }
37
+ end
38
+
39
+ @name ||= klass
40
+
41
+ @worker = IronWorkerNG::Feature::Ruby::MergeWorker::Feature.new(path, klass)
42
+ @features << @worker
43
+ end
44
+
45
+ def self.included(base)
46
+ IronWorkerNG::Code::Base.register_feature(:name => 'merge_worker', :for_klass => base, :args => 'PATH[,CLASS]')
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,7 @@
1
+ module IronWorkerNG
2
+ @@version = nil
3
+
4
+ def self.version
5
+ @@version ||= File.read(File.dirname(__FILE__) + '/../../VERSION').strip
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: iron_worker_ng
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andrew Kirilenko
9
+ - Iron.io, Inc
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-02-23 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: zip
17
+ requirement: &79402670 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *79402670
26
+ - !ruby/object:Gem::Dependency
27
+ name: rest-client
28
+ requirement: &79402330 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *79402330
37
+ - !ruby/object:Gem::Dependency
38
+ name: rest
39
+ requirement: &79401930 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *79401930
48
+ - !ruby/object:Gem::Dependency
49
+ name: json
50
+ requirement: &79401450 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *79401450
59
+ - !ruby/object:Gem::Dependency
60
+ name: bundler
61
+ requirement: &79401140 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: 1.0.0
67
+ type: :runtime
68
+ prerelease: false
69
+ version_requirements: *79401140
70
+ - !ruby/object:Gem::Dependency
71
+ name: jeweler
72
+ requirement: &79400870 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.8.3
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: *79400870
81
+ description: New generation ruby client for IronWorker
82
+ email: info@iron.io
83
+ executables:
84
+ - iron_worker_ng
85
+ extensions: []
86
+ extra_rdoc_files:
87
+ - LICENSE
88
+ - README.md
89
+ files:
90
+ - LICENSE
91
+ - README.md
92
+ - VERSION
93
+ - bin/iron_worker_ng
94
+ - lib/iron_worker_ng.rb
95
+ - lib/iron_worker_ng/api_client.rb
96
+ - lib/iron_worker_ng/api_client_error.rb
97
+ - lib/iron_worker_ng/client.rb
98
+ - lib/iron_worker_ng/code/base.rb
99
+ - lib/iron_worker_ng/code/java.rb
100
+ - lib/iron_worker_ng/code/node.rb
101
+ - lib/iron_worker_ng/code/ruby.rb
102
+ - lib/iron_worker_ng/feature/base.rb
103
+ - lib/iron_worker_ng/feature/common/merge_dir.rb
104
+ - lib/iron_worker_ng/feature/common/merge_file.rb
105
+ - lib/iron_worker_ng/feature/java/merge_jar.rb
106
+ - lib/iron_worker_ng/feature/java/merge_worker.rb
107
+ - lib/iron_worker_ng/feature/node/merge_worker.rb
108
+ - lib/iron_worker_ng/feature/ruby/merge_gem.rb
109
+ - lib/iron_worker_ng/feature/ruby/merge_gemfile.rb
110
+ - lib/iron_worker_ng/feature/ruby/merge_worker.rb
111
+ - lib/iron_worker_ng/version.rb
112
+ homepage: http://www.iron.io
113
+ licenses: []
114
+ post_install_message:
115
+ rdoc_options: []
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ! '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ segments:
125
+ - 0
126
+ hash: 745459379
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - ! '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ requirements: []
134
+ rubyforge_project:
135
+ rubygems_version: 1.8.15
136
+ signing_key:
137
+ specification_version: 3
138
+ summary: New generation ruby client for IronWorker
139
+ test_files: []