manband 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README CHANGED
@@ -102,7 +102,11 @@ By default, bucket used is "manband". It can be specified in command-line.
102
102
  ## Gem creation
103
103
 
104
104
  Execute:
105
- rack package
105
+ rake package
106
106
 
107
107
  Gem is created in pkg directory
108
108
  Webband may use this gem, or use current files with same hierarchy
109
+
110
+ ## History
111
+
112
+ 0.6.0: Remove mb-minion dependency. New bunny gem is incompatible now, code has been rewriten to remove the dependency and use only amqp.
data/bin/jobhandler.rb CHANGED
@@ -3,9 +3,7 @@ require 'yaml'
3
3
  require 'optparse'
4
4
  require 'amqp'
5
5
  require 'json'
6
- require 'mb-minion'
7
6
 
8
- include Minion
9
7
 
10
8
  # The program manages job commands. Master nodes (workflow handler) sends
11
9
  # messages to jobhandler instances. Each instance manages one and
@@ -93,7 +91,33 @@ end
93
91
 
94
92
  log.info "Start handler "+handler
95
93
 
96
- job "manband.node"+options[:queue] do |args|
94
+ urlconfig = FlowConfig.config()
95
+
96
+
97
+ EventMachine.run do
98
+ connection = AMQP.connect(FlowConfig.config())
99
+
100
+ show_stopper = Proc.new do
101
+ $stdout.puts "Stopping..."
102
+ connection.close {
103
+ EventMachine.stop { exit }
104
+ }
105
+ end
106
+
107
+ Signal.trap 'INT', show_stopper
108
+ Signal.trap 'TERM', show_stopper
109
+
110
+ channel_exception_handler = Proc.new { |ch, channel_close| EventMachine.stop; raise "channel error: #{channel_close.reply_text}" }
111
+
112
+ channel = AMQP::Channel.new(connection)
113
+ #channel.on_error(&channel_exception_handler)
114
+ channel.prefetch(1)
115
+
116
+ exchange = channel.direct()
117
+ queue = channel.queue('manband.node'+options[:queue], :auto_delete => false, :durable => true)
118
+ queue.bind(exchange).subscribe(:ack => true) do |metadata, message|
119
+ puts "##DEBUG "+message
120
+ args = JSON.parse(message)
97
121
  msg = JSON.parse(args["msg"])
98
122
  if args["operation"] == OP_DESTROY
99
123
  myworkflow = WorkFlow.get(msg["id"])
@@ -127,5 +151,10 @@ job "manband.node"+options[:queue] do |args|
127
151
  end
128
152
  end
129
153
  end
154
+
155
+
156
+ channel.acknowledge(metadata.delivery_tag, false)
157
+ end
158
+
130
159
  end
131
160
 
data/bin/manband.rb CHANGED
@@ -13,6 +13,7 @@ require 'manband/workflow.rb'
13
13
  require 'manband/flowconfig.rb'
14
14
  require 'manband/job.rb'
15
15
  require 'manband/bandmanager.rb'
16
+ require 'manband/util.rb'
16
17
 
17
18
  # The program sends a workflow execution request to manband orchestrator.
18
19
  # Author: Olivier Sallou <olivier.sallou@irisa.fr>
data/bin/remoteband.rb CHANGED
@@ -3,9 +3,13 @@ require 'yaml'
3
3
  require 'optparse'
4
4
  require 'amqp'
5
5
  require 'json'
6
- require 'mb-minion'
6
+ require 'logger'
7
+
8
+ $:.push File.expand_path("../lib")
9
+
10
+ require 'manband/flowconfig.rb'
11
+ require 'manband/util.rb'
7
12
 
8
- include Minion
9
13
 
10
14
  # The program sends a workflow execution request to manband orchestrator.
11
15
  # This program does not need database credentials but does not get workflow id in return
@@ -78,4 +82,12 @@ msg["wfile"]=options[:workflow]
78
82
  msg["var"]=options[:var]
79
83
  msg["uid"]=options[:uid]
80
84
  msg["bucket"]=options[:bucket]
