wires 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 20865bb4eb206ffbcbbf1213093615337bcfddb8
4
- data.tar.gz: 765995fb8eaa1bda0dbf45f9cfd87317c17cd3f5
3
+ metadata.gz: d72f9190bfd10374aa6b7a6dd5b6514cda1cd439
4
+ data.tar.gz: 09da831c965785c1fa55faaf48f1276ecec12d2c
5
5
  SHA512:
6
- metadata.gz: cbd2971bd9d192b39cc20f97b3f301eb8175ac25cb1548db7f0e5ffeb1461cf777dcf377ed700d3694f80b9f39bc3017ccf0bf7cb236141cbde96b99e233776b
7
- data.tar.gz: c85542dec7dabf46d30a7108dd71a83c2fd3791dc9f1956555c6fc4ed623f411e9bf878d772f6dac6344f3a1307787ec65cb81bef0635c4c81845ab03de7a1d2
6
+ metadata.gz: 0187c7ade4378ebaa10f861e3e0f9c20a60b84ce319c914644b0a598c7274a8ee054c12708aab0843557152e66ae2adbbc13cf05fbbf7037d0072caa0e3ca023
7
+ data.tar.gz: c00baf917ecbfca83f43cbefac1877c1eecfb14043f4834863288cbf777ecb66c0c328d4dfd1a6701a74de2ab593d8d60ee1404fd92417bb3fad9635d4999fa1
data/lib/wires/event.rb CHANGED
@@ -103,7 +103,7 @@ module Wires
103
103
  att = key.to_s
104
104
  obj.instance_variable_set("@#{att}", kwargs[key])
105
105
  class_eval("def #{att}; @#{att}; end")
106
- class_eval("def #{att}=(val); @#{att}=val; end")
106
+ # class_eval("def #{att}=(val); @#{att}=val; end")
107
107
  end
108
108
 
109
109
  obj
data/lib/wires/hub.rb CHANGED
@@ -6,8 +6,8 @@ module Wires
6
6
  # An Event Hub. Event/proc associations come in, and the procs
7
7
  # get called in new threads in the order received
8
8
  class Hub
9
+
9
10
  @queue = Queue.new
10
- @state = [:dead, :alive, :dying][0]
11
11
 
12
12
  @child_threads = Array.new
13
13
  @child_threads_lock = Mutex.new
@@ -18,13 +18,8 @@ module Wires
18
18
  # Operate on the metaclass as a type of singleton pattern
19
19
  class << self
20
20
 
21
- def dead?; @state==:dead end
22
- def alive?; @state==:alive end
23
- def dying?; @state==:dying end
24
- def state; @state end
25
-
26
- # Clear the Hub queue, but do not kill working threads
27
- def clear; @queue.clear end
21
+ def dead?; state==:dead end
22
+ def alive?; state==:alive end
28
23
 
29
24
  ##
30
25
  # Start the Hub event loop (optional flags change thread behavior)
@@ -35,24 +30,13 @@ module Wires
35
30
  # specified, the Hub event loop is run in a new thread,
36
31
  # which the main thread joins in at_exit.
37
32
  def run(*flags)
38
- if dead? # Only run if not already alive or dying
39
-
40
- # If :blocking is not set, run in a new thread and join at_exit
41
- if not (flags.include? :blocking)
42
- @thread = Thread.new() do
43
- self.send(:run_loop)
44
- end
45
- # Only join if main thread wasn't killed by an exception
46
- at_exit { @thread.join if not $! }
47
-
48
- # If :blocking is set, run in main thread and block until Hub death
49
- else self.send(:run_loop) end
50
-
51
- end
33
+ request_state :alive until alive?
52
34
 
53
- sleep 0 # Yield to other threads
54
-
55
- nil end
35
+ # If :blocking, block now, else block at exit
36
+ (flags.include? :blocking) ?
37
+ (join_hegemon_auto_thread) :
38
+ (at_exit { join_hegemon_auto_thread unless $! })
39
+ end
56
40
 
57
41
  ##
58
42
  # Kill the Hub event loop (optional flags change thread behavior)
@@ -61,9 +45,9 @@ module Wires
61
45
  # [+:finish_all+] Hub thread won't be done until all child threads done
62
46
  # [+:blocking+] calling thread won't be done until Hub thread is done
63
47
  def kill(*flags)
64
- @finish_all = (flags.include? :finish_all)
65
- @state=:dying
66
- @thread.join if (dying? and flags.include? :blocking)
48
+ @please_finish_all = (flags.include? :finish_all)
49
+ @please_kill = true
50
+ block_until_state :dead if (flags.include? :blocking)
67
51
  nil end
68
52
 
69
53
  # Register hook to execute before kill - can call multiple times
@@ -91,28 +75,25 @@ module Wires
91
75
  nil end
92
76
  def <<(x); fire(x); end
93
77
 
78
+ def flush_queue
79
+ (process_item(@queue.shift) until @queue.empty?)
80
+ end
81
+
82
+
94
83
  private
95
-
96
- # Kill all currently working child threads
97
- # Newly fired events could still queue up,
98
- # Waiting to be born until this thread is done killing
99
- def kill_children
100
- @child_threads_lock.synchronize do
101
- until @child_threads.empty?
102
- @child_threads.shift.exit
103
- end
104
- end
105
- nil end
106
84
 
