rbgo 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9125e71cafdd2fc084f39bd7ad9f3f5ffd96c8e9a93d7fe4c35e1db9f76341d
4
- data.tar.gz: 618ab2ee058c1c1538140f4a98e6ff938b34c9c521cb89af2d105a4f7cb84100
3
+ metadata.gz: ec171658e61d3d64d313126f3b3ee709565a4676624a513982c73d531c4c2ce8
4
+ data.tar.gz: 7266385dc226a8643dae466209ec674e59390fee1faabfbba39e85d578d875a6
5
5
  SHA512:
6
- metadata.gz: a0c92fe1b129173ccceacc0315285f41ab6f4ef24c0881919ac8c33f6fe66e63fdb5c4797f061537dcbf5faa31e96135e528e026cf53c6f73631d8f018086df0
7
- data.tar.gz: 314321f3953cdb3c23802f7c0d99af866101c48163c90fe314ffff7513032b4e79c249125c9be1b5610907b836604078cf0d86942d4ccf347cf96e5a20b30c9e
6
+ metadata.gz: 42f49f6cade30b7f4ebc6ac57c2ff9386d09256032cec1d87d11ca9f2b5b7f0c4b92e56c1db593066ddebfbb7f6ea208a2de9f64c721332268c0e0b10fddeba2
7
+ data.tar.gz: 637bdfec998a93e8aadbef3d84d0ffc6faf1744b41f877e8faed3de349b3a77ecc80662822dbc6816302e8b5cbe7109b1a2c0fe58b52938095eb6b90e9de260e
data/README.md CHANGED
@@ -231,12 +231,13 @@ require 'rbgo'
231
231
  using Rbgo::CoRunExtensions
232
232
 
233
233
  #localhost, port 3000
234
- tcp_service = Rbgo::NetworkServiceFactory.open_tcp_service(3000) do|sock, clientAddrInfo|
235
- p [sock, clientAddrInfo]
236
- p sock.yield_read
237
- sock.yield_write("hello")
238
- sock.close #SHOULD CLOSE SOCK MANUALLY since version 0.2.0
239
- end
234
+ tcp_service = Rbgo::NetworkServiceFactory.open_tcp_service(3000) do|sock, _|
235
+ sock.yield_read_line("\r\n\r\n") # read http request
236
+ sock.close_read
237
+ sock.yield_write("HTTP/1.1 200 OK \r\n\r\nHello World!")
238
+ sock.close_write
239
+ sock.close
240
+ end
240
241
 
241
242
 
242
243
 
data/lib/rbgo/actor.rb CHANGED
@@ -35,9 +35,10 @@ module Rbgo
35
35
  private
36
36
 
37
37
  def start_msg_loop
38
- CoRun::Routine.new(new_thread: true) do
38
+ CoRun::Routine.new(new_thread: false) do
39
39
  while msg = mail_box.deq
40
40
  handler.call(msg, self) rescue nil
41
+ Fiber.yield
41
42
  end
42
43
  end
43
44
  end
data/lib/rbgo/corun.rb CHANGED
@@ -3,6 +3,7 @@ require 'fiber'
3
3
  require 'system'
4
4
  require 'singleton'
5
5
  require_relative 'io_machine'
6
+ require_relative 'once'
6
7
 
7
8
  module Rbgo
8
9
  module CoRun
@@ -23,6 +24,16 @@ module Rbgo
23
24
  end
24
25
  end
25
26
 
27
+ def self.read_line_from(io, sep: $/, limit: nil)
28
+ if is_in_corun_fiber?
29
+ return "" if limit == 0
30
+ receipt = Scheduler.instance.io_machine.do_read_line(io, sep: sep, limit: limit)
31
+ Fiber.yield [YIELD_IO_OPERATION, receipt]
32
+ else
33
+ io.readline(sep, limit)
34
+ end
35
+ end
36
+
26
37
  def self.write_to(io, str:)
27
38
  if is_in_corun_fiber?
28
39
  receipt = Scheduler.instance.io_machine.do_write(io, str: str)
@@ -49,7 +60,8 @@ module Rbgo
49
60
  self.blk = blk
50
61
  if new_thread
51
62
  Thread.new do
52
- self.fiber = Fiber.new do |args|
63
+ Thread.current.report_on_exception = false
64
+ self.fiber = Fiber.new do |args|
53
65
  blk.call(*args)
54
66
  end
55
67
 
@@ -102,12 +114,24 @@ module Rbgo
102
114
  include Singleton
103
115
  attr_accessor :num_thread, :check_interval, :io_machine
104
116
 
117
+ def io_machine
118
+ io_machine_init_once.do do
119
+ @io_machine = IOMachine.new
120
+ end
121
+ @io_machine
122
+ end
123
+
124
+ def io_machine=(machine)
125
+ @io_machine = machine
126
+ end
127
+
105
128
  private