81
- Minion.enqueue("manband.master", { "operation" => "new", "msg" => msg.to_json })
85
+
86
+
87
+ Utils.publish('manband.master',{ "operation" => "new", "msg" => msg.to_json })
88
+
89
+ urlconfig = FlowConfig.config()
90
+
91
+
92
+
93
+
@@ -3,9 +3,7 @@ require 'yaml'
3
3
  require 'optparse'
4
4
  require 'amqp'
5
5
  require 'json'
6
- require 'mb-minion'
7
6
 
8
- include Minion
9
7
 
10
8
  # The program s the main orchestrator of the workflow.
11
9
  # It starts with a workflow execution request and sends messages to job
@@ -26,6 +24,7 @@ end
26
24
 
27
25
  $:.push File.expand_path("../lib")
28
26
 
27
+ require 'manband/flowconfig.rb'
29
28
  require 'manband/workflow.rb'
30
29
  require 'manband/job.rb'
31
30
  require 'manband/bandmanager.rb'
@@ -33,8 +32,17 @@ require 'manband/bandmanager.rb'
33
32
  log = Logger.new(STDOUT)
34
33
  log.level = Logger::INFO
35
34
 
35
+
36
36
  @@options = {}
37
37
 
38
+ def savemessage(id,operation,msg)
39
+ if @@options[:debug] == false
40
+ return
41
+ end
42
+ bmsg = BandMessage.new(:wid => id, :message => '{ "operation" => '+operation+', "msg" => '+msg+' }' )
43
+ bmsg.save
44
+ end
45
+
38
46
  optparse = OptionParser.new do|opts|
39
47
 
40
48
  # This displays the help screen, all programs are
@@ -75,8 +83,37 @@ if @@options[:conf]!=nil
75
83
  FlowConfig.setworkdir(conf["workdir"])
76
84
  end
77
85
 
78
- job "manband.master" do |args|
86
+
87
+ EventMachine.run do
88
+ connection = AMQP.connect(FlowConfig.config())
89
+
90
+ show_stopper = Proc.new do
91
+ $stdout.puts "Stopping..."
92
+ connection.close {
93
+ EventMachine.stop { exit }
94
+ }
95
+ end
96
+
97
+ Signal.trap 'INT', show_stopper
98
+ Signal.trap 'TERM', show_stopper
99
+
100
+ channel_exception_handler = Proc.new { |ch, channel_close| EventMachine.stop; raise "channel error: #{channel_close.reply_text}" }
101
+
102
+ channel = AMQP::Channel.new(connection)
103
+ #channel.on_error(&channel_exception_handler)
104
+ channel.prefetch(1)
105
+
106
+ exchange = channel.direct()
107
+ queue = channel.queue('manband.master', :auto_delete => false, :durable => true)
108
+ queue.bind(exchange).subscribe(:ack => true) do |metadata, message|
109
+
110
+ begin
111
+ args = JSON.parse(message)
79
112
  msg = JSON.parse(args["msg"])
113
+ rescue Exception => e
114
+ log.error("Could not parse message "+args["msg"])
115
+ channel.acknowledge(metadata.delivery_tag, false)
116
+ end
80
117
  if args["operation"] == OP_NEW
81
118
  BandManager.launch(msg["wfile"],msg["var"],msg["uid"],msg["bucket"])
82
119
  end
@@ -180,12 +217,10 @@ job "manband.master" do |args|
180
217
  curjob.resume
181
218
  end
182
219
  end
183
- end
184
220
 
185
- def savemessage(id,operation,msg)
186
- if @@options[:debug] == false
187
- return
188
- end
189
- bmsg = BandMessage.new(:wid => id, :message => '{ "operation" => '+operation+', "msg" => '+msg+' }' )
190
- bmsg.save
221
+
222
+ channel.acknowledge(metadata.delivery_tag, false)
223
+ end
224
+
191
225
  end
226
+
@@ -3,10 +3,8 @@ require 'yaml'
3
3
  require 'optparse'
4
4
  require 'amqp'
5
5
  require 'json'
6
- require 'mb-minion'
7
6
  require 'fileutils'
8
7
 
9
- include Minion
10
8
 
11
9
  require 'manband/workflow.rb'
12
10
  require 'manband/flowconfig.rb'
@@ -136,9 +134,9 @@ class BandManager
136
134
  # Request workflow management
