sfpagent 0.2.5 → 0.2.6
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 +1 -1
- data/lib/sfpagent/agent.rb +5 -1
- data/lib/sfpagent/bsig.rb +109 -25
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.6
|
data/lib/sfpagent/agent.rb
CHANGED
@@ -262,7 +262,11 @@ module Sfp
|
|
262
262
|
f.flock(File::LOCK_EX)
|
263
263
|
Sfp::Agent.logger.info "Setting the BSig model [Wait]"
|
264
264
|
f.rewind
|
265
|
-
data =
|
265
|
+
data = ''
|
266
|
+
if !bsig.nil?
|
267
|
+
bsig['operators'].each_index { |i| bsig['operators'][i]['id'] = i }
|
268
|
+
data = JSON.generate(bsig)
|
269
|
+
end
|
266
270
|
f.write(data)
|
267
271
|
f.flush
|
268
272
|
f.truncate(f.pos)
|
data/lib/sfpagent/bsig.rb
CHANGED
@@ -63,6 +63,7 @@ class Sfp::BSig
|
|
63
63
|
exec_status = :no_bsig
|
64
64
|
sleep SleepTime
|
65
65
|
else
|
66
|
+
bsig['operators'].sort! { |op1,op2| op1['pi'] <=> op2['pi'] }
|
66
67
|
exec_status = achieve_local_goal(bsig['id'], bsig['goal'], bsig['operators'], 1, :main)
|
67
68
|
if exec_status == :failure
|
68
69
|
Sfp::Agent.logger.error "[main] Executing BSig model [Failed]"
|
@@ -92,13 +93,19 @@ class Sfp::BSig
|
|
92
93
|
end
|
93
94
|
end
|
94
95
|
|
95
|
-
#
|
96
|
+
# @param id BSig's id
|
97
|
+
# @param goal goal state
|
98
|
+
# @param operators an array of sorted (by 'pi') operators
|
99
|
+
# @param pi current priority index value
|
100
|
+
# @param mode 'main' thread or 'satisfier' thread
|
101
|
+
#
|
102
|
+
# @return
|
96
103
|
# :no_flaw => there is no goal-flaw
|
97
104
|
# :failure => there is a failure on achieving the goal
|
98
105
|
# :ongoing => the selected operator is being executed
|
99
106
|
# :repaired => some goal-flaws have been repaired, but the goal may have other flaws
|
100
107
|
#
|
101
|
-
def
|
108
|
+
def sequential_achieve_local_goal(id, goal, operators, pi, mode)
|
102
109
|
operator = nil
|
103
110
|
|
104
111
|
current = get_current_state
|
@@ -107,13 +114,61 @@ class Sfp::BSig
|
|
107
114
|
|
108
115
|
operator = select_operator(flaws, operators, pi)
|
109
116
|
return :failure if operator.nil?
|
117
|
+
|
118
|
+
execute_operator(operator, id, operators, mode)
|
119
|
+
end
|
110
120
|
|
111
|
-
|
112
|
-
|
121
|
+
# @param id BSig's id
|
122
|
+
# @param goal goal state
|
123
|
+
# @param operators an array of sorted (by 'pi') operators
|
124
|
+
# @param pi current priority index value
|
125
|
+
# @param mode 'main' thread or 'satisfier' thread
|
126
|
+
#
|
127
|
+
# @return
|
128
|
+
# :no_flaw => there is no goal-flaw
|
129
|
+
# :failure => there is a failure on achieving the goal
|
130
|
+
# :ongoing => the selected operator is being executed
|
131
|
+
# :repaired => some goal-flaws have been repaired, but the goal may have other flaws
|
132
|
+
#
|
133
|
+
def achieve_local_goal(id, goal, operators, pi, mode)
|
134
|
+
current = get_current_state
|
135
|
+
flaws = compute_flaws(goal, current)
|
136
|
+
return :no_flaw if flaws.length <= 0
|
137
|
+
|
138
|
+
operators = select_operators(flaws, operators, pi)
|
139
|
+
return :failure if operators == :failure
|
140
|
+
|
141
|
+
Sfp::Agent.logger.info "total operators: #{operators.length}"
|
142
|
+
|
143
|
+
total = operators.length
|
144
|
+
status = []
|
145
|
+
operators_lock = Mutex.new
|
146
|
+
operators.each do |operator|
|
147
|
+
Thread.new {
|
148
|
+
stat = execute_operator(operator, id, operators, mode)
|
149
|
+
Sfp::Agent.logger.info "#{operator['name']}{#{JSON.generate(operator['parameters'])}} => #{stat}"
|
150
|
+
operators_lock.synchronize { status << stat }
|
151
|
+
}
|
152
|
+
end
|
153
|
+
wait? { status.length >= operators.length }
|
154
|
+
Sfp::Agent.logger.info "exec status: #{status.inspect}"
|
155
|
+
status.each { |stat|
|
156
|
+
return :failure if stat == :failure
|
157
|
+
return :ongoing if stat == :ongoing
|
158
|
+
}
|
159
|
+
:repaired
|
160
|
+
end
|
113
161
|
|
162
|
+
def wait?
|
163
|
+
until yield do
|
164
|
+
sleep 1
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def execute_operator(operator, id, operators, mode)
|
114
169
|
return :ongoing if not lock_operator(operator)
|
115
170
|
|
116
|
-
Sfp::Agent.logger.info "[#{mode}] Selected operator: #{operator['name']}"
|
171
|
+
Sfp::Agent.logger.info "[#{mode}] Selected operator: #{operator['id']}:#{operator['name']}{#{JSON.generate(operator['parameters'])}}"
|
117
172
|
|
118
173
|
next_pi = operator['pi'] + 1
|
119
174
|
pre_local, pre_remote = split_preconditions(operator)
|
@@ -151,16 +206,29 @@ class Sfp::BSig
|
|
151
206
|
def achieve_remote_goal(id, goal, pi, mode)
|
152
207
|
if goal.length > 0
|
153
208
|
agents = Sfp::Agent.get_agents
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
209
|
+
status = []
|
210
|
+
lock = Mutex.new
|
211
|
+
agents_goal = split_goal_by_agent(goal)
|
212
|
+
agents_goal.each do |agent_name,agent_goal|
|
213
|
+
Thread.new {
|
214
|
+
stat = achieve_remote_agent_goal(agents, agent_name, agent_goal, id, pi, mode)
|
215
|
+
lock.synchronize { status << stat }
|
216
|
+
}
|
161
217
|
end
|
218
|
+
wait? { status.length >= agents_goal.length }
|
219
|
+
Sfp::Agent.logger.info "achieve_remote_goal: #{status}"
|
220
|
+
status.each { |stat| return false if !stat }
|
162
221
|
end
|
222
|
+
true
|
223
|
+
end
|
163
224
|
|
225
|
+
def achieve_remote_agent_goal(agents, name, goal, id, pi, mode)
|
226
|
+
if agents.has_key?(name)
|
227
|
+
return false if agents[name]['sfpAddress'].to_s == ''
|
228
|
+
return false if not send_goal_to_agent(agents[name], id, goal, pi, name, mode)
|
229
|
+
else
|
230
|
+
return false if not verify_state_of_not_exist_agent(name, goal)
|
231
|
+
end
|
164
232
|
true
|
165
233
|
end
|
166
234
|
|
@@ -180,6 +248,7 @@ class Sfp::BSig
|
|
180
248
|
bsig = Sfp::Agent.get_bsig
|
181
249
|
return false if bsig.nil? or id < bsig['id']
|
182
250
|
|
251
|
+
bsig['operators'].sort! { |op1,op2| op1['pi'] <=> op2['pi'] }
|
183
252
|
status = nil
|
184
253
|
tries = MaxTries
|
185
254
|
begin
|
@@ -226,7 +295,7 @@ class Sfp::BSig
|
|
226
295
|
|
227
296
|
def lock_operator(operator)
|
228
297
|
@lock.synchronize {
|
229
|
-
operator_lock_file = "#{CacheDir}/operator.#{operator['name']}.lock"
|
298
|
+
operator_lock_file = "#{CacheDir}/operator.#{operator['id']}.#{operator['name']}.lock"
|
230
299
|
return false if File.exist?(operator_lock_file)
|
231
300
|
File.open(operator_lock_file, 'w') { |f| f.write('1') }
|
232
301
|
return true
|
@@ -235,7 +304,7 @@ class Sfp::BSig
|
|
235
304
|
|
236
305
|
def unlock_operator(operator)
|
237
306
|
@lock.synchronize {
|
238
|
-
operator_lock_file = "#{CacheDir}/operator.#{operator['name']}.lock"
|
307
|
+
operator_lock_file = "#{CacheDir}/operator.#{operator['id']}.#{operator['name']}.lock"
|
239
308
|
File.delete(operator_lock_file) if File.exist?(operator_lock_file)
|
240
309
|
}
|
241
310
|
end
|
@@ -327,20 +396,35 @@ class Sfp::BSig
|
|
327
396
|
flaws
|
328
397
|
end
|
329
398
|
|
330
|
-
|
331
|
-
|
332
|
-
|
399
|
+
# @param flaws a map of flaws (variable-value) that should be repaired
|
400
|
+
# @param operators a sorted-list of operators (sorted by 'pi')
|
401
|
+
# @param pi minimum priority-index value
|
402
|
+
#
|
403
|
+
# @return a list of applicable operators, or symbol :failure if all flaws
|
404
|
+
# cannot be repaired by available operators
|
405
|
+
#
|
406
|
+
def select_operators(flaws, operators, pi)
|
407
|
+
selected_operator = []
|
408
|
+
repaired = {}
|
409
|
+
operators.each do |op|
|
333
410
|
next if op['pi'] < pi
|
334
411
|
if can_repair?(op, flaws)
|
335
|
-
|
336
|
-
|
337
|
-
elsif selected_operator['pi'] > op['pi']
|
338
|
-
selected_operator = op
|
339
|
-
end
|
412
|
+
selected_operator << op
|
413
|
+
op['effect'].each { |var,val| repaired[var] = val if flaws[var] == val }
|
340
414
|
end
|
341
|
-
|
415
|
+
break if repaired.length >= flaws.length
|
416
|
+
end
|
417
|
+
return :failure if repaired.length < flaws.length
|
342
418
|
selected_operator
|
343
419
|
end
|
420
|
+
|
421
|
+
def select_operator(flaws, operators, pi)
|
422
|
+
operators.each do |op|
|
423
|
+
next if op['pi'] < pi
|
424
|
+
return op if can_repair?(op, flaws)
|
425
|
+
end
|
426
|
+
nil
|
427
|
+
end
|
344
428
|
|
345
429
|
def can_repair?(operator, flaws)
|
346
430
|
operator['effect'].each { |variable,value| return true if flaws[variable] == value }
|
@@ -365,7 +449,7 @@ class Sfp::BSig
|
|
365
449
|
end
|
366
450
|
|
367
451
|
def invoke(operator, mode)
|
368
|
-
Sfp::Agent.logger.info "[#{mode}] Invoking #{operator['name']}"
|
452
|
+
Sfp::Agent.logger.info "[#{mode}] Invoking #{operator['name']}{#{operator['parameters']}}"
|
369
453
|
|
370
454
|
begin
|
371
455
|
status = Sfp::Agent.execute_action(operator)
|
@@ -377,7 +461,7 @@ class Sfp::BSig
|
|
377
461
|
end
|
378
462
|
end
|
379
463
|
rescue Exception => e
|
380
|
-
Sfp::Agent.logger.error "Error in invoking operator #{operator['name']}\n#{e}\n#{e.backtrace.join("\n")}"
|
464
|
+
Sfp::Agent.logger.error "Error in invoking operator #{operator['name']}{#{operator['parameters']}}\n#{e}\n#{e.backtrace.join("\n")}"
|
381
465
|
return false
|
382
466
|
end
|
383
467
|
|
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.2.
|
4
|
+
version: 0.2.6
|
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: &
|
16
|
+
requirement: &15974100 !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: *
|
24
|
+
version_requirements: *15974100
|
25
25
|
description: A Ruby implementation of SFP agent.
|
26
26
|
email: herry13@gmail.com
|
27
27
|
executables:
|