Class: TaskInfo

Inherits:
Object show all
Defined in:
lib/task_info.rb

Overview

TaskInfo represents the result of a babel call, an object with all the information that the user would be interested in relating to their task. At the simplest level, this is just the output of their job, but it also can includes profiling information (e.g., performance and cost), as well as information that may help with debugging (e.g. info about the environment we executed the task in).

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(job_data) ⇒ TaskInfo

Creates a new TaskInfo object, storing the parameters the user gave us to invoke the job for later use. The user can give us a Hash containing the parameters that the job was started with, or a String that is the JSON-dumped version of that data (also obtainable from TaskInfo objects via to_json).



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/task_info.rb', line 36

def initialize(job_data)
  if job_data.class == String
    begin
      job_data = JSON.load(job_data)
    rescue JSON::ParserError
      raise BadConfigurationException.new("job data not JSONable")
    end
  end

  if job_data.class != Hash
    raise BadConfigurationException.new("job data not a Hash")
  end
  @job_data = job_data

  # To prevent us from repeatedly grabbing (potentially) large files over the
  # network repeatedly, we keep a local, cached copy of the task's standard
  # output, error, and metadata - initially empty, but pulled in the first
  # time that the user asks for it. Since we expose this functionality through
  # the accessor methods below, we should not use attr_accessor or attr_reader
  # to directly expose this variables.
  @output = nil
  @error = nil
  @metadata = nil

  # To prevent concurrent threads from pulling in output multiple times, we
  # guard access to remotely grabbing output/error/metadata with this
  # lock.
  @lock = Mutex.new
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(id, *args, &block) ⇒ Object (private)

We would like to be able to directly call .name on anything in the metadata hash for a task. One way to avoid having to add all of these method calls ourselves and keep it in sync with whatever Neptune over AppScale offers is just to use method_missing and automatically respond to anything that is a key in the metadata hash.



145
146
147
148
149
150
151
152
# File 'lib/task_info.rb', line 145

def method_missing(id, *args, &block)
  methods_available = ()
  if methods_available[id.to_s].nil?
    super
  else
    return methods_available[id.to_s]
  end
end

Instance Attribute Details

#job_dataObject

A Hash consisting of the parameters that the user passed to babel().



28
29
30
# File 'lib/task_info.rb', line 28

def job_data
  @job_data
end

Instance Method Details

#stderrObject

Returns a string with the standard error produced by this Babel task. While all jobs should produce standard output, they may not produce standard error, so it is reasonable that this could return an empty string to the user.



85
86
87
88
89
90
91
92
93
# File 'lib/task_info.rb', line 85

def stderr
  if @error.nil?
    @lock.synchronize {
      @error = BabelHelper.wait_and_get_output(@job_data, @job_data['@error'])
    }
  end

  return @error
end

#stdoutObject

Returns a string with the standard output produced by this Babel task. If the task has not yet completed, this call blocks until it completes.



69
70
71
72
73
74
75
76
77
78
# File 'lib/task_info.rb', line 69

def stdout
  if @output.nil?
    @lock.synchronize {
      @output = BabelHelper.wait_and_get_output(@job_data,
        @job_data['@output'])
    }
  end

  return @output
end

#success?Boolean

A common operation that users may perform is asking if the task executed successfully, indicated by a return value of zero. This method provides a quick alias for that functionality.

Returns:

  • (Boolean)


105
106
107
# File 'lib/task_info.rb', line 105

def success?
  return return_value.zero?
end

#to_jsonObject

Converts this object to JSON, so that it can be written to disk or passed over the network. Since our stdout/stderr/metadata objects are all locally cached, we don’t need to write them (and thus can potentially save a lot of space).



114
115
116
# File 'lib/task_info.rb', line 114

def to_json
  return JSON.dump(@job_data)
end

#to_sObject

An alias for stdout.



97
98
99
# File 'lib/task_info.rb', line 97

def to_s
  return stdout
end