taverna-player 0.5.0 → 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/.gitignore +1 -0
- data/.travis.yml +8 -0
- data/CHANGES.rdoc +47 -0
- data/README.rdoc +43 -3
- data/Rakefile +1 -4
- data/app/assets/stylesheets/taverna_player/coderay.css +30 -20
- data/app/controllers/taverna_player/application_controller.rb +2 -2
- data/app/controllers/taverna_player/job_queue_controller.rb +18 -0
- data/app/models/taverna_player/run.rb +10 -3
- data/app/views/taverna_player/job_queue/index.html.erb +47 -0
- data/app/views/taverna_player/runs/_interaction.html.erb +7 -1
- data/app/views/taverna_player/runs/embedded/new.html.erb +1 -1
- data/config/locales/en.yml +36 -0
- data/config/routes.rb +4 -1
- data/db/migrate/20140226135723_change_taverna_player_runs_status_message_to_use_keys.rb +19 -0
- data/lib/generators/taverna_player/install_generator.rb +6 -1
- data/lib/generators/templates/ReadMe.txt +6 -0
- data/lib/generators/templates/controllers/job_queue_controller.rb +19 -0
- data/lib/generators/templates/player_initializer.rb +8 -0
- data/lib/tasks/delete-cancelled-runs.rake +1 -1
- data/lib/taverna-player.rb +9 -1
- data/lib/taverna_player/concerns/controllers/job_queue_controller.rb +38 -0
- data/lib/taverna_player/concerns/controllers/runs_controller.rb +2 -13
- data/lib/taverna_player/concerns/models/run.rb +22 -9
- data/lib/taverna_player/concerns/models/run_port.rb +5 -0
- data/lib/taverna_player/port_renderer.rb +1 -1
- data/lib/taverna_player/version.rb +1 -1
- data/lib/taverna_player/worker.rb +78 -51
- data/taverna_player.gemspec +7 -5
- data/test/dummy/app/views/home/index.html.erb +1 -1
- data/test/dummy/app/views/layouts/application.html.erb +2 -1
- data/test/dummy/config/application.rb +1 -0
- data/test/dummy/config/initializers/taverna_player.rb +8 -3
- data/test/dummy/config/locales/taverna_player.en.yml +36 -0
- data/test/dummy/db/migrate/20140226143013_change_taverna_player_runs_status_message_to_use_keys.taverna_player.rb +20 -0
- data/test/dummy/db/schema.rb +9 -9
- data/test/dummy/lib/callbacks.rb +1 -5
- data/test/fixtures/files/non-ascii.csv +30 -0
- data/test/fixtures/taverna_player/interactions.yml +4 -1
- data/test/fixtures/taverna_player/runs.yml +6 -1
- data/test/functional/taverna_player/job_queue_controller_test.rb +35 -0
- data/test/functional/taverna_player/runs_controller_test.rb +20 -0
- data/test/functional/taverna_player/service_credentials_controller_test.rb +3 -3
- data/test/test_helper.rb +4 -1
- data/test/unit/helpers/taverna_player/runs_helper_test.rb +20 -1
- data/test/unit/taverna_player/run_port_test.rb +41 -5
- data/test/unit/{utils_test.rb → taverna_player/utils_test.rb} +0 -0
- data/test/unit/taverna_player/worker_test.rb +201 -0
- metadata +67 -18
- data/test/fixtures/files/crassostrea_gigas.csv +0 -737
data/config/routes.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
class ChangeTavernaPlayerRunsStatusMessageToUseKeys < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
rename_column :taverna_player_runs, :status_message, :status_message_key
|
4
|
+
|
5
|
+
TavernaPlayer::Run.all.each do |run|
|
6
|
+
run.status_message_key = run.saved_state
|
7
|
+
run.save
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def down
|
12
|
+
rename_column :taverna_player_runs, :status_message_key, :status_message
|
13
|
+
|
14
|
+
TavernaPlayer::Run.all.each do |run|
|
15
|
+
run.status_message = run.saved_state.capitalize
|
16
|
+
run.save
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#------------------------------------------------------------------------------
|
2
|
-
# Copyright (c) 2013 The University of Manchester, UK.
|
2
|
+
# Copyright (c) 2013, 2014 The University of Manchester, UK.
|
3
3
|
#
|
4
4
|
# BSD Licenced. See LICENCE.rdoc for details.
|
5
5
|
#
|
@@ -25,6 +25,11 @@ module TavernaPlayer
|
|
25
25
|
"config/initializers/taverna_server.rb.example"
|
26
26
|
end
|
27
27
|
|
28
|
+
def copy_locale
|
29
|
+
copy_file "../../../config/locales/en.yml",
|
30
|
+
"config/locales/taverna_player.en.yml"
|
31
|
+
end
|
32
|
+
|
28
33
|
def show_readme
|
29
34
|
readme "ReadMe.txt" if behavior == :invoke
|
30
35
|
end
|
@@ -23,6 +23,12 @@ Taverna Player configuration, leaving the sensitive parts out.
|
|
23
23
|
In your application's install instructions remember to tell your users to copy
|
24
24
|
the example initializer and configure their Taverna Server information.
|
25
25
|
|
26
|
+
A locale file has also been installed to:
|
27
|
+
|
28
|
+
config/locales/taverna_player.en.yml
|
29
|
+
|
30
|
+
Please edit this to suit your application if required.
|
31
|
+
|
26
32
|
There is also some manual setup to do, if you haven't already done it:
|
27
33
|
|
28
34
|
1. Mount the Taverna Player engine in your config/routes.rb. For example:
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#------------------------------------------------------------------------------
|
2
|
+
# Copyright (c) 2014 The University of Manchester, UK.
|
3
|
+
#
|
4
|
+
# BSD Licenced. See LICENCE.rdoc for details.
|
5
|
+
#
|
6
|
+
# Taverna Player was developed in the BioVeL project, funded by the European
|
7
|
+
# Commission 7th Framework Programme (FP7), through grant agreement
|
8
|
+
# number 283359.
|
9
|
+
#
|
10
|
+
# Author: Robert Haines
|
11
|
+
#------------------------------------------------------------------------------
|
12
|
+
|
13
|
+
module TavernaPlayer
|
14
|
+
class JobQueueController < TavernaPlayer::ApplicationController
|
15
|
+
# Do not remove the next line.
|
16
|
+
include TavernaPlayer::Concerns::Controllers::JobQueueController
|
17
|
+
# Extend the JobQueueControllerController here.
|
18
|
+
end
|
19
|
+
end
|
@@ -42,6 +42,14 @@ TavernaPlayer.setup do |config|
|
|
42
42
|
# or use :rails_root for the root directory of your application.
|
43
43
|
#config.file_store = ":rails_root/public/system"
|
44
44
|
|
45
|
+
# If you would like to use a different namespace for admin type resources
|
46
|
+
# you can configure it here. Defaults to the empty string.
|
47
|
+
#config.admin_scope = "admin"
|
48
|
+
|
49
|
+
# The queue name for Taverna Player's delayed jobs to be run. Whatever you
|
50
|
+
# use here be sure to start delayed job workers listening to this queue.
|
51
|
+
#config.job_queue_name = "player"
|
52
|
+
|
45
53
|
# Callbacks to be run at various points during a workflow run. These can be
|
46
54
|
# defined as Proc objects or as methods and referenced by name.
|
47
55
|
#
|
data/lib/taverna-player.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#------------------------------------------------------------------------------
|
2
|
-
# Copyright (c) 2013 The University of Manchester, UK.
|
2
|
+
# Copyright (c) 2013, 2014 The University of Manchester, UK.
|
3
3
|
#
|
4
4
|
# BSD Licenced. See LICENCE.rdoc for details.
|
5
5
|
#
|
@@ -99,6 +99,10 @@ module TavernaPlayer
|
|
99
99
|
mattr_accessor :file_store
|
100
100
|
@@file_store = ":rails_root/public/system"
|
101
101
|
|
102
|
+
# Admin scope for system configuration routes.
|
103
|
+
mattr_accessor :admin_scope
|
104
|
+
@@admin_scope = ""
|
105
|
+
|
102
106
|
# Taverna server polling interval (in seconds)
|
103
107
|
mattr_accessor :server_poll_interval
|
104
108
|
@@server_poll_interval = 5
|
@@ -111,6 +115,10 @@ module TavernaPlayer
|
|
111
115
|
mattr_accessor :server_connection
|
112
116
|
@@server_connection = T2Server::DefaultConnectionParameters.new
|
113
117
|
|
118
|
+
# Queue on which to create workflow execution jobs
|
119
|
+
mattr_accessor :job_queue_name
|
120
|
+
@@job_queue_name = "player"
|
121
|
+
|
114
122
|
# Pre run callback
|
115
123
|
mattr_accessor :pre_run_callback
|
116
124
|
@@pre_run_callback = nil
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#------------------------------------------------------------------------------
|
2
|
+
# Copyright (c) 2014 The University of Manchester, UK.
|
3
|
+
#
|
4
|
+
# BSD Licenced. See LICENCE.rdoc for details.
|
5
|
+
#
|
6
|
+
# Taverna Player was developed in the BioVeL project, funded by the European
|
7
|
+
# Commission 7th Framework Programme (FP7), through grant agreement
|
8
|
+
# number 283359.
|
9
|
+
#
|
10
|
+
# Author: Robert Haines
|
11
|
+
#------------------------------------------------------------------------------
|
12
|
+
|
13
|
+
module TavernaPlayer
|
14
|
+
module Concerns
|
15
|
+
module Controllers
|
16
|
+
module JobQueueController
|
17
|
+
|
18
|
+
extend ActiveSupport::Concern
|
19
|
+
|
20
|
+
included do
|
21
|
+
respond_to :html
|
22
|
+
|
23
|
+
before_filter :find_jobs
|
24
|
+
|
25
|
+
def find_jobs
|
26
|
+
@jobs = Delayed::Job.find_all_by_queue(TavernaPlayer.job_queue_name)
|
27
|
+
end
|
28
|
+
end # included
|
29
|
+
|
30
|
+
# GET job_queue
|
31
|
+
def index
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -32,8 +32,6 @@ module TavernaPlayer
|
|
32
32
|
before_filter :filter_update_parameters, :only => :update
|
33
33
|
before_filter :find_interaction, :only => [ :read_interaction, :write_interaction ]
|
34
34
|
|
35
|
-
layout :choose_layout
|
36
|
-
|
37
35
|
private
|
38
36
|
|
39
37
|
def find_runs
|
@@ -87,15 +85,6 @@ module TavernaPlayer
|
|
87
85
|
send_data @port.value, :type => type, :filename => @port.filename
|
88
86
|
end
|
89
87
|
|
90
|
-
# Choose a layout for the page depending on action and embedded status.
|
91
|
-
def choose_layout
|
92
|
-
if (action_name == "new" || action_name == "show") && @run.embedded?
|
93
|
-
"taverna_player/embedded"
|
94
|
-
else
|
95
|
-
ApplicationController.new.send(:_layout).virtual_path
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
88
|
end # included
|
100
89
|
|
101
90
|
# GET /runs
|
@@ -119,7 +108,7 @@ module TavernaPlayer
|
|
119
108
|
respond_with(@run) do |format|
|
120
109
|
# Render show.{html|js}.erb unless the run is embedded.
|
121
110
|
format.any(:html, :js) do
|
122
|
-
render "taverna_player/runs/embedded/show" if @run.embedded
|
111
|
+
render "taverna_player/runs/embedded/show", :layout => "taverna_player/embedded" if @run.embedded
|
123
112
|
end
|
124
113
|
end
|
125
114
|
end
|
@@ -129,7 +118,7 @@ module TavernaPlayer
|
|
129
118
|
respond_with(@run) do |format|
|
130
119
|
# Render new.html.erb unless the run is embedded.
|
131
120
|
format.html do
|
132
|
-
render "taverna_player/runs/embedded/new" if @run.embedded
|
121
|
+
render "taverna_player/runs/embedded/new", :layout => "taverna_player/embedded" if @run.embedded
|
133
122
|
end
|
134
123
|
end
|
135
124
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#------------------------------------------------------------------------------
|
2
|
-
# Copyright (c) 2013 The University of Manchester, UK.
|
2
|
+
# Copyright (c) 2013, 2014 The University of Manchester, UK.
|
3
3
|
#
|
4
4
|
# BSD Licenced. See LICENCE.rdoc for details.
|
5
5
|
#
|
@@ -20,7 +20,7 @@ module TavernaPlayer
|
|
20
20
|
included do
|
21
21
|
attr_accessible :create_time, :delayed_job, :embedded, :finish_time,
|
22
22
|
:inputs_attributes, :log, :name, :parent_id, :results, :run_id,
|
23
|
-
:start_time, :
|
23
|
+
:start_time, :status_message_key, :user_id, :workflow_id
|
24
24
|
|
25
25
|
# Each run is spawned from a workflow. This provides the link to the
|
26
26
|
# workflow model in the parent app, whatever it calls its model.
|
@@ -48,7 +48,8 @@ module TavernaPlayer
|
|
48
48
|
|
49
49
|
accepts_nested_attributes_for :inputs
|
50
50
|
|
51
|
-
STATES = ["pending", "initialized", "running", "finished",
|
51
|
+
STATES = ["pending", "initialized", "running", "finished",
|
52
|
+
"cancelled", "timeout", "failed"]
|
52
53
|
|
53
54
|
validates :workflow_id, :presence => true
|
54
55
|
validates :name, :presence => true
|
@@ -65,18 +66,20 @@ module TavernaPlayer
|
|
65
66
|
# needs to be checked on update because on create we don't have an
|
66
67
|
# id for ourself.
|
67
68
|
validates :parent_id, :numericality => { :less_than => :id,
|
68
|
-
:message => "
|
69
|
+
:message => I18n.t("taverna_player.errors.invalid-parent") },
|
69
70
|
:allow_nil => true, :on => :update
|
70
71
|
|
71
72
|
has_attached_file :log,
|
72
73
|
:path => File.join(TavernaPlayer.file_store, ":class/:attachment/:id/:filename"),
|
73
74
|
:url => "/runs/:id/download/log",
|
74
75
|
:default_url => ""
|
76
|
+
do_not_validate_attachment_file_type :log
|
75
77
|
|
76
78
|
has_attached_file :results,
|
77
79
|
:path => File.join(TavernaPlayer.file_store, ":class/:attachment/:id/:filename"),
|
78
80
|
:url => "/runs/:id/download/results",
|
79
81
|
:default_url => ""
|
82
|
+
do_not_validate_attachment_file_type :results
|
80
83
|
|
81
84
|
after_initialize :initialize_child_run, :if => "new_record? && has_parent?"
|
82
85
|
after_create :populate_child_inputs, :if => :has_parent?
|
@@ -106,8 +109,8 @@ module TavernaPlayer
|
|
106
109
|
|
107
110
|
def enqueue
|
108
111
|
worker = TavernaPlayer::Worker.new(self)
|
109
|
-
job = Delayed::Job.enqueue worker, :queue =>
|
110
|
-
update_attributes(:delayed_job => job, :
|
112
|
+
job = Delayed::Job.enqueue worker, :queue => TavernaPlayer.job_queue_name
|
113
|
+
update_attributes(:delayed_job => job, :status_message_key => "pending")
|
111
114
|
end
|
112
115
|
|
113
116
|
end # included
|
@@ -144,7 +147,7 @@ module TavernaPlayer
|
|
144
147
|
if delayed_job.locked_by.nil?
|
145
148
|
delayed_job.destroy
|
146
149
|
update_attribute(:saved_state, "cancelled")
|
147
|
-
update_attribute(:
|
150
|
+
update_attribute(:status_message_key, "cancelled")
|
148
151
|
end
|
149
152
|
end
|
150
153
|
end
|
@@ -173,6 +176,11 @@ module TavernaPlayer
|
|
173
176
|
self[:saved_state] = s
|
174
177
|
end
|
175
178
|
|
179
|
+
def status_message
|
180
|
+
key = status_message_key.nil? ? saved_state : status_message_key
|
181
|
+
I18n.t("taverna_player.status.#{key}")
|
182
|
+
end
|
183
|
+
|
176
184
|
def running?
|
177
185
|
state == :running
|
178
186
|
end
|
@@ -189,13 +197,18 @@ module TavernaPlayer
|
|
189
197
|
state == :cancelling
|
190
198
|
end
|
191
199
|
|
200
|
+
def timeout?
|
201
|
+
state == :timeout
|
202
|
+
end
|
203
|
+
|
192
204
|
def failed?
|
193
205
|
state == :failed
|
194
206
|
end
|
195
207
|
|
196
|
-
# This is used as a catch-all for finished, cancelled and
|
208
|
+
# This is used as a catch-all for finished, cancelled, failed and
|
209
|
+
# timeout
|
197
210
|
def complete?
|
198
|
-
finished? || cancelled? || failed?
|
211
|
+
finished? || cancelled? || failed? || timeout?
|
199
212
|
end
|
200
213
|
|
201
214
|
def has_parent?
|
@@ -37,6 +37,7 @@ module TavernaPlayer
|
|
37
37
|
:path => File.join(TavernaPlayer.file_store, ":class/:attachment/:id/:filename"),
|
38
38
|
:url => :file_url_via_run,
|
39
39
|
:default_url => ""
|
40
|
+
do_not_validate_attachment_file_type :file
|
40
41
|
|
41
42
|
default_scope order("lower(name) ASC")
|
42
43
|
|
@@ -159,6 +160,10 @@ module TavernaPlayer
|
|
159
160
|
end
|
160
161
|
end
|
161
162
|
|
163
|
+
def value=(v)
|
164
|
+
self[:value] = v.force_encoding("BINARY")
|
165
|
+
end
|
166
|
+
|
162
167
|
def path(*indices)
|
163
168
|
index = [*indices].flatten
|
164
169
|
path = index.empty? ? "" : "/" + index.join("/")
|
@@ -15,12 +15,16 @@ module TavernaPlayer
|
|
15
15
|
include TavernaPlayer::Concerns::Callback
|
16
16
|
include TavernaPlayer::Concerns::Zip
|
17
17
|
|
18
|
+
attr_reader :run
|
19
|
+
|
18
20
|
# How to get the interaction presentation frame out of the interaction page.
|
19
21
|
INTERACTION_REGEX = /document\.getElementById\(\'presentationFrame\'\)\.src = \"(.+)\";/
|
20
22
|
|
21
|
-
|
23
|
+
# The workflow file to be run can be specified explicitly or it will be
|
24
|
+
# taken from the workflow model.
|
25
|
+
def initialize(run, workflow_file = nil)
|
22
26
|
@run = run
|
23
|
-
@workflow = TavernaPlayer.workflow_proxy.
|
27
|
+
@workflow = workflow_file || TavernaPlayer.workflow_proxy.file(@run.workflow)
|
24
28
|
end
|
25
29
|
|
26
30
|
# This tells delayed_job to only try and complete each run once.
|
@@ -29,12 +33,9 @@ module TavernaPlayer
|
|
29
33
|
end
|
30
34
|
|
31
35
|
def perform
|
32
|
-
unless TavernaPlayer.pre_run_callback
|
33
|
-
status_message "Running pre-run tasks"
|
34
|
-
callback(TavernaPlayer.pre_run_callback, @run)
|
35
|
-
end
|
36
|
+
return unless run_callback(TavernaPlayer.pre_run_callback, "pre-callback")
|
36
37
|
|
37
|
-
status_message
|
38
|
+
status_message("connect")
|
38
39
|
|
39
40
|
server_uri = URI.parse(TavernaPlayer.server_address)
|
40
41
|
credentials = T2Server::HttpBasic.new(TavernaPlayer.server_username,
|
@@ -43,14 +44,14 @@ module TavernaPlayer
|
|
43
44
|
|
44
45
|
begin
|
45
46
|
server = T2Server::Server.new(server_uri, conn_params)
|
46
|
-
wkf = File.read(
|
47
|
+
wkf = File.read(@workflow)
|
47
48
|
|
48
49
|
# Try and create the run bearing in mind that the server might be at
|
49
50
|
# the limit of runs that it can hold at once.
|
50
51
|
begin
|
51
52
|
run = server.create_run(wkf, credentials)
|
52
53
|
rescue T2Server::ServerAtCapacityError
|
53
|
-
status_message
|
54
|
+
status_message("full")
|
54
55
|
|
55
56
|
if cancelled?
|
56
57
|
cancel
|
@@ -61,7 +62,7 @@ module TavernaPlayer
|
|
61
62
|
retry
|
62
63
|
end
|
63
64
|
|
64
|
-
status_message
|
65
|
+
status_message("initialized")
|
65
66
|
|
66
67
|
@run.run_id = run.id
|
67
68
|
@run.state = run.status
|
@@ -69,7 +70,7 @@ module TavernaPlayer
|
|
69
70
|
@run.save
|
70
71
|
|
71
72
|
unless @run.inputs.size == 0
|
72
|
-
status_message
|
73
|
+
status_message("inputs")
|
73
74
|
@run.inputs.each do |input|
|
74
75
|
unless input.file.blank?
|
75
76
|
run.input_port(input.name).file = input.file.path
|
@@ -84,13 +85,13 @@ module TavernaPlayer
|
|
84
85
|
run.add_password_credential(cred.uri, cred.login, cred.password)
|
85
86
|
end
|
86
87
|
|
87
|
-
status_message
|
88
|
+
status_message("start")
|
88
89
|
run.name = @run.name
|
89
90
|
|
90
91
|
# Try and start the run bearing in mind that the server might be at
|
91
92
|
# the limit of runs that it can run at once.
|
92
93
|
while !run.start
|
93
|
-
status_message
|
94
|
+
status_message("busy")
|
94
95
|
|
95
96
|
if cancelled?
|
96
97
|
cancel(run)
|
@@ -104,7 +105,7 @@ module TavernaPlayer
|
|
104
105
|
@run.start_time = run.start_time
|
105
106
|
@run.save
|
106
107
|
|
107
|
-
status_message
|
108
|
+
status_message("running")
|
108
109
|
until run.finished?
|
109
110
|
sleep(TavernaPlayer.server_poll_interval)
|
110
111
|
waiting = false
|
@@ -116,7 +117,7 @@ module TavernaPlayer
|
|
116
117
|
|
117
118
|
run.notifications(:requests).each do |note|
|
118
119
|
if @run.has_parent?
|
119
|
-
next if note.has_reply?
|
120
|
+
next if note.has_reply? || note.is_notification?
|
120
121
|
int = Interaction.find_by_run_id_and_serial(@run.parent_id, note.serial)
|
121
122
|
new_int = Interaction.find_or_initialize_by_run_id_and_serial(@run.id, note.serial)
|
122
123
|
if new_int.new_record?
|
@@ -154,6 +155,10 @@ module TavernaPlayer
|
|
154
155
|
end
|
155
156
|
end
|
156
157
|
|
158
|
+
if note.is_notification? && !int.new_record?
|
159
|
+
int.replied = true
|
160
|
+
end
|
161
|
+
|
157
162
|
if int.data.blank?
|
158
163
|
int.data = note.input_data.force_encoding("UTF-8")
|
159
164
|
end
|
@@ -169,10 +174,10 @@ module TavernaPlayer
|
|
169
174
|
end
|
170
175
|
end
|
171
176
|
|
172
|
-
status_message(waiting ? "
|
177
|
+
status_message(waiting ? "interact" : "running")
|
173
178
|
end
|
174
179
|
|
175
|
-
status_message
|
180
|
+
status_message("outputs")
|
176
181
|
download_outputs(run)
|
177
182
|
download_log(run)
|
178
183
|
|
@@ -182,41 +187,35 @@ module TavernaPlayer
|
|
182
187
|
|
183
188
|
run.delete
|
184
189
|
rescue => exception
|
185
|
-
|
186
|
-
unless run.nil?
|
187
|
-
download_log(run)
|
188
|
-
run.delete
|
189
|
-
end
|
190
|
-
rescue
|
191
|
-
# Try and grab the log then delete the run from Taverna Server here,
|
192
|
-
# but at this point we don't care if we fail...
|
193
|
-
end
|
194
|
-
|
195
|
-
unless TavernaPlayer.run_failed_callback.nil?
|
196
|
-
status_message "Running post-failure tasks"
|
197
|
-
callback(TavernaPlayer.run_failed_callback, @run)
|
198
|
-
end
|
199
|
-
|
200
|
-
backtrace = exception.backtrace.join("\n")
|
201
|
-
@run.failure_message = "#{exception.message}\n#{backtrace}"
|
202
|
-
|
203
|
-
@run.state = :failed
|
204
|
-
@run.finish_time = Time.now
|
205
|
-
status_message "Failed"
|
190
|
+
failed(exception, run)
|
206
191
|
return
|
207
192
|
end
|
208
193
|
|
209
|
-
unless TavernaPlayer.post_run_callback
|
210
|
-
status_message "Running post-run tasks"
|
211
|
-
callback(TavernaPlayer.post_run_callback, @run)
|
212
|
-
end
|
194
|
+
return unless run_callback(TavernaPlayer.post_run_callback, "post-callback")
|
213
195
|
|
214
196
|
@run.state = :finished
|
215
|
-
status_message
|
197
|
+
status_message("finished")
|
216
198
|
end
|
217
199
|
|
218
200
|
private
|
219
201
|
|
202
|
+
# Run the specified callback and return false on error so that we know to
|
203
|
+
# return out of the worker code completely.
|
204
|
+
def run_callback(cb, message)
|
205
|
+
unless cb.nil?
|
206
|
+
status_message(message)
|
207
|
+
begin
|
208
|
+
callback(cb, @run)
|
209
|
+
rescue => exception
|
210
|
+
failed(exception)
|
211
|
+
return false
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
# no errors
|
216
|
+
true
|
217
|
+
end
|
218
|
+
|
220
219
|
def download_log(run)
|
221
220
|
Dir.mktmpdir(run.id, Rails.root.join("tmp")) do |tmp_dir|
|
222
221
|
tmp_file_name = File.join(tmp_dir, "log.txt")
|
@@ -282,8 +281,8 @@ module TavernaPlayer
|
|
282
281
|
File.new(tmp_file)
|
283
282
|
end
|
284
283
|
|
285
|
-
def status_message(
|
286
|
-
@run.
|
284
|
+
def status_message(key)
|
285
|
+
@run.status_message_key = key
|
287
286
|
@run.save!
|
288
287
|
end
|
289
288
|
|
@@ -295,21 +294,49 @@ module TavernaPlayer
|
|
295
294
|
end
|
296
295
|
|
297
296
|
def cancel(run = nil)
|
298
|
-
status_message
|
297
|
+
status_message("cancel")
|
299
298
|
|
300
299
|
unless run.nil?
|
301
300
|
download_log(run)
|
302
301
|
run.delete
|
303
302
|
end
|
304
303
|
|
305
|
-
unless TavernaPlayer.run_cancelled_callback
|
306
|
-
status_message "Running post-cancel tasks"
|
307
|
-
callback(TavernaPlayer.run_cancelled_callback, @run)
|
308
|
-
end
|
304
|
+
return unless run_callback(TavernaPlayer.run_cancelled_callback, "cancel-callback")
|
309
305
|
|
310
306
|
@run.state = :cancelled
|
311
307
|
@run.finish_time = Time.now
|
312
|
-
status_message
|
308
|
+
status_message("cancelled")
|
309
|
+
end
|
310
|
+
|
311
|
+
def failed(exception, run = nil)
|
312
|
+
begin
|
313
|
+
unless run.nil?
|
314
|
+
download_log(run)
|
315
|
+
run.delete
|
316
|
+
end
|
317
|
+
rescue
|
318
|
+
# Try and grab the log then delete the run from Taverna Server here,
|
319
|
+
# but at this point we don't care if we fail...
|
320
|
+
end
|
321
|
+
|
322
|
+
unless TavernaPlayer.run_failed_callback.nil?
|
323
|
+
status_message("fail-callback")
|
324
|
+
|
325
|
+
begin
|
326
|
+
callback(TavernaPlayer.run_failed_callback, @run)
|
327
|
+
rescue
|
328
|
+
# Again, nothing we can really do here, so...
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
backtrace = exception.backtrace.join("\n")
|
333
|
+
@run.failure_message = "#{exception.message}\n#{backtrace}"
|
334
|
+
|
335
|
+
@run.finish_time = Time.now
|
336
|
+
|
337
|
+
state = exception.instance_of?(Delayed::WorkerTimeout) ? :timeout : :failed
|
338
|
+
@run.state = state
|
339
|
+
status_message(state.to_s)
|
313
340
|
end
|
314
341
|
|
315
342
|
end
|