goru 0.3.0 → 0.4.1

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
  SHA256:
3
- metadata.gz: 65d57e96ef8a7bef1abaf43db02e461af067b60238728379b9a5e48cea91c2f9
4
- data.tar.gz: feba54796b8120fe753014a9f904c29c3e379ef50910e6cfde0507ca85d4d695
3
+ metadata.gz: ee1c8b3918ce9583f53e8d0e80c15b45ac402a33cd006b43cc022c90ddab02ae
4
+ data.tar.gz: 8f951013098962c00aca0e20ba82a3b81b6d30ccb7d36abfae333f042b9bbd53
5
5
  SHA512:
6
- metadata.gz: c65b2730c39ec515c1ab44ee83909c4ea93c53072cb33887aebafaedfeb0131a37c0b3d1bb323b79ce21acdc5248be3fefa3d19c007c9aa5c56217e9a7195541
7
- data.tar.gz: f4d7f05d63ad6ce781053946fa0d0e22ec9562b7e20fed83bca8f84441b4f6ec9c30b8b4b79fa7435cc93a76425ec793b6db7ac334aba0fddac84320777226b3
6
+ metadata.gz: 339305691d3b38927b32c5cc51040a2cd48f179956bcfc6d04648631a6508d2d4147c63a3eef4a75cdd7517a37b255e654875c66f6da60b39a37b20a64fb2028
7
+ data.tar.gz: 65fa5d90461938fac3c3857e431505ba855dabd555afb60993b6a52f4f1d3468db0d7747f433d53139fbc2b34ce600b3677aeb0c73ac79f08514732454a7c599
data/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## [v0.4.1](https://github.com/bryanp/goru/releases/tag/v0.4.1)
2
+
3
+ *released on 2023-07-29*
4
+
5
+ * `fix` [#23](https://github.com/bryanp/goru/pull/23) Handle `IOError` in io routines ([bryanp](https://github.com/bryanp))
6
+
7
+ ## [v0.4.0](https://github.com/bryanp/goru/releases/tag/v0.4.0)
8
+
9
+ *released on 2023-07-16*
10
+
11
+ * `add` [#22](https://github.com/bryanp/goru/pull/22) Add reactor as a reader to `Goru::Routine` ([bryanp](https://github.com/bryanp))
12
+ * `add` [#21](https://github.com/bryanp/goru/pull/21) Improve statuses ([bryanp](https://github.com/bryanp))
13
+ * `add` [#20](https://github.com/bryanp/goru/pull/20) Add observer pattern to routines ([bryanp](https://github.com/bryanp))
14
+ * `add` [#19](https://github.com/bryanp/goru/pull/19) Add ability to pause and resume a routine ([bryanp](https://github.com/bryanp))
15
+ * `chg` [#18](https://github.com/bryanp/goru/pull/18) Remove the unused `observer` writer from `Goru::Channel` ([bryanp](https://github.com/bryanp))
16
+
1
17
  ## [v0.3.0](https://github.com/bryanp/goru/releases/tag/v0.3.0)
2
18
 
3
19
  *released on 2023-07-10*
data/lib/goru/bridge.rb CHANGED
@@ -11,6 +11,18 @@ module Goru
11
11
  update_status
12
12
  end
13
13
 
14
+ # [public]
15
+ #
16
+ STATUS_READY = :ready
17
+
18
+ # [public]
19
+ #
20
+ STATUS_FINISHED = :finished
21
+
22
+ # [public]
23
+ #
24
+ STATUS_IDLE = :idle
25
+
14
26
  # [public]
15
27
  #
16
28
  attr_reader :status
@@ -30,9 +42,9 @@ module Goru
30
42
 
31
43
  private def status_changed
32
44
  case @status
33
- when :ready
45
+ when :STATUS_READY
34
46
  @routine.bridged
35
- when :finished
47
+ when :STATUS_FINISHED
36
48
  @channel.remove_observer(self)
37
49
  @routine.unbridge
38
50
  end
@@ -6,14 +6,14 @@ module Goru
6
6
  module Bridges
7
7
  class Readable < Bridge
8
8
  private def update_status
9
- status = if @routine.status == :finished
10
- :finished
9
+ status = if @routine.status == Routine::STATUS_FINISHED
10
+ Bridge::STATUS_FINISHED
11
11
  elsif @channel.full?
12
- :idle
12
+ Bridge::STATUS_IDLE
13
13
  elsif @channel.closed?
14
- :finished
14
+ Bridge::STATUS_FINISHED
15
15
  else
16
- :ready
16
+ Bridge::STATUS_READY
17
17
  end
18
18
 
19
19
  set_status(status)
@@ -6,14 +6,14 @@ module Goru
6
6
  module Bridges
7
7
  class Writable < Bridge
8
8
  private def update_status
9
- status = if @routine.status == :finished
10
- :finished
9
+ status = if @routine.status == Routine::STATUS_FINISHED
10
+ Bridge::STATUS_FINISHED
11
11
  elsif @channel.any?
12
- :ready
12
+ Bridge::STATUS_READY
13
13
  elsif @channel.closed?
14
- :finished
14
+ Bridge::STATUS_FINISHED
15
15
  else
16
- :idle
16
+ Bridge::STATUS_IDLE
17
17
  end
18
18
 
19
19
  set_status(status)
data/lib/goru/channel.rb CHANGED
@@ -11,10 +11,6 @@ module Goru
11
11
  @observers = Set.new
12
12
  end
13
13
 
14
- # [public]
15
- #
16
- attr_writer :observer
17
-
18
14
  # [public]
19
15
  #
20
16
  def <<(message)
data/lib/goru/reactor.rb CHANGED
@@ -21,6 +21,22 @@ module Goru
21
21
  @commands = []
22
22
  end
23
23
 
24
+ # [public]
25
+ #
26
+ STATUS_RUNNING = :running
27
+
28
+ # [public]
29
+ #
30
+ STATUS_FINISHED = :finished
31
+
32
+ # [public]
33
+ #
34
+ STATUS_IDLE = :idle
35
+
36
+ # [public]
37
+ #
38
+ STATUS_STOPPED = :stopped
39
+
24
40
  # [public]
25
41
  #
26
42
  attr_reader :status
@@ -28,7 +44,7 @@ module Goru
28
44
  # [public]
29
45
  #
30
46
  def run
31
- set_status(:running)
47
+ set_status(STATUS_RUNNING)
32
48
 
33
49
  until @stopped
34
50
  tick
@@ -36,7 +52,7 @@ module Goru
36
52
  ensure
37
53
  @timers.cancel
38
54
  @selector.close
39
- set_status(:finished)
55
+ set_status(STATUS_FINISHED)
40
56
  end
41
57
 
42
58
  private def tick
@@ -81,10 +97,10 @@ module Goru
81
97
  interval = @timers.wait_interval
82
98
 
83
99
  if interval.nil? && @routines.empty?
84
- set_status(:idle)
100
+ set_status(STATUS_IDLE)
85
101
  @scheduler.signal
86
102
  wait
87
- set_status(:running)
103
+ set_status(STATUS_RUNNING)
88
104
  elsif interval.nil?
89
105
  wait unless @routines.any?(&:ready?)
90
106
  elsif interval > 0
@@ -103,7 +119,7 @@ module Goru
103
119
  # [public]
104
120
  #
105
121
  def finished?
106
- @status == :idle || @status == :stopped
122
+ @status == STATUS_IDLE || @status == STATUS_STOPPED
107
123
  end
108
124
 
109
125
  # [public]
data/lib/goru/routine.rb CHANGED
@@ -20,14 +20,35 @@ module Goru
20
20
  def initialize(state = nil, &block)
21
21
  @state = state
22
22
  @block = block
23
- set_status(:ready)
23
+ @observers = Set.new
24
+ set_status(STATUS_READY)
24
25
  @result, @error, @reactor = nil
25
26
  @debug = true
26
27
  end
27
28
 
28
29
  # [public]
29
30
  #
30
- attr_reader :state, :status, :error
31
+ STATUS_READY = :ready
32
+
33
+ # [public]
34
+ #
35
+ STATUS_FINISHED = :finished
36
+
37
+ # [public]
38
+ #
39
+ STATUS_ERRORED = :errored
40
+
41
+ # [public]
42
+ #
43
+ STATUS_IDLE = :idle
44
+
45
+ # [public]
46
+ #
47
+ STATUS_PAUSED = :paused
48
+
49
+ # [public]
50
+ #
51
+ attr_reader :state, :status, :error, :reactor
31
52
 
32
53
  # [public]
33
54
  #
@@ -46,7 +67,7 @@ module Goru
46
67
  @block.call(self)
47
68
  rescue => error
48
69
  @error = error
49
- set_status(:errored)
70
+ set_status(STATUS_ERRORED)
50
71
  trigger(error)
51
72
  end
52
73
 
@@ -54,7 +75,7 @@ module Goru
54
75
  #
55
76
  def finished(result = nil)
56
77
  @result = result
57
- set_status(:finished)
78
+ set_status(STATUS_FINISHED)
58
79
 
59
80
  throw :continue
60
81
  end
@@ -69,7 +90,7 @@ module Goru
69
90
  #
70
91
  def result
71
92
  case @status
72
- when :errored
93
+ when STATUS_ERRORED
73
94
  raise @error
74
95
  else
75
96
  @result
@@ -79,9 +100,9 @@ module Goru
79
100
  # [public]
80
101
  #
81
102
  def sleep(seconds)
82
- set_status(:idle)
103
+ set_status(STATUS_IDLE)
83
104
  @reactor.asleep_for(seconds) do
84
- set_status(:ready)
105
+ set_status(STATUS_READY)
85
106
  end
86
107
 
87
108
  throw :continue
@@ -90,7 +111,25 @@ module Goru
90
111
  # [public]
91
112
  #
92
113
  def ready?
93
- @status == :ready
114
+ @status == STATUS_READY
115
+ end
116
+
117
+ # [public]
118
+ #
119
+ def finished?
120
+ @status == STATUS_ERRORED || @status == STATUS_FINISHED
121
+ end
122
+
123
+ # [public]
124
+ #
125
+ def pause
126
+ set_status(STATUS_PAUSED)
127
+ end
128
+
129
+ # [public]
130
+ #
131
+ def resume
132
+ set_status(STATUS_READY)
94
133
  end
95
134
 
96
135
  # [public]
@@ -103,8 +142,10 @@ module Goru
103
142
  # [public]
104
143
  #
105
144
  private def status_changed
145
+ @observers.each(&:call)
146
+
106
147
  case @status
107
- when :errored, :finished
148
+ when STATUS_ERRORED, STATUS_FINISHED
108
149
  @reactor&.routine_finished(self)
109
150
  end
110
151
  end
@@ -114,5 +155,17 @@ module Goru
114
155
  def adopted
115
156
  # noop
116
157
  end
158
+
159
+ # [public]
160
+ #
161
+ def add_observer(observer = nil, &block)
162
+ @observers << (block || observer.method(:routine_status_changed))
163
+ end
164
+
165
+ # [public]
166
+ #
167
+ def remove_observer(observer)
168
+ @observers.delete(observer)
169
+ end
117
170
  end
118
171
  end
@@ -17,9 +17,9 @@ module Goru
17
17
 
18
18
  private def status_changed
19
19
  case @status
20
- when :ready
20
+ when Routine::STATUS_READY
21
21
  @reactor&.wakeup
22
- when :finished
22
+ when Routine::STATUS_FINISHED
23
23
  @channel.remove_observer(self)
24
24
  end
25
25
 
@@ -16,11 +16,11 @@ module Goru
16
16
 
17
17
  private def update_status
18
18
  status = if @channel.any?
19
- :ready
19
+ Routine::STATUS_READY
20
20
  elsif @channel.closed?
21
- :finished
21
+ Routine::STATUS_FINISHED
22
22
  else
23
- :idle
23
+ Routine::STATUS_IDLE
24
24
  end
25
25
 
26
26
  set_status(status)
@@ -16,11 +16,11 @@ module Goru
16
16
 
17
17
  private def update_status
18
18
  status = if @channel.full?
19
- :idle
19
+ Routine::STATUS_IDLE
20
20
  elsif @channel.closed?
21
- :finished
21
+ Routine::STATUS_FINISHED
22
22
  else
23
- :ready
23
+ Routine::STATUS_READY
24
24
  end
25
25
 
26
26
  set_status(status)
@@ -19,6 +19,10 @@ module Goru
19
19
  @monitor = nil
20
20
  end
21
21
 
22
+ # [public]
23
+ #
24
+ STATUS_IO_READY = :io_ready
25
+
22
26
  # [public]
23
27
  #
24
28
  attr_reader :io, :intent
@@ -28,7 +32,7 @@ module Goru
28
32
  # [public]
29
33
  #
30
34
  def adopted
31
- set_status(:ready)
35
+ set_status(Routine::STATUS_READY)
32
36
  end
33
37
 
34
38
  # [public]
@@ -39,11 +43,11 @@ module Goru
39
43
  #
40
44
  @monitor&.interests = nil
41
45
 
42
- set_status(:io_ready)
46
+ set_status(STATUS_IO_READY)
43
47
  end
44
48
 
45
- READY_STATUSES = [:io_ready, :ready].freeze
46
- READY_BRIDGE_STATUSES = [nil, :ready].freeze
49
+ READY_STATUSES = [STATUS_IO_READY, Routine::STATUS_READY].freeze
50
+ READY_BRIDGE_STATUSES = [nil, Bridge::STATUS_READY].freeze
47
51
 
48
52
  # [public]
49
53
  #
@@ -64,8 +68,9 @@ module Goru
64
68
  rescue Errno::EAGAIN
65
69
  wait
66
70
  rescue Errno::ECONNRESET, Errno::EPIPE, EOFError
67
- finished
68
- nil
71
+ handle_io_unavailable
72
+ rescue IOError
73
+ handle_io_unavailable
69
74
  end
70
75
 
71
76
  def wait
@@ -82,8 +87,9 @@ module Goru
82
87
  rescue Errno::EAGAIN
83
88
  wait
84
89
  rescue Errno::ECONNRESET, Errno::EPIPE, EOFError
85
- finished
86
- nil
90
+ handle_io_unavailable
91
+ rescue IOError
92
+ handle_io_unavailable
87
93
  end
88
94
 
89
95
  # [public]
@@ -93,6 +99,12 @@ module Goru
93
99
  rescue Errno::EAGAIN
94
100
  wait
95
101
  rescue Errno::ECONNRESET, Errno::EPIPE, EOFError
102
+ handle_io_unavailable
103
+ rescue IOError
104
+ handle_io_unavailable
105
+ end
106
+
107
+ private def handle_io_unavailable
96
108
  finished
97
109
  nil
98
110
  end
@@ -151,7 +163,7 @@ module Goru
151
163
 
152
164
  private def status_changed
153
165
  case @status
154
- when :finished
166
+ when Routine::STATUS_FINISHED
155
167
  @reactor&.deregister(self)
156
168
  end
157
169
 
data/lib/goru/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Goru
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.1"
5
5
 
6
6
  # [public]
7
7
  #
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: goru
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bryan Powell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-10 00:00:00.000000000 Z
11
+ date: 2023-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: core-extension
@@ -121,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
121
  - !ruby/object:Gem::Version
122
122
  version: '0'
123
123
  requirements: []
124
- rubygems_version: 3.4.12
124
+ rubygems_version: 3.4.17
125
125
  signing_key:
126
126
  specification_version: 4
127
127
  summary: Concurrent routines for Ruby.