106
129
 
107
130
  attr_accessor :thread_pool
108
131
  attr_accessor :task_queue
109
132
  attr_accessor :msg_queue
110
133
  attr_accessor :supervisor_thread
134
+ attr_accessor :io_machine_init_once
111
135
 
112
136
  def initialize
113
137
  self.num_thread = System::CPU.count rescue 8
@@ -118,7 +142,7 @@ module Rbgo
118
142
 
119
143
  self.check_interval = 0.1
120
144
 
121
- self.io_machine = IOMachine.new
145
+ self.io_machine_init_once = Once.new
122
146
 
123
147
  msg_queue << :init
124
148
  create_supervisor_thread
@@ -288,9 +312,14 @@ module Rbgo
288
312
  CoRun.read_from(self, length: len)
289
313
  end
290
314
 
315
+ def yield_read_line(sep = $/, limit = nil)
316
+ CoRun.read_line_from(self, sep: sep, limit: limit)
317
+ end
318
+
291
319
  def yield_write(str)
292
320
  CoRun.write_to(self, str: str)
293
321
  end
322
+
294
323
  end
295
324
  end
296
325
  end
@@ -52,6 +52,14 @@ module Rbgo
52
52
  receipt
53
53
  end
54
54
 
55
+ def do_read_line(io, sep: $/, limit: nil)
56
+ op = [:register_read_line, io, sep, limit]
57
+ receipt = IOReceipt.new(op)
58
+ actor.send_msg(receipt)
59
+ receipt
60
+ end
61
+
62
+
55
63
  def close
56
64
  actor.close
57
65
  selector.close
@@ -78,12 +86,12 @@ module Rbgo
78
86
  receipt = msg
79
87
  op = receipt.registered_op
80
88
 
81
- case
82
- when param_pattern_match([:register_read, IO, Integer], op)
83
- handle_read_msg(receipt, actor)
84
- when param_pattern_match([:register_read, IO, nil], op)
89
+ case op[0]
90
+ when :register_read
85
91
  handle_read_msg(receipt, actor)
86
- when param_pattern_match([:register_write, IO, String], op)
92
+ when :register_read_line
93
+ handle_read_line_msg(receipt, actor)
94
+ when :register_write
87
95
  handle_write_msg(receipt, actor)
88
96
  end
89
97
  end #end of actor
@@ -111,35 +119,34 @@ module Rbgo
111
119
  end
112
120
 
113
121
 
114
- def handle_read_msg(receipt, actor)
115
- op = receipt.registered_op
116
- io = op[1]
117
- len = op[2]
118
- res = StringIO.new
119
- buf_size = 1024 * 512
120
- registered_monitor = monitors[io]
121
- if registered_monitor && (registered_monitor.interests == :r || registered_monitor.interests == :rw)
122
- actor.send_msg receipt
123
- return
124
- end
122
+ def handle_read_line_msg(receipt, actor)
123
+ op = receipt.registered_op
124
+ io = op[1]
125
+ sep = op[2]
126
+ limit = op[3]
127
+ buf_size = 512 * 1024
128
+ res = ""
125
129
 
126
- if registered_monitor
127
- registered_monitor.add_interest(:r)
128
- monitor = registered_monitor
129
- else
130
- monitor = selector.register(io, :r)
131
- monitors[io] = monitor
132
- end
130
+ monitor = register(receipt, interest: :r)
131
+ return if monitor.nil?
133
132
 
134
133
  monitor.value ||= []
135
134
  monitor.value[0] = proc do
136
- if len.nil?
137
- notify_blk = proc do
138
- monitors.delete(monitor.io)
139
- monitor.close
140
- receipt.res = res.string
141
- receipt.notify
135
+ notify_blk = proc do
136
+ monitors.delete(monitor.io)
137
+ monitor.close
138
+ if limit && limit > 0 && res.length == 0
139
+ receipt.res = nil
140
+ else
141
+ receipt.res = res
142
142
  end
143
+ receipt.notify
144
+ end
145
+
146
+ sep = "\n\n" if (sep && sep.length == 0)
147
+
148
+ if limit.nil?
149
+ buf_size = 1 unless sep.nil?
143
150
  loop do
144
151
  begin
145
152
  buf = io.read_nonblock(buf_size, exception: false)
@@ -155,25 +162,98 @@ module Rbgo
155
162
  break
156
163
  end
157
164
  res << buf
165
+ unless sep.nil?
166
+ if res.end_with?(sep)
167
+ notify_blk.call
168
+ break
169
+ end
170
+ end
158
171
  end
