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 |