Module: DirectoryWatcher::Threaded

Included in:
Collector, Notifier, Scanner
Defined in:
lib/directory_watcher/threaded.rb

Overview

Synopsis

The Threaded module is used to perform some activity at a specified interval.

Details

Sometimes it is useful for an object to have its own thread of execution to perform a task at a recurring interval. The Threaded module encapsulates this functionality so you don’t have to write it yourself. It can be used with any object that responds to the run method.

The threaded object is run by calling the start method. This will create a new thread that will invoke the run method at the desired interval. Just before the thread is created the before_starting method will be called (if it is defined by the threaded object). Likewise, after the thread is created the after_starting method will be called (if it is defined by the threaded object).

The threaded object is stopped by calling the stop method. This sets an internal flag and then wakes up the thread. The thread gracefully exits after checking the flag. Like the start method, before and after methods are defined for stopping as well. Just before the thread is stopped the before_stopping method will be called (if it is defined by the threaded object). Likewise, after the thread has died the after_stopping method will be called (if it is defined by the threaded object).

Calling the join method on a threaded object will cause the calling thread to wait until the threaded object has stopped. An optional timeout parameter can be given.

Defined Under Namespace

Classes: ThreadContainer

Instance Method Summary collapse

Instance Method Details

#_activity_threadObject

:stopdoc:



207
208
209
# File 'lib/directory_watcher/threaded.rb', line 207

def _activity_thread
  @_activity_thread ||= ::DirectoryWatcher::Threaded::ThreadContainer.new(60, 0, nil, false);
end

#continue_on_error=(value) ⇒ Object

Set to true to continue running the threaded object even if an error is raised by the run method. The default behavior is to stop the activity thread when an error is raised by the run method.

A SystemExit will never be caught; it will always cause the Ruby interpreter to exit.



194
195
196
# File 'lib/directory_watcher/threaded.rb', line 194

def continue_on_error=( value )
  _activity_thread.continue_on_error = (value ? true : false)
end

#continue_on_error?Boolean

Returns true if the threaded object should continue running even if an error is raised by the run method. The default is to return false. The threaded object will stop running when an error is raised.

Returns:

  • (Boolean)


202
203
204
# File 'lib/directory_watcher/threaded.rb', line 202

def continue_on_error?
  _activity_thread.continue_on_error
end

#finished_iterations?Boolean

Returns true if the activity thread has finished its maximum number of iterations or the thread is no longer running. Returns false otherwise.

Returns:

  • (Boolean)


124
125
126
127
# File 'lib/directory_watcher/threaded.rb', line 124

def finished_iterations?
  return true unless _activity_thread.running?
  @_activity_thread.finished_iterations?
end

#intervalObject

Returns the number of seconds to sleep between invocations of the threaded object’s ‘run’ method.



157
158
159
# File 'lib/directory_watcher/threaded.rb', line 157

def interval
  _activity_thread.interval
end

#interval=(value) ⇒ Object

Sets the number of seconds to sleep between invocations of the threaded object’s ‘run’ method.

Raises:

  • (ArgumentError)


148
149
150
151
152
# File 'lib/directory_watcher/threaded.rb', line 148

def interval=( value )
  value = Float(value)
  raise ArgumentError, "Sleep interval must be >= 0" unless value >= 0
  _activity_thread.interval = value
end

#iterationsObject

Returns the number of iterations of the threaded object’s ‘run’ method completed thus far.



183
184
185
# File 'lib/directory_watcher/threaded.rb', line 183

def iterations
  _activity_thread.iterations
end

#join(limit = nil) ⇒ Object

If the activity thread is running, the calling thread will suspend execution and run the activity thread. This method does not return until the activity thread is stopped or until limit seconds have passed.

If the activity thread is not running, this method returns immediately with nil.



109
110
111
# File 'lib/directory_watcher/threaded.rb', line 109

