sfpagent 0.1.9 → 0.1.10

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sfpagent might be problematic. Click here for more details.

data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.9
1
+ 0.1.10
@@ -25,6 +25,7 @@ module Sfp
25
25
 
26
26
  BSigFile = "#{CachedDir}/bsig.model"
27
27
  BSigPIDFile = "#{CachedDir}/bsig.pid"
28
+ BSigThreadsLockFile = "#{CachedDir}/bsig.threads.lock.#{Time.now.nsec}"
28
29
 
29
30
  @@logger = WEBrick::Log.new(LogFile, WEBrick::BasicLog::INFO ||
30
31
  WEBrick::BasicLog::ERROR ||
@@ -90,6 +91,7 @@ Sfp::Agent.logger.info "modules dir: " + p[:modules_dir]
90
91
  ['INT', 'KILL', 'HUP'].each { |signal|
91
92
  trap(signal) {
92
93
  Sfp::Agent.logger.info "Shutting down web server"
94
+ bsig_engine.disable
93
95
  server.shutdown
94
96
  }
95
97
  }
@@ -693,13 +695,14 @@ Sfp::Agent.logger.info "modules dir: " + p[:modules_dir]
693
695
  end
694
696
 
695
697
  def get_model
696
- model = Sfp::Agent.get_model
697
-
698
698
  # The model is not exist.
699
- return [404, '', ''] if model.nil?
699
+ return [404, '', ''] if not File.exist?(Sfp::Agent::ModelFile)
700
700
 
701
- # The model is exist, and then send it in JSON.
702
- return [200, 'application/json', JSON.generate(model)] if !!model
701
+ begin
702
+ # The model is exist, and then send it in JSON.
703
+ return [200, 'application/json', File.read(Sfp::Agent::ModelFile)]
704
+ rescue
705
+ end
703
706
 
704
707
  # There is an error when retrieving the model!
705
708
  [500, '', '']
@@ -751,8 +754,6 @@ Sfp::Agent.logger.info "modules dir: " + p[:modules_dir]
751
754
  def satisfy_bsig_request(p={})
752
755
  return [400, '', ''] if not p[:query]
753
756
 
754
- Sfp::Agent.logger.info Sfp::Agent.bsig_engine.to_s
755
-
756
757
  return [500, '', ''] if Sfp::Agent.bsig_engine.nil?
757
758
 
758
759
  req = p[:query]
data/lib/sfpagent/bsig.rb CHANGED
@@ -8,11 +8,11 @@ class Sfp::BSig
8
8
 
9
9
  SatisfierPath = '/bsig/satisfier'
10
10
  CachedDir = (Process.euid == 0 ? '/var/sfpagent' : File.expand_path('~/.sfpagent'))
11
- SatisfierLockFile = CachedDir + '/bsig.satisfier.lock'
11
+ SatisfierLockFile = "#{CachedDir}/bsig.satisfier.lock.#{Time.now.nsec}"
12
12
 
13
- attr_accessor :enabled, :mode
13
+ attr_reader :enabled, :mode
14
14
 
15
- def initialize
15
+ def initialize(p={})
16
16
  @lock = Mutex.new
17
17
  @enabled = false
18
18
  end
@@ -27,6 +27,7 @@ class Sfp::BSig
27
27
  @enabled = true
28
28
  }
29
29
 
30
+ @mode = p[:mode]
30
31
  if p[:mode] == :main
31
32
  enable_main_thread
32
33
  elsif p[:mode] == :satisfier
@@ -35,53 +36,58 @@ class Sfp::BSig
35
36
  end
36
37
 
37
38
  def enable_satisfier_thread
38
- @mode = :satisfier
39
- Sfp::Agent.logger.info "[satisfier] BSig engine is enabled."
39
+ Sfp::Agent.logger.info "[#{@mode}] BSig engine is enabled."
40
40
  end
41
41
 
42
42
  def enable_main_thread
43
- @mode = :main
44
-
45
43
  ['INT', 'KILL', 'HUP'].each { |signal|
46
44
  trap(signal) {
47
- Sfp::Agent.logger.info "Shutting down BSig engine"
45
+ Sfp::Agent.logger.info "[#{@mode}] Shutting down BSig engine"
48
46
  disable
49
47
  }
50
48
  }
