diff options
author | Martin Gütlein <martin.guetlein@gmail.com> | 2010-04-28 10:21:35 +0200 |
---|---|---|
committer | Martin Gütlein <martin.guetlein@gmail.com> | 2010-04-28 10:21:35 +0200 |
commit | 8439bb9b337bded4a54018c03500a15082bce6b0 (patch) | |
tree | 2b573ca60a14017be203233b68354e5895aa64e5 | |
parent | 60ee47624583411db004bf3601491320dabe588e (diff) |
adjust to new task api (201)
-rw-r--r-- | lib/environment.rb | 8 | ||||
-rw-r--r-- | lib/model.rb | 4 | ||||
-rw-r--r-- | lib/owl.rb | 13 | ||||
-rw-r--r-- | lib/rest_client_wrapper.rb | 72 | ||||
-rw-r--r-- | lib/task.rb | 63 |
5 files changed, 90 insertions, 70 deletions
diff --git a/lib/environment.rb b/lib/environment.rb index c86d2be..b46bf19 100644 --- a/lib/environment.rb +++ b/lib/environment.rb @@ -45,9 +45,11 @@ before {$sinatra = self unless $sinatra} class Sinatra::Base # overwriting halt to log halts (!= 202) - def halt(status,msg) - LOGGER.error "halt "+status.to_s+" "+msg.to_s if (status != 202) - throw :halt, [status, msg] + def halt(*response) + LOGGER.error "halt "+response.first.to_s+" "+(response.size>1 ? response[1].to_s : "") if response.first >= 300 + # orig sinatra code: + response = response.first if response.length == 1 + throw :halt, response end end diff --git a/lib/model.rb b/lib/model.rb index 236de84..dfd5886 100644 --- a/lib/model.rb +++ b/lib/model.rb @@ -14,7 +14,7 @@ module OpenTox def initialize(owl) [:date, :creator, :title, :format, :algorithm, :dependentVariables, :independentVariables, :predictedVariables, :trainingDataset].each do |a| - self.send("#{a.to_s}=".to_sym, owl.get(a.to_s)) + self.send("#{a.to_s}=".to_sym, owl.get(a.to_s)) end @uri = owl.uri RestClientWrapper.raise_uri_error "invalid model:\n"+ @@ -35,7 +35,7 @@ module OpenTox LOGGER.debug "Build model, algorithm_uri:"+algorithm_uri.to_s+", algorithm_parms: "+algorithm_params.inspect.to_s uri = OpenTox::RestClientWrapper.post(algorithm_uri,algorithm_params).to_s - RestClientWrapper.raise_uri_error("Invalid build model result: "+uri.to_s, algorithm_uri, algorithm_params ) unless Utils.model_uri?(uri) + RestClientWrapper.raise_uri_error("Invalid build model result: '"+uri.to_s+"'", algorithm_uri, algorithm_params ) unless Utils.model_uri?(uri) return PredictionModel.find(uri) end @@ -36,7 +36,7 @@ module OpenTox end # loads owl from data - def self.from_data(data, base_uri, ot_class, no_wrong_class_exception=false ) + def self.from_data(data, base_uri, ot_class) owl = OpenTox::Owl.new parser = Redland::Parser.new @@ -64,15 +64,8 @@ module OpenTox unless owl.root_node types = [] owl.model.find(nil, owl.node("type"), nil){ |s,p,o| types << o.to_s } - msg = "root node for class '"+ot_class+"' not found (available type nodes: "+types.inspect+")" - if no_wrong_class_exception - LOGGER.debug "suppressing error: "+msg - return nil - else - raise msg - end + raise "root node for class '"+ot_class+"' not found (available type nodes: "+types.inspect+")" end - raise "no uri in rdf: '"+owl.uri+"'" unless owl.uri and Utils.is_uri?(owl.uri) owl.ot_class = ot_class owl @@ -98,6 +91,8 @@ module OpenTox return nil unless val if val.is_a?(Redland::Literal) return val.value + elsif val.blank? + return nil else return val.uri.to_s end diff --git a/lib/rest_client_wrapper.rb b/lib/rest_client_wrapper.rb index 7b3e148..f917e35 100644 --- a/lib/rest_client_wrapper.rb +++ b/lib/rest_client_wrapper.rb @@ -31,13 +31,13 @@ module OpenTox end class WrapperResult < String - attr_accessor :content_type + attr_accessor :content_type, :code end class RestClientWrapper - def self.get(uri, headers=nil) - execute( "get", uri, headers) + def self.get(uri, headers=nil, wait=true) + execute( "get", uri, headers, nil, wait) end def self.post(uri, headers, payload=nil, wait=true) @@ -79,35 +79,14 @@ module OpenTox # result is a string, with the additional filed content_type res = WrapperResult.new(result.to_s) res.content_type = result.headers[:content_type] + res.code = result.code - # get result cannot be a task - return res if rest_call=="get" or !wait - return res if res.strip.size==0 + return res if res.code==200 || !wait - # try to load task from result (maybe task-uri, or task-object) - task = nil - case res.content_type - when /application\/rdf\+xml|text\/x-yaml/ - task = OpenTox::Task.from_data(res, res.content_type, uri, true) - when /text\// - return res if res.content_type=~/text\/uri-list/ and - res.split("\n").size > 1 #if uri list contains more then one uri, its not a task - task = OpenTox::Task.find(res.to_s) if Utils.task_uri?(res) - else - raise "unknown content-type when checking for task: "+res.content_type+" content: "+res[0..200] - end - - # task could be loaded, wait for task to finish - if task - LOGGER.debug "result is a task '"+task.uri.to_s+"', wait for completion" - task.wait_for_completion - raise task.description unless task.completed? - do_halt 502,"task resultURI is invalid: '"+task.resultURI.to_s+ - "'",task.uri,nil unless task.resultURI and Utils.is_uri?(task.resultURI) - res = WrapperResult.new(task.resultURI) - LOGGER.debug "task resultURI "+res.to_s - res.content_type = "text/uri-list" + while (res.code==201 || res.code==202) + res = wait_for_task(res, uri) end + raise "illegal status code: '"+res.code.to_s+"'" unless res.code==200 return res rescue RestClient::RequestFailed => ex @@ -128,6 +107,30 @@ module OpenTox end end + def self.wait_for_task( res, base_uri ) + + task = nil + case res.content_type + when /application\/rdf\+xml|text\/x-yaml/ + task = OpenTox::Task.from_data(res, res.content_type, res.code, base_uri) + when /text\// + raise "uri list has more than one entry, should be a task" if res.content_type=~/text\/uri-list/ and + res.split("\n").size > 1 #if uri list contains more then one uri, its not a task + task = OpenTox::Task.find(res.to_s) if Utils.task_uri?(res) + else + raise "unknown content-type for task: "+res.content_type+" content: "+res[0..200] + end + + LOGGER.debug "result is a task '"+task.uri.to_s+"', wait for completion" + task.wait_for_completion + raise task.description unless task.completed? # maybe task was cancelled / error + + res = WrapperResult.new task.resultURI + res.code = task.http_code + res.content_type = "text/uri-list" + return res + end + def self.do_halt( code, body, uri, headers, payload=nil ) #build error @@ -152,13 +155,14 @@ module OpenTox # we are either in a task, or in sinatra # PENDING: always return yaml for now - if $self_task #this global var in Task.as_task to mark that the current process is running in a task raise error.to_yaml # the error is caught, logged, and task state is set to error in Task.as_task - elsif $sinatra #else halt sinatra - $sinatra.halt(502,error.to_yaml) - else - raise "internal error" + #elsif $sinatra #else halt sinatra + #$sinatra.halt(502,error.to_yaml) + elsif defined?(halt) + halt(502,error.to_yaml) + else #for testing purposes (if classes used directly) + raise error.to_yaml end end end diff --git a/lib/task.rb b/lib/task.rb index 03d5330..b686d24 100644 --- a/lib/task.rb +++ b/lib/task.rb @@ -1,7 +1,7 @@ LOGGER.progname = File.expand_path(__FILE__) -DEFAULT_TASK_MAX_DURATION = 120 -EXTERNAL_TASK_MAX_DURATION = 60 +DEFAULT_TASK_MAX_DURATION = 360 +EXTERNAL_TASK_MAX_DURATION = 120 $self_task=nil @@ -12,7 +12,8 @@ module OpenTox # due_to_time is only set in local tasks TASK_ATTRIBS = [ :uri, :date, :title, :creator, :title, :description, :hasStatus, :percentageCompleted, :resultURI, :due_to_time ] TASK_ATTRIBS.each{ |a| attr_accessor(a) } - + attr_accessor :http_code + private def initialize(uri) @uri = uri.to_s.strip @@ -31,24 +32,20 @@ module OpenTox return task end - # test_if_task = true -> error suppressed if data is no task, nil is returned - def self.from_data(data, content_type, base_uri, test_if_task) + def self.from_data(data, content_type, code, base_uri) task = Task.new(nil) - task.reload_from_data(data, content_type, base_uri, test_if_task) - if test_if_task and (!task.uri or task.uri.strip.size==0) - return nil - else - return task - end + task.http_code = code + task.reload_from_data(data, content_type, base_uri) + return task end def reload - result = RestClientWrapper.get(uri, {:accept => 'application/rdf+xml'})#'text/x-yaml'}) - reload_from_data(result, result.content_type, uri, false) + result = RestClientWrapper.get(uri, {:accept => 'application/rdf+xml'}, false)#'text/x-yaml'}) + @http_code = result.code + reload_from_data(result, result.content_type, uri) end - # test_if_task = true -> error suppressed if data is no task, empty task is returned - def reload_from_data( data, content_type, base_uri, test_if_task ) + def reload_from_data( data, content_type, base_uri ) case content_type when /text\/x-yaml/ task = YAML.load data @@ -57,15 +54,13 @@ module OpenTox send("#{a.to_s}=".to_sym,task[a]) end when /application\/rdf\+xml/ - owl = OpenTox::Owl.from_data(data,base_uri,"Task",test_if_task) - if owl - self.uri = owl.uri - (TASK_ATTRIBS-[:uri]).each{|a| self.send("#{a.to_s}=".to_sym, owl.get(a.to_s))} - end + owl = OpenTox::Owl.from_data(data,base_uri,"Task") + self.uri = owl.uri + (TASK_ATTRIBS-[:uri]).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 - raise "uri is null after loading" unless @uri and @uri.to_s.strip.size>0 unless test_if_task + raise "uri is null after loading" unless @uri and @uri.to_s.strip.size>0 end def cancel @@ -104,20 +99,44 @@ module OpenTox if (@uri.match(@@config[:services]["opentox-task"])) due_to_time = Time.parse(@due_to_time) + running_time = due_to_time - Time.parse(@date) else # the date of the external task cannot be trusted, offest to local time might be to big due_to_time = Time.new + EXTERNAL_TASK_MAX_DURATION + running_time = EXTERNAL_TASK_MAX_DURATION end LOGGER.debug "start waiting for task "+@uri.to_s+" at: "+Time.new.to_s+", waiting at least until "+due_to_time.to_s + while self.running? sleep dur reload + check_state if (Time.new > due_to_time) - raise "max waiting time exceeded, task seems to be stalled, task: '"+@uri.to_s+"'" + raise "max wait time exceeded ("+running_time.to_s+"sec), task: '"+@uri.to_s+"'" end end + + LOGGER.debug "task no longer running: "+@uri.to_s+", result: "+@resultURI.to_s end + def check_state + begin + raise "illegal task state, task is completed, resultURI is no URI: '"+@resultURI.to_s+ + "'" unless @resultURI and Utils.is_uri?(@resultURI) if completed? + + if @http_code == 202 + raise "illegal task state, code is 202, but hasStatus is not Running: '"+@hasStatus+"'" unless running? + elsif @http_code == 201 + raise "illegal task state, code is 201, but hasStatus is not Completed: '"+@hasStatus+"'" unless completed? + raise "illegal task state, code is 201, resultURI is no task-URI: '"+@resultURI.to_s+ + "'" unless @resultURI and Utils.task_uri?(@resultURI) + end + rescue => ex + RestClientWrapper.raise_uri_error(ex.message, @uri) + end + + end + # returns the task uri # catches halts and exceptions, task state is set to error then def self.as_task(max_duration=DEFAULT_TASK_MAX_DURATION) |