107
- # Kill all currently working child threads
108
- # Newly fired events could still queue up,
109
- # But they will be cleared out and never be born
110
- def kill_children_and_clear
111
- @child_threads_lock.synchronize do
112
- until @child_threads.empty?
113
- @child_threads.shift.exit
114
- end
115
- clear
85
+
86
+ # Flush/run queue of [proc, retain]s, retaining those with retain==true
87
+ def run_hooks(hooks)
88
+ retained = Queue.new
89
+ while not hooks.empty?
90
+ proc, retain = hooks.shift
91
+ retained << [proc, retain] if retain
92
+ proc.call
93
+ flush_queue if alive?
94
+ end
95
+ while not retained.empty?
96
+ hooks << retained.shift
116
97
  end
117
98
  nil end
118
99
 
@@ -123,47 +104,33 @@ module Wires
123
104
  @child_threads_lock.synchronize do
124
105
  a_thread = @child_threads.shift
125
106
  end
107
+ flush_queue if alive?
126
108
  a_thread.join if a_thread
127
109
  sleep 0 # Yield to other threads
128
110
  end
129
111
  nil end
130
112
 
131
- # Flush/run queue of [proc, retain]s, retaining those with retain==true
132
- def run_hooks(queue)
133
- retained = Queue.new
134
- while not queue.empty?
135
- proc, retain = queue.shift
136
- retained << [proc, retain] if retain
137
- proc.call
138
- end
139
- while not retained.empty?
140
- queue << retained.shift
113
+ # Kill all currently working child threads
114
+ # Newly fired events could still queue up,
115
+ # Waiting to be born until this thread is done killing
116
+ def kill_children
117
+ @child_threads_lock.synchronize do
118
+ until @child_threads.empty?
119
+ @child_threads.shift.exit
120
+ end
141
121
  end
142
122
  nil end
143
-
144
- # Run before_kill hooks, optionally join child threads, then die
145
- def die
146
- run_hooks(@before_kills)
147
- join_children if @finish_all
148
- @state = :dead
149
- nil end
150
123
 
151
- # Run main event loop, not finished until Hub is killed
152
- def run_loop
153
- @state = :alive
154
-
155
- while not dead?
156
- if @queue.empty? then sleep(0)
157
- else process_item(@queue.shift) end
158
-
159
- if dying?
160
- die_thread ||= Thread.new { die }
124
+ # Kill all currently working child threads
125
+ # Newly fired events could still queue up,
126
+ # But they will be cleared out and never be born
127
+ def kill_children_and_clear
128
+ @child_threads_lock.synchronize do
129
+ until @child_threads.empty?
130
+ @child_threads.shift.exit
161
131
  end
132
+ clear
162
133
  end
163
-
164
- run_hooks(@after_kills)
165
- @finish_all = false
166
-
167
134
  nil end
168
135
 
169
136
  def process_item(x)
@@ -178,28 +145,62 @@ module Wires
178
145
 
179
146
  # Start the new child thread
180
147
  @child_threads << Thread.new do
181
- begin
182
- waiting_thread.wakeup unless blocking or not waiting_thread
183
- proc.call(event)
184
- waiting_thread.wakeup if blocking and waiting_thread
185
-
186
- rescue Interrupt, SystemExit => e
187
- @state = :dying
188
- unhandled_exception(e)
189
-
190
- rescue Exception => e
191
- unhandled_exception(e)
192
- end
148
+ waiting_thread.wakeup unless blocking or not waiting_thread
149
+ proc.call(event)
150
+ waiting_thread.wakeup if blocking and waiting_thread
193
151
  end
194
-
195
152
  end
196
-
197
153
  nil end
198
154
 
199
- def unhandled_exception(x)
200
- $stderr.puts $!
201
- $stderr.puts $@
202
- nil end
203
155
  end
156
+
157
+
158
+ #***
159
+ # Initialize state machine properties
160
+ #***
161
+ class << self
162
+ include Hegemon
163
+ def state_machine_init
164
+
165
+ impose_state :dead
166
+
167
+ declare_state :dead do
168
+ # task { puts "I'm dead!" }
169
+
170
+ transition_to :alive do
171
+ after { start_hegemon_auto_thread }
172
+ end
173
+ end
174
+
175
+ declare_state :alive do
176
+ # task { puts "I'm alive!" }
177
+ # task { sleep 0.05 }
178
+ task do
179
+ # puts "task #{Thread.current.inspect}";
180
+ if @queue.empty? then sleep(0)
181
+ else process_item(@queue.shift) end
182
+ end
183
+
184
+ transition_to :dead do
185
+ condition {@please_kill}
186
+
187
+ before { run_hooks @before_kills }
188
+
189
+ before { join_children if @please_finish_all }
190
+
191
+ after { run_hooks @after_kills }
192
+
193
+ after { @please_kill = false }
194
+ after { @please_finish_all = false }
195
+
196
+ after { end_hegemon_auto_thread }
197
+ after { do_state_tasks }
198
+ end
199
+ end
200
+
201
+ end
202
+ end
203
+ state_machine_init
204
+
204
205
  end
205
206
  end
data/lib/wires.rb CHANGED
@@ -2,6 +2,7 @@ require 'set'
2
2
  require 'thread'
3
3
  require 'active_support/core_ext' # Convenience functions from Rails
4
4
  require 'threadlock' # Easily add re-entrant lock to instance methods
5
+ require 'hegemon' # State machine management
5
6
 
6
7
  require 'wires/expect_type'
7
8
  require 'wires/event'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wires
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joe McIlvain
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-06 00:00:00.000000000 Z
11
+ date: 2013-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: hegemon
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rake
43
57
  requirement: !ruby/object:Gem::Requirement