1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
LOGGER.progname = File.expand_path(__FILE__)
module OpenTox
class Task
TASK_ATTRIBS = [ :uri, :date, :title, :creator, :title, :description, :hasStatus, :percentageCompleted, :resultURI ]
TASK_ATTRIBS.each{ |a| attr_accessor(a) }
private
def initialize(uri)
@uri = uri
end
public
def self.create
task_uri = RestClientWrapper.post(@@config[:services]["opentox-task"], nil, nil, false).to_s
Task.find(task_uri.chomp)
end
def self.find(uri)
task = Task.new(uri)
task.reload
return task
end
def self.from_data(data, content_type, base_uri)
begin
task = Task.new(nil)
task.reload_from_data(data, content_type, base_uri)
return task
rescue
return nil
end
end
def reload
result = RestClientWrapper.get(uri)
reload_from_data(result, result.content_type)
end
def reload_from_data( data=nil, content_type=nil, base_uri=nil )
case content_type
when /text\/x-yaml/
task = YAML.load data
raise "yaml data is no task" if task.is_a?(Task)
TASK_ATTRIBS.each{ |a| send("#{a.to_s}=".to_sym,task[a]) }
when /application\/rdf\+xml/
base_uri = uri unless base_uri
owl = OpenTox::Owl.from_data(data,base_uri)
raise "not a task" if owl.ot_class=="Task"
TASK_ATTRIBS.each{|a| self.send("#{a.to_s}=".to_sym, owl.get(a.to_s))}
else
raise "content type for tasks not supported: "+content_type.to_s
end
end
# invalid: getters in task.rb should work for non-internal tasks as well
#
#def self.base_uri
# @@config[:services]["opentox-task"]
#end
#def self.all
# task_uris = RestClientWrapper.get(@@config[:services]["opentox-task"]).chomp.split(/\n/)
# task_uris.collect{|uri| Task.new(uri)}
#end
def cancel
RestClientWrapper.put(File.join(@uri,'Cancelled'))
reload
end
def completed(uri)
RestClientWrapper.put(File.join(@uri,'Completed'),{:resultURI => uri})
reload
end
def error(description)
RestClientWrapper.put(File.join(@uri,'Error'),{:description => description})
reload
end
def parent=(task)
RestClientWrapper.put(File.join(@uri,'parent'), {:uri => task.uri})
reload
end
def pid=(pid)
RestClientWrapper.put(File.join(@uri,'pid'), {:pid => pid})
reload
end
def completed?
@hasStatus.to_s == 'Completed'
end
def error?
@hasStatus.to_s == 'Error'
end
def wait_for_completion(dur=0.1)
until self.completed? or self.error?
sleep dur
reload
end
end
def self.as_task(parent_task=nil)
#return yield nil
task = OpenTox::Task.create
task.parent = parent_task if parent_task
pid = Spork.spork(:logger => LOGGER) do
LOGGER.debug "Task #{task.uri} started #{Time.now}"
begin
result = catch(:halt) do
yield task
LOGGER.debug "Task #{task.uri} done #{Time.now}"
end
if result && result.is_a?(Array) && result.size==2 && result[0]>202
# halted while executing task
LOGGER.error "task was halted: "+result.inspect
task.error(result[1])
throw :halt,result
end
task.completed(result)
rescue => ex
#raise ex
LOGGER.error "task failed: "+ex.message
task.error(ex.message)
end
raise "Invalid task state" unless task.completed? || task.error?
end
LOGGER.debug "Started task with PID: " + pid.to_s
task.pid = pid
task.uri
end
end
end
|