Class: SequenceServer::Job
- Inherits:
-
Object
- Object
- SequenceServer::Job
- Extended by:
- Forwardable
- Includes:
- FileUtils
- Defined in:
- lib/sequenceserver/job.rb
Overview
Abstract job super class.
Provides a simple framework to store job data, execute shell commands asynchronously and capture stdout, stderr and exit status. Subclasses must provide a concrete implementation for ‘command` and may override any other methods as required.
Global ‘config` and `logger` object are available as instance methods.
Singleton methods provide the facility to create and queue a job, fetch a job or all jobs, and delete a job.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#completed_at ⇒ Object
readonly
Returns the value of attribute completed_at.
-
#exitstatus ⇒ Object
readonly
Returns the value of attribute exitstatus.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#submitted_at ⇒ Object
readonly
Returns the value of attribute submitted_at.
Class Method Summary collapse
-
.all ⇒ Object
Returns an Array of all jobs.
-
.create(params) ⇒ Object
Creates and queues a job.
-
.delete(id) ⇒ Object
Deletes job with the given id.
-
.enqueue(job) ⇒ Object
Enqueues a job that is already created, returns the job object.
-
.fetch(id) ⇒ Object
Fetches job with the given id.
- .serializable_classes ⇒ Object
Instance Method Summary collapse
-
#command ⇒ Object
Returns shell command that will be executed.
-
#dir ⇒ Object
Where to save all kind of data for this job.
-
#done? ⇒ Boolean
Is exitstatus of the job available? If yes, it means the job is done.
-
#initialize(params = {}) ⇒ Job
constructor
Initialize the job: generates a job id, creates directory where all kind of job data will be held, yields (if block given) and saves the job.
-
#raise! ⇒ Object
Raise RuntimeError if job finished with non-zero exit status.
-
#run ⇒ Object
Shell out and execute the job.
-
#stderr ⇒ Object
Where will the stderr be written to during execution and read from later.
-
#stdout ⇒ Object
Where will the stdout be written to during execution and read from later.
Constructor Details
#initialize(params = {}) ⇒ Job
Initialize the job: generates a job id, creates directory where all kind of job data will be held, yields (if block given) and saves the job.
Subclasses should extend ‘initialize` as per requirement.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/sequenceserver/job.rb', line 87 def initialize(params = {}) @id = params.fetch(:id, SecureRandom.uuid) @submitted_at = Time.now mkdir_p dir yield if block_given? save rescue Errno::ENOSPC raise SystemError, 'Not enough disk space to start a new job' rescue Errno::EACCES raise SystemError, "Permission denied to write to #{DOTDIR}" rescue StandardError => e rm_rf dir raise e end |
Instance Attribute Details
#completed_at ⇒ Object (readonly)
Returns the value of attribute completed_at.
102 103 104 |
# File 'lib/sequenceserver/job.rb', line 102 def completed_at @completed_at end |
#exitstatus ⇒ Object (readonly)
Returns the value of attribute exitstatus.
102 103 104 |
# File 'lib/sequenceserver/job.rb', line 102 def exitstatus @exitstatus end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
102 103 104 |
# File 'lib/sequenceserver/job.rb', line 102 def id @id end |
#submitted_at ⇒ Object (readonly)
Returns the value of attribute submitted_at.
102 103 104 |
# File 'lib/sequenceserver/job.rb', line 102 def submitted_at @submitted_at end |
Class Method Details
.all ⇒ Object
Returns an Array of all jobs.
58 59 60 61 |
# File 'lib/sequenceserver/job.rb', line 58 def all Dir["#{DOTDIR}/**/job.yaml"] .map { |f| fetch File.basename File.dirname f } end |
.create(params) ⇒ Object
Creates and queues a job. Returns created job object.
26 27 28 29 |
# File 'lib/sequenceserver/job.rb', line 26 def create(params) job = BLAST::Job.new(params) # TODO: Dynamic dispatch. enqueue(job) end |
.delete(id) ⇒ Object
Deletes job with the given id.
53 54 55 |
# File 'lib/sequenceserver/job.rb', line 53 def delete(id) FileUtils.rm_r File.join(DOTDIR, id) end |
.enqueue(job) ⇒ Object
Enqueues a job that is already created, returns the job object
64 65 66 67 |
# File 'lib/sequenceserver/job.rb', line 64 def enqueue(job) pool.queue { job.run } job end |
.fetch(id) ⇒ Object
Fetches job with the given id.
42 43 44 45 46 47 48 49 50 |
# File 'lib/sequenceserver/job.rb', line 42 def fetch(id) job_file = File.join(DOTDIR, id, 'job.yaml') return nil unless File.exist?(job_file) YAML.safe_load_file( job_file, permitted_classes: serializable_classes ) end |
.serializable_classes ⇒ Object
31 32 33 34 35 36 37 38 39 |
# File 'lib/sequenceserver/job.rb', line 31 def serializable_classes [ Time, Symbol, SequenceServer::Job, SequenceServer::BLAST::Job, SequenceServer::Database ] end |
Instance Method Details
#command ⇒ Object
Returns shell command that will be executed. Subclass needs to provide a concrete implementation.
106 107 108 |
# File 'lib/sequenceserver/job.rb', line 106 def command fail 'Not implemented.' end |
#dir ⇒ Object
Where to save all kind of data for this job.
143 144 145 |
# File 'lib/sequenceserver/job.rb', line 143 def dir File.join(DOTDIR, id) end |
#done? ⇒ Boolean
Is exitstatus of the job available? If yes, it means the job is done.
121 122 123 |
# File 'lib/sequenceserver/job.rb', line 121 def done? !!@exitstatus end |
#raise! ⇒ Object
Raise RuntimeError if job finished with non-zero exit status. This method should be called on a completed job before attempting to use the results. Subclasses should provide their own implementation.
128 129 130 |
# File 'lib/sequenceserver/job.rb', line 128 def raise! fail if done? && exitstatus != 0 end |
#run ⇒ Object
Shell out and execute the job.
NOTE: This method is called asynchronously by thread pool.
113 114 115 116 117 118 |
# File 'lib/sequenceserver/job.rb', line 113 def run sys(command, path: config[:bin], stdout: stdout, stderr: stderr) done! rescue CommandFailed => e done! e.exitstatus end |
#stderr ⇒ Object
Where will the stderr be written to during execution and read from later.
138 139 140 |
# File 'lib/sequenceserver/job.rb', line 138 def stderr File.join(dir, 'stderr') end |
#stdout ⇒ Object
Where will the stdout be written to during execution and read from later.
133 134 135 |
# File 'lib/sequenceserver/job.rb', line 133 def stdout File.join(dir, 'stdout') end |