rbgo 0.2.6 → 0.2.7

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: 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