Class: ThreadStorm::Execution

Inherits:
Object
  • Object
show all
Defined in:
lib/thread_storm/execution.rb

Overview

Encapsulates a unit of work to be sent to the thread pool.

Constant Summary collapse

STATE_INITIALIZED =

When an execution has been created, but hasn’t been scheduled to run.

0
STATE_QUEUED =

When an execution has been scheduled to run but is waiting for an available thread.

1
STATE_STARTED =

When an execution is running on a thread.

2
STATE_FINISHED =

When an execution has finished running.

3
STATE_SYMBOLS =

A hash mapping state symbols (:initialized, :queued, :started, :finished) to their corresponding state constant values.

{
  :initialized  => STATE_INITIALIZED,
  :queued       => STATE_QUEUED,
  :started      => STATE_STARTED,
  :finished     => STATE_FINISHED
}
STATE_SYMBOLS_INVERTED =

Inverted STATE_SYMBOLS.

STATE_SYMBOLS.invert

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args, &block) ⇒ Execution

call-seq:

new(options = {}) -> Execution
new(*args){ |*args| ... } -> Execution

Create an execution. The execution will be in the :initialized state. Call ThreadStorm#execute to schedule the execution to be run and transition it into the :queued state.

Default options come from the global ThreadStorm.options. If you want options specific to a ThreadStorm instance, use ThreadStorm#new_execution.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/thread_storm/execution.rb', line 53

def initialize(*args, &block)
  if block_given?
    @args = args
    @block = block
    @options = ThreadStorm.options.dup
  elsif args.length == 0
    @args = []
    @block = nil
    @options = ThreadStorm.options.dup
  elsif args.length == 1 and args.first.kind_of?(Hash)
    @args = []
    @block = nil
    @options = ThreadStorm.options.merge(args.first)
  else
    raise ArgumentError, "illegal call-seq"
  end
  
  @state = nil
  @state_at = []
  @value = nil
  @exception = nil
  @thread = nil
  @lock = Monitor.new
  @cond = @lock.new_cond
  @callback_exceptions = {}
  
  enter_state(:initialized)
end

Instance Attribute Details

#argsObject (readonly)

The arguments passed into new or ThreadStorm#execute.



29
30
31
# File 'lib/thread_storm/execution.rb', line 29

def args
  @args
end

#blockObject (readonly)

:nodoc:



41
42
43
# File 'lib/thread_storm/execution.rb', line 41

def block
  @block
end

#exceptionObject (readonly)

If an exception was raised when running an execution, it is stored here.



35
36
37
# File 'lib/thread_storm/execution.rb', line 35

def exception
  @exception
end

#optionsObject (readonly)

Options specific to an Execution instance. Note that you cannot modify the options once ThreadStorm#execute has been called on the execution.



39
40
41
# File 'lib/thread_storm/execution.rb', line 39

def options
  @options
end

#threadObject (readonly)

:nodoc:



41
42
43
# File 'lib/thread_storm/execution.rb', line 41

def thread
  @thread
end

#valueObject (readonly)

The value returned by the execution’s code block. This implicitly calls join.



32
33
34
# File 'lib/thread_storm/execution.rb', line 32

def value
  @value
end

Instance Method Details

#callback_exception(state = nil) ⇒ Object



221
222
223
224
225
226
227
# File 'lib/thread_storm/execution.rb', line 221

def callback_exception(state = nil)
  if state
    @callback_exceptions[state]
  else
    @callback_exceptions
  end
end

#callback_exception?(state = nil) ⇒ Boolean

Returns:

  • (Boolean)


217
218
219
# File 'lib/thread_storm/execution.rb', line 217

def callback_exception?(state = nil)
  ![nil, {}].include?(callback_exception(state))
end

#define(*args, &block) ⇒ Object

This code:

execution = ThreadStorm::Execution.new
execution.define(1, 2, 3){ |a1, a2, a3| ... some code ... }

Is equivalent to:

ThreadStorm::Execution.new(1, 2, 3){ |a1, a2, a3| ... some code ... }

The advantage is that you can use the first form of Execution.new to pass in options.



88
89
90
91
92
# File 'lib/thread_storm/execution.rb', line 88

def define(*args, &block)
  @args = args
  @block = block
  self
end

#duration(state = :started) ⇒ Object

How long an execution was (or has been) in a given state. state can be either a state constant or symbol.



157
158
159
160
161
162
163
164
165
166
# File 'lib/thread_storm/execution.rb', line 157

