Class: Thread::Every

Inherits:
Object
  • Object
show all
Defined in:
lib/thread/every.rb

Overview

An every runs the given block every given seconds, you can then get the value, check if the value is old and you can check how many seconds until the next run.

Constant Summary collapse

Cancel =
Class.new(Exception)
Restart =
Class.new(Exception)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(every, &block) ⇒ Every

Create an every with the given seconds and block.

Raises:

  • (ArgumentError)


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
65
66
67
# File 'lib/thread/every.rb', line 21

def initialize (every, &block)
	raise ArgumentError, 'no block given' unless block

	@every  = every
	@old    = true
	@mutex  = Mutex.new
	@thread = Thread.new {
		loop do
			begin
				value = block.call

				@mutex.synchronize {
					@at        = Time.now
 					@value     = value
					@old       = false
					@exception = nil
				}
			rescue Restart
				next
			rescue Exception => e
				@mutex.synchronize {
					@at        = Time.now
					@exception = e
				}

				break if e.is_a? Cancel
			end

			cond.broadcast if cond?

			begin
				sleep @every
			rescue Restart
				next
			rescue Cancel => e
				@mutex.synchronize {
					@at        = Time.now
					@exception = e
				}

				break
			end
		end
	}

	ObjectSpace.define_finalizer self, self.class.finalizer(@thread)
end

Class Method Details

.finalizer(thread) ⇒ Object



70
71
72
73
74
# File 'lib/thread/every.rb', line 70

def self.finalizer (thread)
	proc {
		thread.raise Cancel.new
	}
end

Instance Method Details

#called_atObject

Gets the Time when the block was called.



131
132
133
134
135
# File 'lib/thread/every.rb', line 131

def called_at
	@mutex.synchronize {
		@at
	}
end

#cancelObject

Cancel the every, #value will yield a Cancel exception.



84
85
86
87
88
89
90
# File 'lib/thread/every.rb', line 84

def cancel
	@mutex.synchronize {
		@thread.raise Cancel.new('every cancelled')
	}

	self
end

#cancelled?Boolean

Check if the every has been cancelled.

Returns:

  • (Boolean)


93
94
95
96
97
# File 'lib/thread/every.rb', line 93

def cancelled?
	@mutex.synchronize {
		@exception.is_a? Cancel
	}
end

#cancelled_atObject

Checks when the every was cancelled.



100
101
102
103
104
105
106
# File 'lib/thread/every.rb', line 100

def cancelled_at
	if cancelled?
		@mutex.synchronize {
			@at
		}
	end
end

#every(seconds) ⇒ Object

Change the number of seconds between each call.



77
78
79
80
81
# File 'lib/thread/every.rb', line 77

def every (seconds)
	@every = seconds

	restart
end

#next_inObject

Gets how many seconds are missing before another call.



138
139
140
141
142
143
144
# File 'lib/thread/every.rb', line 138

def next_in
	return if cancelled?

	@mutex.synchronize {
		@every - (Time.now - @at)
	}
end

#old?Boolean

Check if the every is old, after the first #value call it becomes old, until another run of the block is gone)

Returns:

  • (Boolean)


124
125
126
127
128
# File 'lib/thread/every.rb', line 124

def old?
	@mutex.synchronize {
		@old
	}
end

#restartObject

Restart the every.



109
110
111
112
113
114
115
# File 'lib/thread/every.rb', line 109

def restart
	@mutex.synchronize {
		@thread.raise Restart.new
	}

	self
end

#running?Boolean

Check if the every is running.

Returns:

  • (Boolean)


118
119
120
# File 'lib/thread/every.rb', line 118

def running?
	!cancelled?
end

#value(timeout = nil) ⇒ Object Also known as: ~

Gets the current every value.



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/thread/every.rb', line 147

def value (timeout = nil)
	@mutex.synchronize {
		if @old
			cond.wait(@mutex, *timeout)
		end

		@old = true

		if @exception
			raise @exception
		else
			@value
		end
	}
end

#value!Object

Gets the current every value, without blocking and waiting for the next call.



167
168
169
170
171
172
173
# File 'lib/thread/every.rb', line 167

def value!
	@mutex.synchronize {
		@old = true

		@value unless @exception
	}
end