137
135
  msg = '{ "id" : "'+workflow.id.to_s+'", "root" : "'+rootjob.id.to_s+'"}'
138
136
  if debug
139
- Minion.enqueue("manband.master", { "operation" => OP_SKIP, "msg" => msg })
137
+ Utils.publish("manband.master", { "operation" => OP_SKIP, "msg" => msg })
140
138
  else
141
- Minion.enqueue("manband.master", { "operation" => OP_START, "msg" => msg })
139
+ Utils.publish("manband.master", { "operation" => OP_START, "msg" => msg })
142
140
  end
143
141
  end
144
142
  end
@@ -153,7 +151,10 @@ class BandManager
153
151
  newworkflow.parse('root',rootjob.id)
154
152
  jobmsg = '{ "id" : "'+newworkflow.id.to_s+'", "root" : "'+rootjob.id.to_s+'"}'
155
153
  job = Job.new(:wid => newworkflow.id, :node => "fake", :command => "", :status => STATUS_FAKE, :instances => 0, :workdir => '')
156
- job.sendmessage(OP_START,jobmsg)
154
+
155
+ Utils.publish('manband.master', { "operation" => OP_START, "msg" => jobmsg })
156
+ job.logMessage(OP_START,jobmsg)
157
+
157
158
  return newworkflow.id
158
159
  end
159
160
 
@@ -113,6 +113,22 @@ class FlowConfig
113
113
  end
114
114
  end
115
115
 
116
+ def self.config
117
+ url ||= (ENV["AMQP_URL"] || "amqp://guest:guest@localhost/")
118
+ uri = URI.parse(url)
119
+ {
120
+ :vhost => uri.path,
121
+ :host => uri.host,
122
+ :user => uri.user,
123
+ :port => (uri.port || 5672),
124
+ :pass => uri.password,
125
+ :heartbeat => 0
126
+ }
127
+ rescue Object => e
128
+ raise("invalid AMQP_URL: #{uri.inspect} (#{e})")
129
+ end
130
+
131
+
116
132
 
117
133
  end
118
134
 
data/lib/manband/job.rb CHANGED
@@ -3,10 +3,9 @@ require 'dm-migrations'
3
3
  require 'yaml'
4
4
  require 'manband/workflow.rb'
5
5
  require 'manband/flowconfig.rb'
6
- require 'mb-minion'
6
+ require 'manband/util.rb'
7
7
  require 'logger'
8
8
 
9
- include Minion
10
9
 
11
10
  #DataMapper.setup(:default, 'sqlite:///home/osallou/Desktop/genflow/project.db')
12
11
  DataMapper.setup(:default, ENV['MYSQL_URL'])
@@ -68,6 +67,7 @@ class Job
68
67
  if instance>0
69
68
  workdir = workdir + "/node" + instance.to_s
70
69
  end
70
+ EventMachine.defer do
71
71
  err = runcommand(workdir,instance)
72
72
  if err == nil || err == false
73
73
  # An error occured
@@ -82,6 +82,7 @@ class Job
82
82
  jobmsg = '{ "workflow" : "'+@wid.to_s+'" , "node" : "'+@node+'", "id" : "'+@id.to_s+'", "handler" : "'+curhandler.to_s+'", "instance" : "'+instance.to_s+'" }'
83
83
  sendmessage(OP_FINISH,jobmsg)
84
84
  end
85
+ end # End EventMachine
85
86
  end
86
87
 
87
88
  # Skip treatment, just answer, for debug
@@ -117,7 +118,7 @@ class Job
117
118
  cmd = "sudo -u "+wflow.uid+" '"+script+"'"
118
119
  end
119
120
  @@log.debug cmd
120
- system(cmd)
121
+ system(cmd)
121
122
  end
122
123
 
123
124
  # Change instance counter
@@ -292,12 +293,17 @@ class Job
292
293
  queue = "manband.node"+jobqueue
293
294
  end
294
295
  if queue != nil
295
- Minion.enqueue(queue, { "operation" => operation, "msg" => msg })
296
+ Utils.enqueue(queue, { "operation" => operation, "msg" => msg })
297
+ logMessage(operation,msg)
298
+ end
299
+ end
300
+
301
+ # If debug, log the message in the database
302
+ def logMessage(operation,msg)
296
303
  if @@debug == true
