sequenceserver 1.1.0.beta3 → 1.1.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2e60bdefc921484208426a507ff32229e5945b1b
4
- data.tar.gz: 85a162161cae976cc790ae3fed7b06ab81f11786
3
+ metadata.gz: a526ad89575f0b9118bf986359b9750a2a1ef894
4
+ data.tar.gz: 3fa16082e5bb2b99c16be95413ba0fbdf722baf4
5
5
  SHA512:
6
- metadata.gz: c4511c2651001127d25f0b319984ed4cbc5b4e4d6dccde42823b1c33fd14a99e86045d8416da1d8e514e6825df44933359d32eafe1167e0bdb30243d2017a295
7
- data.tar.gz: 3917c29dfb8be319b92029295f3996338195aa3bab09a176c625b22e1f7b7fe56588aedf8d16b8724aa07acdfbe35c1c3982a3f2a3bbf47d165745d11cef4523
6
+ metadata.gz: 2b95e0a703717cd2af830462624dcea36c10b103cffaa3fb4f80e811abe54625a070d94caefe8c05f26fc59fa41ebaa06c80091b8a0b88b0286f8597d5cea2fd
7
+ data.tar.gz: 5a4e459777fe4ecf68e1f80c0aee8aadb8b231e2dd11bbee79b51ef16f1907c2b6ff69751552daa7bca3c927b38d5f92b9b9123ae537862a016e7b368011c8f2
@@ -18,6 +18,8 @@ module SequenceServer
18
18
  def message
19
19
  'The requested job could not be found'
20
20
  end
21
+
22
+ undef_method :backtrace
21
23
  end
22
24
 
23
25
  # Errors caused due to incorrect user input.
@@ -11,20 +11,20 @@ module SequenceServer
11
11
  extend Forwardable
12
12
  def_delegators SequenceServer, :config, :logger, :sys
13
13
 
14
- def initialize(archive_file, type)
15
- @archive_file = archive_file
14
+ def initialize(job, type)
15
+ @job = job
16
16
  @format, @mime, @specifiers = OUTFMT[type]
17
17
  @type = type
18
18
 
19
19
  validate && run
20
20
  end
21
21
 
22
- attr_reader :archive_file, :type
22
+ attr_reader :job, :type
23
23
 
24
24
  attr_reader :format, :mime, :specifiers
25
25
 
26
26
  def file
27
- @file ||= File.join(File.dirname(archive_file), filename)
27
+ @file ||= File.join(job.dir, filename)
28
28
  end
29
29
 
30
30
  def filename
@@ -37,7 +37,7 @@ module SequenceServer
37
37
  def run
38
38
  return if File.exist?(file)
39
39
  command =
40
- "blast_formatter -archive '#{archive_file}'" \
40
+ "blast_formatter -archive '#{job.stdout}'" \
41
41
  " -outfmt '#{format} #{specifiers}'" \
42
42
  " -out '#{file}'"
43
43
  sys(command, path: config[:bin], dir: DOTDIR)
@@ -46,12 +46,9 @@ module SequenceServer
46
46
  end
47
47
 
48
48
  def validate
49
- return true if archive_file && format &&
50
- File.exist?(archive_file)
51
- fail InputError, <<MSG
52
- Incorrect request parameters. Please ensure that requested file name is
53
- correct and the file type is either xml or tsv.
54
- MSG
49
+ fail SystemError if !File.exist?(job.stdout) ||
50
+ File.zero?(job.stdout)
51
+ true
55
52
  end
56
53
  end
57
54
  end
@@ -33,8 +33,16 @@ module SequenceServer
33
33
 
34
34
  # BLAST's exit status is not definitive of success or error, so we
35
35
  # override success? to define custom criteria. :TODO:
36
- def success?
37
- super
36
+ def raise!
37
+ return true if exitstatus == 0
38
+
39
+ stderr = File.readlines(this.stderr)
40
+ if exitstatus == 1 # error in query sequence or options; see [1]
41
+ error = stderr.grep(ERROR_LINE)
42
+ error = stderr if error.empty?
43
+ fail InputError, error.join
44
+ end
45
+ fail SystemError, stderr.join
38
46
  end