def join( limit = nil )
  _activity_thread.join(limit) ? self : nil
end

#maximum_iterationsObject

Returns the maximum number of invocations of the threaded object’s ‘run’ method



176
177
178
# File 'lib/directory_watcher/threaded.rb', line 176

def maximum_iterations
  _activity_thread.maximum_iterations
end

#maximum_iterations=(value) ⇒ Object

Sets the maximum number of invocations of the threaded object’s ‘run’ method



164
165
166
167
168
169
170
171
# File 'lib/directory_watcher/threaded.rb', line 164

def maximum_iterations=( value )
  unless value.nil?
    value = Integer(value)
    raise ArgumentError, "maximum iterations must be >= 1" unless value >= 1
  end

  _activity_thread.maximum_iterations = value
end

#pauseObject

Stop the activity thread from doing work. This will not stop the activity thread, it will just stop it from calling the ‘run’ method on every iteration. It will also not increment the number of iterations it has run.



78
79
80
# File 'lib/directory_watcher/threaded.rb', line 78

def pause
  @_activity_thread.working = false
end

#resumeObject

Resume the activity thread



83
84
85
# File 'lib/directory_watcher/threaded.rb', line 83

def resume
  @_activity_thread.working = true
end

#runObject

This method will be called by the activity thread at the desired interval. Implementing classes are expect to provide this functionality.

Raises:

  • (NotImplementedError)


37
38
39
40
# File 'lib/directory_watcher/threaded.rb', line 37

def run
  raise NotImplementedError,
       'The run method must be defined by the threaded object.'
end

#running?Boolean

Returns true if the activity thread is running. Returns false otherwise.

Returns:

  • (Boolean)


116
117
118
# File 'lib/directory_watcher/threaded.rb', line 116

def running?
  _activity_thread.running?
end

#startObject

Start the activity thread. If already started this method will return without taking any action.

If the including class defines a ‘before_starting’ method, it will be called before the thread is created and run. Likewise, if the including class defines an ‘after_starting’ method, it will be called after the thread is created.



50
51
52
53
54
55
56
57
# File 'lib/directory_watcher/threaded.rb', line 50

def start
  return self if _activity_thread.running?

  before_starting if self.respond_to?(:before_starting)
  @_activity_thread.start self
  after_starting if self.respond_to?(:after_starting)
  self
end

#statusObject

Returns the status of threaded object.

'sleep'    : sleeping or waiting on I/O
'run'      : executing
'aborting' : aborting
false      : not running or terminated normally
nil        : terminated with an exception

If this method returns nil, then calling join on the threaded object will cause the exception to be raised in the calling thread.



140
141
142
143
# File 'lib/directory_watcher/threaded.rb', line 140

def status
  return false if _activity_thread.thread.nil?
  @_activity_thread.thread.status
end

#stopObject

Stop the activity thread. If already stopped this method will return without taking any action.

If the including class defines a ‘before_stopping’ method, it will be called before the thread is stopped. Likewise, if the including class defines an ‘after_stopping’ method, it will be called after the thread has stopped.



67
68
69
70
71
72
73
# File 'lib/directory_watcher/threaded.rb', line 67

def stop
  return self unless _activity_thread.running?

  before_stopping if self.respond_to?(:before_stopping)
  @_activity_thread.stop
  self
end

#wait(limit = nil) ⇒ Object

Wait on the activity thread. If the thread is already stopped, this method will return without taking any action. Otherwise, this method does not return until the activity thread has stopped, or a specific number of iterations has passed since this method was called.



92
93
94
95
96
97
98
99
100
# File 'lib/directory_watcher/threaded.rb', line 92

def wait( limit = nil )
  return self unless _activity_thread.running?
  initial_iterations = @_activity_thread.iterations
  loop {
    break unless @_activity_thread.running?
    break if limit and @_activity_thread.iterations > ( initial_iterations + limit )
    Thread.pass
  }
end