Class: Build::Graph::Task

Inherits:
Object
  • Object
show all
Defined in:
lib/build/graph/task.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(walker, node) ⇒ Task



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/build/graph/task.rb', line 39

def initialize(walker, node)
  @walker = walker
  
  @walker.tasks[node] = self
  
  @node = node
  @fiber = nil
  
  @error = nil
  
  # Tasks that must be complete before finishing this task.
  @children = []
  
  @state = nil
  
  @inputs_failed = false
end

Instance Attribute Details

#childrenObject (readonly)

Returns the value of attribute children.



60
61
62
# File 'lib/build/graph/task.rb', line 60

def children
  @children
end

#errorObject (readonly)

The error, if the execution of the node fails.



66
67
68
# File 'lib/build/graph/task.rb', line 66

def error
  @error
end

#inputsObject (readonly)

Returns the value of attribute inputs.



57
58
59
# File 'lib/build/graph/task.rb', line 57

def inputs
  @inputs
end

#inputs_failedObject (readonly)

A list of any inputs whose relevant tasks failed:



73
74
75
# File 'lib/build/graph/task.rb', line 73

def inputs_failed
  @inputs_failed
end

#nodeObject (readonly)

Returns the value of attribute node.



70
71
72
# File 'lib/build/graph/task.rb', line 70

def node
  @node
end

#outputsObject (readonly)

Returns the value of attribute outputs.



58
59
60
# File 'lib/build/graph/task.rb', line 58

def outputs
  @outputs
end

#stateObject (readonly)

The state of the task, one of nil, :complete or :failed.



63
64
65
# File 'lib/build/graph/task.rb', line 63

def state
  @state
end

#walkerObject (readonly)

Returns the value of attribute walker.



68
69
70
# File 'lib/build/graph/task.rb', line 68

def walker
  @walker
end

Instance Method Details

#changed!Object



147
148
149
# File 'lib/build/graph/task.rb', line 147

def changed!
  @walker.delete(@node) if (@inputs.update! or @outputs.update!)
end

#complete?Boolean



133
134
135
# File 'lib/build/graph/task.rb', line 133

def complete?
  @state == :complete
end

#directoriesObject



151
152
153
# File 'lib/build/graph/task.rb', line 151

def directories
  (@inputs.roots + @outputs.roots).collect{|path| path.to_s}
end

#dirty?Boolean

Returns true if the outputs of the task are out of date w.r.t. the inputs. Currently, does not take into account if the input is a glob and files have been added.



139
140
141
142
143
144
145
# File 'lib/build/graph/task.rb', line 139

def dirty?
  if @outputs
    @outputs.dirty?(@inputs)
  else
    true
  end
end

#failed?Boolean



129
130
131
# File 'lib/build/graph/task.rb', line 129

def failed?
  @state == :failed
end

#invoke(node) ⇒ Task

Returns the child task that was created to update the node.

Raises:

  • (ArgumentError)


119
120
121
122
123
124
125
126
127
# File 'lib/build/graph/task.rb', line 119

def invoke(node)
  child_task = @walker.call(node, self)
  
  raise ArgumentError.new("Invalid child task") unless child_task
  
  @children << child_task
  
  return child_task
end

#to_sObject



155
156
157
# File 'lib/build/graph/task.rb', line 155

def to_s
  "#<#{self.class} #{node_string} #{state_string}>"
end

#visitObject

Derived task can override this function to provide appropriate behaviour.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/build/graph/task.rb', line 76

def visit
  update_inputs_and_outputs
  
  # Inforn the walker a new task is being generated for this node:
  @walker.enter(self)
  
  if @fiber
    raise RuntimeError, "Task is already running!"
  end
  
  @fiber = Fiber.new do
    # If all inputs were good, we can update the node.
    if wait_for_inputs?
      begin
        yield
      rescue TransientError => error
        fail!(error)
      end
    else
      fail!(InputsFailed)
    end
    
    if wait_for_children?
      update_outputs
    else
      fail!(ChildrenFailed)
    end
    
    @state ||= :complete
    
    @walker.exit(self)
    
    @fiber = nil
  end
  
  # Schedule the work, hopefully synchronously:
  @fiber.resume
  
  # This allows the child task to be passed back to the parent when it is first invoked.
  return self
end