39
47
 
40
48
  private
@@ -43,27 +43,15 @@ module SequenceServer
43
43
 
44
44
  # Generate report.
45
45
  def generate
46
- assert_job_completed_successfully
47
- xml_ir = parse_xml File.read(Formatter.run(job.stdout, 'xml').file)
48
- tsv_ir = parse_tsv File.read(Formatter.run(job.stdout, 'custom_tsv').file)
46
+ job.raise!
47
+ xml_ir = parse_xml File.read(Formatter.run(job, 'xml').file)
48
+ tsv_ir = parse_tsv File.read(Formatter.run(job, 'custom_tsv').file)
49
49
  extract_program_info xml_ir
50
50
  extract_params xml_ir
51
51
  extract_stats xml_ir
52
52
  extract_queries xml_ir, tsv_ir
53
53
  end
54
54
 
55
- def assert_job_completed_successfully
56
- return true if job.success?
57
-
58
- stderr = File.readlines(job.stderr)
59
- if job.exitstatus == 1 # error in query sequence or options; see [1]
60
- error = stderr.grep(ERROR_LINE)
61
- error = stderr if error.empty?
62
- fail InputError, error.join
63
- end
64
- fail SystemError, stderr.join
65
- end
66
-
67
55
  # Make program name and program name + version available via `program`
68
56
  # and `program_version` attributes.
69
57
  def extract_program_info(ir)
@@ -107,10 +95,6 @@ module SequenceServer
107
95
  xml_ir[8].each do |n|
108
96
  query = Query.new(self, n[0], n[2], n[3], [])
109
97
  extract_hits(n[4], tsv_ir[query.id], query)
110
- query.hits = query.hits.sort_by do |h|
111
- first_hsp = h.hsps.first # most significant hsp
112
- [first_hsp.evalue, first_hsp.score]
113
- end
114
98
  queries << query
115
99
  end
116
100
  end
@@ -131,9 +115,6 @@ module SequenceServer
131
115
  hit = Hit.new(query, n[0], n[1], n[3], n[2], n[4],
132
116
  tsv_ir[n[1]][0], tsv_ir[n[1]][1],[])
133
117
  extract_hsps(n[5], tsv_ir[n[1]][2], hit)
134
- hit.hsps = hit.hsps.sort_by do |h|
135
- [h.evalue, h.score]
136
- end
137
118
  query.hits << hit
138
119
  end
139
120
  end
@@ -63,6 +63,10 @@ module SequenceServer
63
63
  mkdir_p dir
64
64
  yield if block_given?
65
65
  save
66
+ rescue Errno::ENOSPC
67
+ raise SystemError
68
+ rescue Errno::EACCES
69
+ raise SystemError
66
70
  rescue => e
67
71
  rm_rf dir
68
72
  raise e
@@ -70,6 +74,12 @@ module SequenceServer
70
74
 
71
75
  attr_reader :id, :completed_at, :exitstatus
72
76
 
77
+ # Returns shell command that will be executed. Subclass needs to provide a
78
+ # concrete implementation.
79
+ def command
80
+ raise "Not implemented."
81
+ end
82
+
73
83
  # Shell out and execute the job.
74
84
  #
75
85
  # NOTE: This method is called asynchronously by thread pool.
@@ -80,10 +90,16 @@ module SequenceServer
80
90
  done! e.exitstatus
81
91
  end
82
92
 
83
- # Returns shell command that will be executed. Subclass needs to provide a
84
- # concrete implementation.
85
- def command
86
- raise "Not implemented."
93
+ # Is exitstatus of the job available? If yes, it means the job is done.
94
+ def done?
95
+ !!@exitstatus
96
+ end
97
+
98
+ # Raise RuntimeError if job finished with non-zero exit status. This method
99
+ # should be called on a completed job before attempting to use the results.
100
+ # Subclasses should provide their own implementation.
101
+ def raise!
102
+ raise if done? && exitstatus != 0
87
103
  end
88
104
 
89
105
  # Where will the stdout be written to during execution and read from later.
@@ -96,14 +112,9 @@ module SequenceServer
96
112
  File.join(dir, 'stderr')
97
113
  end
98
114
 
