Class: Roby::TaskMatcher

Inherits:
Object show all
Defined in:
lib/roby/query.rb,
lib/roby/distributed/protocol.rb

Overview

This class represents a predicate which can be used to filter tasks. To filter plan-related properties, use Query.

A TaskMatcher object is a AND combination of various tests against tasks.

Defined Under Namespace

Classes: DRoby

Constant Summary collapse

STATE_PREDICATES =
[:pending?, :running?, :finished?, :success?, :failed?].to_value_set

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeTaskMatcher

Initializes an empty TaskMatcher object



25
26
27
28
29
30
31
32
# File 'lib/roby/query.rb', line 25

def initialize
    @predicates           = ValueSet.new
    @neg_predicates       = ValueSet.new
    @owners               = Array.new
    @improved_information = ValueSet.new
    @needed_information   = ValueSet.new
    @interruptible    = nil
end

Instance Attribute Details

#argumentsObject (readonly)

Returns the value of attribute arguments.



18
19
20
# File 'lib/roby/query.rb', line 18

def arguments
  @arguments
end

#improved_informationObject (readonly)

Returns the value of attribute improved_information.



21
22
23
# File 'lib/roby/query.rb', line 21

def improved_information
  @improved_information
end

#modelObject (readonly)

Returns the value of attribute model.



18
19
20
# File 'lib/roby/query.rb', line 18

def model
  @model
end

#needed_informationObject (readonly)

Returns the value of attribute needed_information.



22
23
24
# File 'lib/roby/query.rb', line 22

def needed_information
  @needed_information
end

#neg_predicatesObject (readonly)

Returns the value of attribute neg_predicates.



19
20
21
# File 'lib/roby/query.rb', line 19

def neg_predicates
  @neg_predicates
end

#ownersObject (readonly)

Returns the value of attribute owners.



19
20
21
# File 'lib/roby/query.rb', line 19

def owners
  @owners
end

#predicatesObject (readonly)

Returns the value of attribute predicates.



19
20
21
# File 'lib/roby/query.rb', line 19

def predicates
  @predicates
end

Class Method Details

.declare_class_methods(*names) ⇒ Object

:nodoc:



96
97
98
99
100
101
102
103
# File 'lib/roby/query.rb', line 96

def declare_class_methods(*names) # :nodoc:
    names.each do |name|
 raise "no instance method #{name} on TaskMatcher" unless TaskMatcher.method_defined?(name)
 TaskMatcher.singleton_class.send(:define_method, name) do |*args|
      TaskMatcher.new.send(name, *args)
 end
    end
end

.match_predicates(*names) ⇒ Object

For each name in names, define a #name and a #not_name method. If the first is called, the matcher will match only tasks whose #name? method returns true. If the second is called, the opposite will be done.



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/roby/query.rb', line 109

def match_predicates(*names)
    names.each do |name|
 class_eval " def \#{name}\n      if neg_predicates.include?(:\#{name}?)\n  raise ArgumentError, \"trying to match (\#{name}? & !\#{name}?)\"\n     end\n      predicates << :\#{name}?\n      self\n end\n def not_\#{name}\n      if predicates.include?(:\#{name}?)\n  raise ArgumentError, \"trying to match (\#{name}? & !\#{name}?)\"\n     end\n      neg_predicates << :\#{name}?\n      self\n end\n EOD\n    end\n    declare_class_methods(*names)\n    declare_class_methods(*names.map { |n| \"not_\#{n}\" })\nend\n"

Instance Method Details

#&(other) ⇒ Object

Combines this predicate with another using a AND logical operation



210
# File 'lib/roby/query.rb', line 210

def &(other); AndTaskMatcher.new(self, other) end

#===(task) ⇒ Object

True if task matches all the criteria defined on this object.



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/roby/query.rb', line 136

def ===(task)
    return unless task.kind_of?(Roby::Task)
    if model
  return unless task.fullfills?(model)
    end
    if arguments
  return unless task.arguments.slice(*arguments.keys) == arguments
    end

    for info in improved_information
  return false if !task.improves?(info)
    end
    for info in needed_information
  return false if !task.needs?(info)
    end
    for pred in predicates
  return false if !task.send(pred)
    end
    for pred in neg_predicates
  return false if task.send(pred)
    end

    return false if !owners.empty? && !(task.owners - owners).empty?
    true
