lowdown 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,188 +0,0 @@
1
- require "thread"
2
-
3
- module Lowdown
4
- # A collection of internal threading related helpers.
5
- #
6
- module Threading
7
- # This class performs jobs on a private thread, provides lifecycle callbacks, and sends exceptions onto its parent
8
- # thread.
9
- #
10
- class Consumer
11
- # @param [Thread::Queue] queue
12
- # a queue instance. Provide a `Thread::SizedQueue` if you want queue of a max size.
13
- #
14
- # @param [Thread] parent_thread
15
- # the thread to send exceptions to.
16
- #
17
- def initialize(queue: Thread::Queue.new, parent_thread: Thread.current)
18
- @queue, @parent_thread = queue, parent_thread
19
- @thread = Thread.new(&method(:main))
20
- end
21
-
22
- # Schedules a job to be performed.
23
- #
24
- # @return [void]
25
- #
26
- def enqueue(&job)
27
- queue << job
28
- end
29
-
30
- # Kills the private thread.
31
- #
32
- # @return [void]
33
- #
34
- def kill
35
- thread.kill
36
- end
37
-
38
- # @return [Boolean]
39
- # whether or not the private thread is still alive.
40
- #
41
- def alive?
42
- thread.alive?
43
- end
44
-
45
- # @return [Boolean]
46
- # whether or not there are any scheduled jobs left in the queue.
47
- #
48
- def empty?
49
- queue.empty?
50
- end
51
-
52
- protected
53
-
54
- # @return [Thread]
55
- # the private thread.
56
- #
57
- attr_reader :thread
58
-
59
- # @return [Thread]
60
- # the thread to send exceptions to.
61
- #
62
- attr_reader :parent_thread
63
-
64
- # @return [Thread::Queue]
65
- # the jobs queue.
66
- #
67
- attr_reader :queue
68
-
69
- # This represents the full lifecycle of the consumer thread. It performs the individual events, catches uncaught
70
- # exceptions and sends those to the parent thread, and performs cleanup.
71
- #
72
- # Subclasses should override the individual events.
73
- #
74
- # @note This method is ran on the private thread.
75
- #
76
- # @return [void]
77
- #
78
- def main
79
- pre_runloop
80
- runloop
81
- rescue Exception => exception
82
- parent_thread.raise(exception)
83
- ensure
84
- post_runloop
85
- end
86
-
87
- # Ran _before_ any jobs are performed.
88
- #
89
- # @note (see #main)
90
- #
91
- # @return [void]
92
- #
93
- def pre_runloop
94
- end
95
-
96
- # The loop that performs scheduled jobs.
97
- #
98
- # @note (see #main)
99
- #
100
- # @return [void]
101
- #
102
- def runloop
103
- loop { perform_job(non_block: false) }
104
- end
105
-
106
- # Ran when the thread is killed or an uncaught exception occurred.
107
- #
108
- # This kills the consumer thread, which means that any cleanup you need to perform should be done *before* calling
109
- # this `super` implementation.
110
- #
111
- # @note (see #main)
112
- #
113
- # @return [void]
114
- #
115
- def post_runloop
116
- thread.kill
117
- end
118
-
119
- # @param [Boolean] non_block
120
- # whether or not the thread should be halted if there are no jobs to perform.
121
- #
122
- # @param [Array<Object>] arguments
123
- # arguments that should be passed to the invoked job.
124
- #
125
- # @return [void]
126
- #
127
- def perform_job(non_block:, arguments: nil)
128
- queue.pop(non_block).call(*arguments)
129
- rescue ThreadError
130
- end
131
- end
132
-
133
- # A simple thread-safe counter.
134
- #
135
- class Counter
136
- # @param [Integer] value
137
- # the initial count.
138
- #
139
- def initialize(value = 0)
140
- @value = value
141
- @mutex = Mutex.new
142
- end
143
-
144
- # @return [Integer]
145
- # the current count.
146
- #
147
- def value
148
- value = nil
149
- @mutex.synchronize { value = @value }
150
- value
151
- end
152
-
153
- # @return [Boolean]
154
- # whether or not the current count is zero.
155
- #
156
- def zero?
157
- value.zero?
158
- end
159
-
160
- # @param [Integer] value
161
- # the new count.
162
- #
163
- # @return [Integer]
164
- # the input value.
165
- #
166
- def value=(value)
167
- @mutex.synchronize { @value = value }
168
- value
169
- end
170
-
171
- # Increments the current count.
172
- #
173
- # @return [void]
174
- #
175
- def increment!
176
- @mutex.synchronize { @value += 1 }
177
- end
178
-
179
- # Decrements the current count.
180
- #
181
- # @return [void]
182
- #
183
- def decrement!
184
- @mutex.synchronize { @value -= 1 }
185
- end
186
- end
187
- end
188
- end