99
- # Was the job successful?
100
- def success?
101
- exitstatus == 0
102
- end
103
-
104
- # Is the job done? Yes if exitstatus of the job is available. No otherwise.
105
- def done?
106
- !!@exitstatus
115
+ # Where to save all kind of data for this job.
116
+ def dir
117
+ File.join(DOTDIR, id)
107
118
  end
108
119
 
109
120
  private
@@ -144,11 +155,6 @@ module SequenceServer
144
155
  save
145
156
  end
146
157
 
147
- # Where to save all kind of data for this job.
148
- def dir
149
- File.join(DOTDIR, id)
150
- end
151
-
152
158
  # Where to write serialised job object.
153
159
  def yfile
154
160
  File.join(dir, 'job.yaml')
@@ -8,7 +8,7 @@ module SequenceServer
8
8
  # be deleted as soon as they are done, or it can be Infinity in which case
9
9
  # jobs will never be deleted. Default is to delete finished jobs after 7 days.
10
10
  class JobRemover
11
- DEFAULT_JOB_LIFETIME = 10080 # minutes (24 hrs = 7 days)
11
+ DEFAULT_JOB_LIFETIME = 43200 # minutes (i.e., 30 days)
12
12
 
13
13
  def initialize(job_lifetime)
14
14
  @job_lifetime = job_lifetime || DEFAULT_JOB_LIFETIME
@@ -122,19 +122,38 @@ module SequenceServer
122
122
  # Download BLAST report in various formats.
123
123
  get '/download/:jid.:type' do |jid, type|
124
124
  job = Job.fetch(jid)
125
- out = BLAST::Formatter.new(job.rfile, type)
125
+ out = BLAST::Formatter.new(job, type)
126
126
  send_file out.file, :filename => out.filename, :type => out.mime
127
127
  end
128
128
 
129
- # Catches any exception raised within the app and returns error message and
130
- # the backtrace as response body. If the error class defines `http_status`
131
- # instance method, its return value will be used to set HTTP status. HTTP
132
- # status is set to 500 otherwise.
129
+ # Catches any exception raised within the app and returns JSON
130
+ # representation of the error:
131
+ # {
132
+ # title: ..., // plain text
133
+ # message: ..., // plain or HTML text
134
+ # more_info: ..., // pre-formatted text
135
+ # }
136
+ #
137
+ # If the error class defines `http_status` instance method, its return
138
+ # value will be used to set HTTP status. HTTP status is set to 500
139
+ # otherwise.
140
+ #
141
+ # If the error class defines `title` instance method, its return value
142
+ # will be used as title. Otherwise name of the error class is used as
143
+ # title.
144
+ #
145
+ # If the error class defines `more_info` instance method, its return
146
+ # value will be used as more_info, otherwise `backtrace.join("\n")`
147
+ # is used as more_info. If an error class does not want to include
148
+ # more_info (like for NotFound), the error class must undefine
149
+ # `backtrace` method.
150
+ #
151
+ # All error classes should define `message` instance method.
133
152
  error 400..500 do
134
153
  error = env['sinatra.error']
135
154
 
136
155
  # All errors will have a message.
137
- error_data = {message: error.message}
156
+ error_data = { message: error.message }
138
157
 
139
158
  # If error object has a title method, use that, or use error class for
140
159
  # title.
@@ -149,7 +168,7 @@ module SequenceServer
149
168
  # more_info.
150
169
  if error.respond_to? :more_info
151
170
  error_data[:more_info] = error.more_info
152
- else
171
+ elsif error.respond_to? :backtrace
153
172
  error_data[:more_info] = error.backtrace.join("\n")
154
173
  end
155
174
 
@@ -1,4 +1,4 @@
1
1
  # Define version number.
2
2
  module SequenceServer
3
- VERSION = '1.1.0.beta3'
3
+ VERSION = '1.1.0.beta4'
4
4
  end
@@ -28,7 +28,8 @@ a:hover, .btn-link:hover {
28
28
  * Disable resize grabber on textarea.
29
29
  */
30
30
  textarea {
31
- resize: none;
31
+ resize: vertical;
32
+ min-height: 214px;
32
33
  }
33
34
 
34
35
  /**