end

#droby_dump(dest, klass = DRoby) ⇒ Object

Returns an intermediate representation of self suitable to be sent to the dest peer. klass is the actual class of the intermediate representation. It is used for code reuse by subclasses of TaskMatcher.



156
157
158
159
# File 'lib/roby/distributed/protocol.rb', line 156

def droby_dump(dest, klass = DRoby)
    args = [model, arguments, improved_information, needed_information, predicates, neg_predicates, owners]
    klass.new args.droby_dump(dest)
end

#each(plan, &block) ⇒ Object

Enumerates all tasks of plan which match this TaskMatcher object



195
196
197
198
# File 'lib/roby/query.rb', line 195

def each(plan, &block)
    plan.query_each(plan.query_result_set(self), &block)
    self
end

#filter(initial_set, task_index) ⇒ Object

Filters the tasks in initial_set by using the information in task_index, and returns the result. The resulting set must include all tasks in initial_set which match with #===, but can include tasks which do not match #===



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/roby/query.rb', line 168

def filter(initial_set, task_index)
    if model
  initial_set &= task_index.by_model[model]
    end

    if !owners.empty?
  for o in owners
      if candidates = task_index.by_owner[o]
    initial_set &= candidates
      else
    return ValueSet.new
      end
  end
    end

    for pred in (predicates & STATE_PREDICATES)
  initial_set &= task_index.by_state[pred]
    end

    for pred in (neg_predicates & STATE_PREDICATES)
  initial_set -= task_index.by_state[pred]
    end

    initial_set
end

#negateObject

Returns the negation of this predicate



208
# File 'lib/roby/query.rb', line 208

def negate; NegateTaskMatcher.new(self) end

#owned_by(*ids) ⇒ Object

Finds by owners. The set of owner is added to any owner already added. Do

matcher.owners.clear

to remove all owners



84
85
86
87
# File 'lib/roby/query.rb', line 84

def owned_by(*ids)
    @owners |= ids
    self
end

#self_ownedObject

Finds tasks which we own ourselves.



90
91
92
93
# File 'lib/roby/query.rb', line 90

def self_owned
    owned_by(Roby::Distributed)
    self
end

#which_fullfills(model, arguments = nil) ⇒ Object

Shortcut to set both model and argument



35
36
37
# File 'lib/roby/query.rb', line 35

def which_fullfills(model, arguments = nil)
    with_model(model).with_model_arguments(arguments || {})
end

#which_improves(*info) ⇒ Object

Find tasks which improves information contained in info



67
68
69
70
# File 'lib/roby/query.rb', line 67

def which_improves(*info)
    improved_information.merge(info.to_value_set)
    self
end

#which_needs(*info) ⇒ Object

Find tasks which need information contained in info



73
74
75
76
# File 'lib/roby/query.rb', line 73

def which_needs(*info)
    needed_information.merge(info.to_value_set)
    self
end

#with_arguments(arguments) ⇒ Object

Find by argument (exact matching)



55
56
57
58
59
60
61
62
63
64
# File 'lib/roby/query.rb', line 55

def with_arguments(arguments)
    @arguments ||= Hash.new
    self.arguments.merge!(arguments) do |k, old, new| 
  if old != new
      raise ArgumentError, "a constraint has already been set on the #{k} argument" 
  end
  old
    end
    self
end

#with_model(model) ⇒ Object

Find by model



40
41
42
43
# File 'lib/roby/query.rb', line 40

def with_model(model)
    @model = model
    self
end

#with_model_arguments(arguments) ⇒ Object

Find by arguments defined by the model



46
47
48
49
50
51
52
# File 'lib/roby/query.rb', line 46

def with_model_arguments(arguments)
    if !model
  raise ArgumentError, "set model first"
    end
    with_arguments(arguments.slice(*model.arguments))
    self
end

#|(other) ⇒ Object

Combines this predicate with another using an OR logical operation



212
# File 'lib/roby/query.rb', line 212

def |(other); OrTaskMatcher.new(self, other) end