def duration(state = :started)
  state = state_to_const(state)
  if state == @state
    Time.now - state_at(state)
  elsif state < @state and state_at(state)
    next_state_at(state) - state_at(state)
  else
    nil
  end
end

#executeObject

:nodoc:



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/thread_storm/execution.rb', line 174

def execute #:nodoc:
  timeout           = options[:timeout]
  timeout_method    = options[:timeout_method]
  timeout_exception = options[:timeout_exception]
  default_value     = options[:default_value]
  
  @thread = Thread.current
  enter_state(STATE_STARTED)
  
  begin
    timeout_method.call(timeout){ @value = @block.call(*args) }
  rescue timeout_exception => e
    @exception = e
    @value = default_value
  rescue Exception => e
    @exception = e
    @value = default_value
  ensure
    enter_state(STATE_FINISHED)
  end
end

#failure?Boolean Also known as: exception?

True if this execution raised an exception.

Returns:

  • (Boolean)


202
203
204
# File 'lib/thread_storm/execution.rb', line 202

def failure?
  !!@exception and !timeout?
end

#finished?Boolean

Returns true if the execution is currently in the :finished state.

Returns:

  • (Boolean)


125
126
127
# File 'lib/thread_storm/execution.rb', line 125

def finished?
  state?(STATE_FINISHED)
end

#finished_atObject

When this execution entered the :finished state.



151
152
153
# File 'lib/thread_storm/execution.rb', line 151

def finished_at
  state_at(:finished)
end

#initialized?Boolean

Returns true if the execution is currently in the :initialized state.

Returns:

  • (Boolean)


110
111
112
# File 'lib/thread_storm/execution.rb', line 110

def initialized?
  state?(STATE_INITIALIZED)
end

#initialized_atObject

When this execution entered the :initialized state.



136
137
138
# File 'lib/thread_storm/execution.rb', line 136

def initialized_at
  state_at(:initialized)
end

#joinObject

Block until this execution has finished running.



230
231
232
233
234
# File 'lib/thread_storm/execution.rb', line 230

def join
  @lock.synchronize{ @cond.wait_until{ finished? } }
  raise exception if exception? and options[:reraise]
  true
end

#queued!Object

This is soley for ThreadStorm to put the execution into the queued state.



169
170
171
172
# File 'lib/thread_storm/execution.rb', line 169

def queued! #:nodoc:
  options.freeze
  enter_state(STATE_QUEUED)
end

#queued?Boolean

Returns true if the execution is currently in the :queued state.

Returns:

  • (Boolean)


115
116
117
# File 'lib/thread_storm/execution.rb', line 115

def queued?
  state?(STATE_QUEUED)
end

#queued_atObject

When this execution entered the :queued state.



141
142
143
# File 'lib/thread_storm/execution.rb', line 141

def queued_at
  state_at(:queued)
end

#started?Boolean

Returns true if the execution is currently in the :started state.

Returns:

  • (Boolean)


120
121
122
# File 'lib/thread_storm/execution.rb', line 120

def started?
  state?(STATE_STARTED)
end

#started_atObject

When this execution entered the :started state.



146
147
148
# File 'lib/thread_storm/execution.rb', line 146

def started_at
  state_at(:started)
end

#state(how = :const) ⇒ Object

Returns the state of an execution. If how is set to :sym, returns the state as symbol.



95
96
97
98
99
100
101
# File 'lib/thread_storm/execution.rb', line 95

def state(how = :const)
  if how == :sym
    STATE_SYMBOLS_INVERTED[@state] or raise RuntimeError, "invalid state: #{@state.inspect}"
  else
    @state
  end
end

#state?(state) ⇒ Boolean

Returns true if the execution is currently in the given state. state can be either a state constant or symbol.

Returns:

  • (Boolean)


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

def state?(state)
  self.state == state_to_const(state)
end

#state_at(state) ⇒ Object

Returns the time when the execution entered the given state. state can be either a state constant or symbol.



131
132
133
# File 'lib/thread_storm/execution.rb', line 131

def state_at(state)
  @state_at[state_to_const(state)]
end

#success?Boolean

True if the execution finished without failure (exception) or timeout.

Returns:

  • (Boolean)


197
198
199
# File 'lib/thread_storm/execution.rb', line 197

def success?
  !exception? and !timeout?
end

#timeout?Boolean Also known as: timed_out?

True if the execution went over the timeout limit.

Returns:

  • (Boolean)


210
211
212
# File 'lib/thread_storm/execution.rb', line 210

def timeout?
  !!@exception and @exception.kind_of?(options[:timeout_exception])
end