51
49
  register_satisfier_thread(:reset)
52
50
 
53
- Sfp::Agent.logger.info "[main] BSig engine is running."
51
+ Sfp::Agent.logger.info "[#{@mode}] BSig engine is running."
54
52
 
55
53
  puts "BSig Engine is running with PID #{$$}"
56
54
  File.open(Sfp::Agent::BSigPIDFile, 'w') { |f| f.write($$.to_s) }
57
55
 
58
56
  self.execute_model
59
57
 
60
- Sfp::Agent.logger.info "[main] BSig engine has stopped."
58
+ File.delete(SatisfierLockFile) if File.exist?(SatisfierLockFile)
59
+ Sfp::Agent.logger.info "[#{@mode}] BSig engine has stopped."
61
60
  end
62
61
 
63
62
  def execute_model
63
+ Sfp::Agent.logger.info "[#{@mode}] Executing BSig model"
64
+
65
+ previous_status = nil
64
66
  while @enabled
65
67
  begin
66
- Sfp::Agent.logger.info "[main] Sfp::BSig enabled"
67
68
 
68
69
  wait_for_satisfier?
69
70
 
70
71
  bsig = Sfp::Agent.get_bsig
71
72
  if bsig.nil?
73
+ status = :no_bsig
72
74
  sleep BSigSleepTime
73
75
  else
74
- status = achieve_local_goal(bsig['id'], bsig['goal'], bsig['operators'], 1, :main)
75
- Sfp::Agent.logger.info "[main] execute model - status: " + status.to_s
76
+ status = achieve_local_goal(bsig['id'], bsig['goal'], bsig['operators'], 1)
76
77
  if status == :failure
77
- Sfp::Agent.logger.error "[main] Executing BSig model [Failed]"
78
+ Sfp::Agent.logger.error "[#{@mode}] Executing BSig model [Failed]"
78
79
  sleep BSigSleepTime
79
80
  elsif status == :no_flaw
80
81
  sleep BSigSleepTime
81
82
  end
82
83
  end
84
+
85
+ if previous_status != status
86
+ Sfp::Agent.logger.info "[#{@mode}] BSig engine - status: " + status.to_s
87
+ previous_status = status
88
+ end
83
89
  rescue Exception => e
84
- Sfp::Agent.logger.error "Error on executing BSig model\n#{e}\n#{e.backtrace.join("\n")}"
90
+ Sfp::Agent.logger.error "[#{@mode}] Error on executing BSig model\n#{e}\n#{e.backtrace.join("\n")}"
85
91
  sleep BSigSleepTime
86
92
  end
87
93
  end
@@ -91,7 +97,7 @@ Sfp::Agent.logger.info "[main] execute model - status: " + status.to_s
91
97
  total_satisfier = 1
92
98
  loop do
93
99
  total_satisfier = (File.exist?(SatisfierLockFile) ? File.read(SatisfierLockFile).to_i : 0)
94
- return if total_satisfier <= 0
100
+ return if total_satisfier <= 0 or not @enabled
95
101
  sleep 1
96
102
  end
97
103
  end
@@ -101,13 +107,12 @@ Sfp::Agent.logger.info "[main] execute model - status: " + status.to_s
101
107
  # :failure : there is a failure on achieving the goal
102
108
  # :ongoing : the selected operator is being executed
103
109
  # :repaired : some goal-flaws have been repaired, but the goal may have other flaws
104
- def achieve_local_goal(id, goal, operators, pi, mode=nil)
110
+ def achieve_local_goal(id, goal, operators, pi)
105
111
  operator = nil
106
112
 
107
113
  current = get_current_state
108
114
  flaws = compute_flaws(goal, current)
109
115
  return :no_flaw if flaws.length <= 0
110
- Sfp::Agent.logger.info "[#{mode}] Flaws: #{JSON.generate(flaws)}"
111
116
 
112
117
  operator = select_operator(flaws, operators, pi)
113
118
  return :failure if operator.nil?