297
304
  bmsg = BandMessage.new(:wid => @wid, :message => '{ "operation" => '+operation+', "msg" => '+msg+' }' )
298
305
  bmsg.save
299
306
  end
300
- end
301
307
  end
302
308
 
303
309
  end
@@ -0,0 +1,50 @@
1
+ require 'manband/flowconfig.rb'
2
+ require 'amqp'
3
+
4
+ # Utility classes
5
+ class Utils
6
+
7
+
8
+ @@connection = nil
9
+ @@channel = nil
10
+ @@exchange = nil
11
+
12
+ def self.setcontext()
13
+ if(@@connection==nil)
14
+ @@connection = AMQP.connect(FlowConfig.config())
15
+ @@channel = AMQP::Channel.new(@@connection)
16
+ @@exchange = @@channel.direct()
17
+ end
18
+ end
19
+
20
+ # Send a message in context
21
+ # args:
22
+ # dest name of destination queue
23
+ # msg message to send. Message is a hash with keys operation and msg.
24
+ def self.enqueue(dest,data= {})
25
+ Utils.setcontext()
26
+ msg = data.to_json
27
+ queue = @@channel.queue(dest, :auto_delete => false, :durable => true)
28
+ queue.bind(@@exchange)
29
+ @@exchange.publish(msg)
30
+ end
31
+
32
+ # Creates a context and sends a message
33
+ # args:
34
+ # dest name of destination queue
35
+ # msg message to send. Message is a hash with keys operation and msg.
36
+ def self.publish(dest,data= {})
37
+ msg = data.to_json
38
+ EventMachine.run do
39
+ connection = AMQP.connect(FlowConfig.config())
40
+ channel = AMQP::Channel.new(connection)
41
+ exchange = channel.direct()
42
+ queue = channel.queue(dest, :auto_delete => false, :durable => true)
43
+ queue.bind(exchange)
44
+ exchange.publish(msg) do
45
+ connection.close { EventMachine.stop }
46
+ end
47
+ end
48
+ end
49
+
50
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manband
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 5
9
- - 1
10
- version: 0.5.1
8
+ - 6
9
+ - 0
10
+ version: 0.6.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Olivier Sallou
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-07-16 00:00:00 Z
18
+ date: 2012-07-17 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: amqp
@@ -88,7 +88,7 @@ dependencies:
88
88
  type: :runtime
89
89
  version_requirements: *id005
90
90
  - !ruby/object:Gem::Dependency
91
- name: mb-minion
91
+ name: mb-aws-s3
92
92
  prerelease: false
93
93
  requirement: &id006 !ruby/object:Gem::Requirement
94
94
  none: false
@@ -102,7 +102,7 @@ dependencies:
102
102
  type: :runtime
103
103
  version_requirements: *id006
104
104
  - !ruby/object:Gem::Dependency
105
- name: mb-aws-s3
105
+ name: uuid
106
106
  prerelease: false
107
107
  requirement: &id007 !ruby/object:Gem::Requirement
108
108
  none: false
@@ -115,20 +115,6 @@ dependencies:
115
115
  version: "0"
116
116
  type: :runtime
117
117
  version_requirements: *id007
118
- - !ruby/object:Gem::Dependency
119
- name: uuid
120
- prerelease: false
121
- requirement: &id008 !ruby/object:Gem::Requirement
122
- none: false
123
- requirements:
124
- - - ">="
125
- - !ruby/object:Gem::Version
126
- hash: 3
127
- segments:
128
- - 0
129
- version: "0"
130
- type: :runtime
131
- version_requirements: *id008
132
118
  description:
133
119
  email: olivier.sallou@irisa.fr
134
120
  executables: []
@@ -148,6 +134,7 @@ files:
148
134
  - lib/manband/bandmanager.rb
149
135
  - lib/manband/user.rb
150
136
  - lib/manband/workflow.rb
137
+ - lib/manband/util.rb
151
138
  - lib/manband/job.rb
152
139
  - lib/manband/flowconfig.rb
153
140
  - README