159
- elsif len == 0
160
- monitors.delete(monitor.io)
161
- monitor.close
162
- receipt.res = ""
163
- receipt.notify
164
- break
165
- else
166
- notify_blk = proc do
167
- monitors.delete(monitor.io)
168
- monitor.close
169
- if res.string.length == 0
170
- receipt.res = nil
172
+ elsif limit > 0
173
+ bytes_read_n = 0
174
+ loop do
175
+ need_read_bytes_n = limit - bytes_read_n
176
+ if need_read_bytes_n <= 0
177
+ notify_blk.call
178
+ break
179
+ end
180
+ if sep.nil?
181
+ buf_size = need_read_bytes_n
171
182
  else
172
- receipt.res = res.string
183
+ buf_size = 1
184
+ end
185
+ begin
186
+ buf = io.read_nonblock(buf_size, exception: false)
187
+ rescue Exception => ex
188
+ notify_blk.call
189
+ STDERR.puts ex
190
+ break
191
+ end
192
+ if buf == :wait_readable
193
+ break
194
+ elsif buf.nil?
195
+ notify_blk.call
196
+ break
197
+ end
198
+ res << buf
199
+ bytes_read_n += buf.bytesize
200
+ unless sep.nil?
201
+ if res.end_with?(sep)
202
+ notify_blk.call
203
+ break
204
+ end
173
205
  end
174
- receipt.notify
175
206
  end
207
+ else
208
+ notify_blk.call
209
+ end
210
+ end
211
+ actor.send_msg :do_select
212
+ end
213
+
176
214
 
215
+ def handle_read_msg(receipt, actor)
216
+ op = receipt.registered_op
217
+ io = op[1]
218
+ len = op[2]
219
+ res = ""
220
+ buf_size = 1024 * 512
221
+
222
+ monitor = register(receipt, interest: :r)
223
+ return if monitor.nil?
224
+ notify_blk = proc do
225
+ monitors.delete(monitor.io)
226
+ monitor.close
227
+ if len && len > 0 && res.length == 0
228
+ receipt.res = nil
229
+ else
230
+ receipt.res = res
231
+ end
232
+ receipt.notify
233
+ end
234
+ monitor.value ||= []
235
+ monitor.value[0] = proc do
236
+ if len.nil?
237
+ loop do
238
+ begin
239
+ buf = io.read_nonblock(buf_size, exception: false)
240
+ rescue Exception => ex
241
+ notify_blk.call
242
+ STDERR.puts ex
243
+ break
244
+ end
245
+ if buf == :wait_readable
246
+ break
247
+ elsif buf.nil?
248
+ notify_blk.call
249
+ break
250
+ end
251
+ res << buf
252
+ end
253
+ elsif len == 0
254
+ notify_blk.call
255
+ break
256
+ else
177
257
  bytes_read_n = 0
178
258
  loop do
179
259
  need_read_bytes_n = len - bytes_read_n
@@ -208,19 +288,8 @@ module Rbgo
208
288
  io = op[1]
209
289
  str = op[2].to_s
210
290
 
211
- registered_monitor = monitors[io]
212
- if registered_monitor && (registered_monitor.interests == :w || registered_monitor.interests == :rw)
213
- actor.send_msg receipt
214
- return
215
- end
216
-
217
- if registered_monitor
218
- registered_monitor.add_interest(:w)
219
- monitor = registered_monitor
220
- else
221
- monitor = selector.register(io, :w)
222
- monitors[io] = monitor
223
- end
291
+ monitor = register(receipt, interest: :w)
292
+ return if monitor.nil?
224
293
 
225
294
  buf = NIO::ByteBuffer.new(str.bytesize)
226
295
  buf << str
@@ -250,17 +319,23 @@ module Rbgo
250
319
  end
251
320
 
252
321
 
253
- def param_pattern_match(pattern, params)
254
- return false unless pattern.is_a?(Array) && params.is_a?(Array)
255
- return false if pattern.size != params.size
256
- match = true
257
- pattern.zip(params) do |type, param|
258
- unless type === param
259
- match = false
260
- break
261
- end
322
+ def register(receipt, interest:)
323
+ io = receipt.registered_op[1]
324
+ registered_monitor = monitors[io]
325
+ if registered_monitor && (registered_monitor.interests == interest || registered_monitor.interests == :rw)
326
+ actor.send_msg receipt
327
+ return nil
262
328
  end
263
- match
329
+
330
+ if registered_monitor
331
+ registered_monitor.add_interest(interest)
332
+ monitor = registered_monitor
333
+ else
334
+ monitor = selector.register(io, interest)
335
+ monitors[io] = monitor
336
+ end
337
+ monitor
264
338
  end
339
+
265
340
  end
266
341
  end
data/lib/rbgo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rbgo
2
- VERSION = "0.2.6"
2
+ VERSION = "0.2.7"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbgo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wang Yin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-09 00:00:00.000000000 Z
11
+ date: 2019-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: system