@@ -115,14 +120,13 @@ Sfp::Agent.logger.info "[#{mode}] Flaws: #{JSON.generate(flaws)}"
115
120
  @lock.synchronize {
116
121
  return :ongoing if operator['selected']
117
122
  operator['selected'] = true
118
- Sfp::Agent.logger.info "[#{mode}] Selected operator: #{JSON.generate(operator)}"
119
123
  }
124
+ Sfp::Agent.logger.info "[#{@mode}] Selected operator: #{operator['name']}" #{JSON.generate(operator)}"
120
125
 
121
126
  next_pi = pi + 1
122
127
  pre_local, pre_remote = split_preconditions(operator)
123
128
 
124
- Sfp::Agent.logger.info "[#{mode}] local-flaws: #{JSON.generate(pre_local)}"
125
- Sfp::Agent.logger.info "[#{mode}] remote-flaws: #{JSON.generate(pre_remote)}"
129
+ Sfp::Agent.logger.info "[#{@mode}] local-flaws: #{JSON.generate(pre_local)}, remote-flaws: #{JSON.generate(pre_remote)}"
126
130
 
127
131
  status = nil
128
132
  tries = MaxTries
@@ -139,8 +143,7 @@ Sfp::Agent.logger.info "[#{mode}] remote-flaws: #{JSON.generate(pre_remote)}"
139
143
  tries -= 1
140
144
  end until tries <= 0
141
145
 
142
- #Sfp::Agent.logger.info "[#{mode}] status local: " + status.to_s
143
- return :failure if status == :failure
146
+ return :failure if status != :no_flaw
144
147
 
145
148
  return :failure if not achieve_remote_goal(id, pre_remote, next_pi)
146
149
 
@@ -155,9 +158,10 @@ Sfp::Agent.logger.info "[#{mode}] remote-flaws: #{JSON.generate(pre_remote)}"
155
158
  def achieve_remote_goal(id, goal, pi)
156
159
  if goal.length > 0
157
160
  agents = Sfp::Agent.get_agents
158
- split_goal_by_agent(goal).each do |agent,g|
159
- return false if not agents.has_key?(agent) or agents[agent]['sfpAddress'].to_s == ''
160
- return false if not send_goal_to_agent(agents[agent], id, g, pi)
161
+ split_goal_by_agent(goal).each do |agent_name,agent_goal|
162
+ return false if not agents.has_key?(agent_name) or agents[agent_name]['sfpAddress'].to_s == ''
163
+
164
+ return false if not send_goal_to_agent(agents[agent_name], id, agent_goal, pi, agent_name)
161
165
  end
162
166
  end
163
167
  true
@@ -166,20 +170,16 @@ Sfp::Agent.logger.info "[#{mode}] remote-flaws: #{JSON.generate(pre_remote)}"
166
170
  def receive_goal_from_agent(id, goal, pi)
167
171
  register_satisfier_thread
168
172
 
169
- Sfp::Agent.logger.info "[satisfier] enabled: " + @enabled.to_s
170
173
  return false if not @enabled
171
174
 
172
175
  bsig = Sfp::Agent.get_bsig
173
176
 
174
- Sfp::Agent.logger.info "[satisfier] receive_goal_from_agent - " + id.inspect + " - " + goal.inspect + " - " + pi.inspect
175
- Sfp::Agent.logger.info "[satisfier] " + bsig.inspect
176
-
177
177
  return false if bsig.nil? or id < bsig['id']
178
178
 
179
179
  status = nil
180
180
  tries = MaxTries
181
181
  begin
182
- status = achieve_local_goal(bsig['id'], goal, bsig['operators'], pi, :satisfier)
182
+ status = achieve_local_goal(bsig['id'], goal, bsig['operators'], pi)
183
183
  if status == :no_flaw or status == :failure or not @enabled
184
184
  break
185
185
  elsif status == :ongoing
@@ -191,9 +191,7 @@ Sfp::Agent.logger.info "[satisfier] " + bsig.inspect
191
191
  tries -= 1
192
192
  end until tries <= 0
193
193
 
194
- return false if status == :failure
195
-
196
- true
194
+ return (status == :no_flaw)
197
195
 
198
196
  ensure
199
197
  unregister_satisfier_thread
@@ -201,8 +199,6 @@ Sfp::Agent.logger.info "[satisfier] " + bsig.inspect
201
199
 
202
200
  protected
203
201
  def register_satisfier_thread(mode=nil)
204
- return if mode == :reset and File.exist?(SatisfierLockFile)
205
-
206
202
  File.open(SatisfierLockFile, File::RDWR|File::CREAT, 0644) { |f|
207
203
  f.flock(File::LOCK_EX)
208
204
  value = (mode == :reset ? 0 : (f.read.to_i + 1))
@@ -236,12 +232,14 @@ Sfp::Agent.logger.info "[satisfier] " + bsig.inspect
236
232
  agent_goal
237
233
  end
238
234
 
239
- def send_goal_to_agent(agent, id, g, pi)
235
+ def send_goal_to_agent(agent, id, g, pi, agent_name='')
240
236
  data = {'id' => id,
241
237
  'goal' => JSON.generate(g),
242
238
  'pi' => pi}
243
239
  code, _ = put_data(agent['sfpAddress'], agent['sfpPort'], SatisfierPath, data)
244
- Sfp::Agent.logger.info "send_goal_to_agent - status: " + code.to_s
240
+
241
+ Sfp::Agent.logger.info "[#{@mode}] Request goal to: #{agent_name} - status: " + code.to_s
242
+
245
243
  (code == '200')
246
244
  end
247
245
 
@@ -282,9 +280,7 @@ Sfp::Agent.logger.info "send_goal_to_agent - status: " + code.to_s
282
280
  end
283
281
 
284
282
  def can_repair?(operator, flaws)
285
- operator['effect'].each { |var,val|
286
- return true if flaws[var] == val
287
- }
283
+ operator['effect'].each { |variable,value| return true if flaws[variable] == value }
288
284
  false
289
285
  end
290
286
 
@@ -306,6 +302,7 @@ Sfp::Agent.logger.info "send_goal_to_agent - status: " + code.to_s
306
302
  end
307
303
 
308
304
  def invoke(operator)
305
+ Sfp::Agent.logger.info "[#{@mode}] Invoking #{operator['name']}"
309
306
  Sfp::Agent.execute_action(operator)
310
307
  end
311
308
  end
@@ -94,24 +94,13 @@ class Sfp::Runtime
94
94
  def update_model(model, root, path)
95
95
  object = {}
96
96
  if model['_context'] == 'object' and model['_isa'].to_s.isref and model['_isa'].to_s != '$.Object'
97
- # if this model is an instance of a subclass of Object, then
98
- # get the current state of this object
99
- obj = (!defined?(@root) or @root.nil? ? nil : @root.at?(path))
100
- if obj.is_a?(Hash)
101
- object[:_self] = obj[:_self]
102
- object[:_self].update_model(model)
103
- else
104
- Sfp::Agent.logger.info "Instantiating object: #{model['_self']}"
105
- # the module has not been instantiated yet!
106
- object[:_self] = instantiate_sfp_object(model, root)
107
- end
97
+ object[:_self] = instantiate_sfp_object(model, root)
108
98
  end
109
99
 
110
100
  model.each do |key,child|
111
- next if key[0,1] == '_' or not child.is_a?(Hash) or child['_context'] != 'object' or
112
- child['_isa'].to_s == '$.Object'
113
- #not child['_isa'].to_s.isref or child['_isa'].to_s == '$.Object'
114
- object[key] = update_model(child, root, path.push(key))
101
+ if key[0,1] != '_' and child.is_a?(Hash) and child['_context'] == 'object' and child['_isa'].to_s != '$.Object'
102
+ object[key] = update_model(child, root, path.push(key))
103
+ end
115
104
  end
116
105
 
117
106
  object
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sfpagent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.1.10
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2013-08-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sfp
16
- requirement: &18421700 !ruby/object:Gem::Requirement
16
+ requirement: &16928140 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: 0.3.12
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *18421700
24
+ version_requirements: *16928140
25
25
  description: A Ruby implementation of SFP agent.
26
26
  email: herry13@gmail.com
27
27
  executables: