plux 0.1.4 → 0.1.5
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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +4 -3
- data/lib/plux/reactor.rb +76 -0
- data/lib/plux/server.rb +3 -3
- data/lib/plux/version.rb +1 -1
- metadata +3 -3
- data/lib/plux/reactors.rb +0 -91
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56011d823e56b1bd06759d5546edc8519338a99392ce980ebc6033b7f458cd0f
|
4
|
+
data.tar.gz: 7b3353cbbb07daa6394aceb3fefa830c438c797a455352d6283c6a71942cdb59
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2c201408eb9e5d0d2b19d1eabf0908324645ef2b95b922bda8e1ec3f2b39d988b58ebfb50c1fc17ec2e0522900122956b65fd2bdda4285785e42f4b28ff0838
|
7
|
+
data.tar.gz: 4ac2ab94501c97a09d3416d3dcf0837a04ecafc12050b0f8346f30a541e088059761ede6b7c674c9c1e720380a95b7bf1adc46d9c0df52c2dfa70a53132bcfb0
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -25,7 +25,7 @@ Or install it yourself as:
|
|
25
25
|
# no matter the code below is called how many times in whatever processes/threads
|
26
26
|
server = Plux.worker(:abc, thread: 2) do
|
27
27
|
|
28
|
-
# prepare resources like mq/db, to handle requests
|
28
|
+
# prepare thread-safe resources like mq/db, to handle requests
|
29
29
|
def initialize
|
30
30
|
# @db = ...
|
31
31
|
end
|
@@ -36,11 +36,12 @@ server = Plux.worker(:abc, thread: 2) do
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
#
|
39
|
+
# clients connect, send msg, and close concurrently
|
40
40
|
5.times do |n|
|
41
41
|
Thread.new do
|
42
42
|
client = server.connect
|
43
|
-
client.puts "hello
|
43
|
+
client.puts "hello"
|
44
|
+
client.puts "my name is #{n}"
|
44
45
|
client.close
|
45
46
|
end
|
46
47
|
end
|
data/lib/plux/reactor.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
module Plux
|
2
|
+
class Reactor
|
3
|
+
def initialize(count, worker)
|
4
|
+
@worker = worker
|
5
|
+
@msg_q = Queue.new
|
6
|
+
@count = count
|
7
|
+
|
8
|
+
@nio = NIO::Selector.new
|
9
|
+
@newly_accepted = Queue.new
|
10
|
+
@closed = []
|
11
|
+
|
12
|
+
receive
|
13
|
+
process
|
14
|
+
end
|
15
|
+
|
16
|
+
def register(socket)
|
17
|
+
@newly_accepted << socket
|
18
|
+
@nio.wakeup
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def receive
|
24
|
+
Thread.new do
|
25
|
+
loop do
|
26
|
+
@closed.size.times{ @nio.deregister(@closed.pop) }
|
27
|
+
|
28
|
+
@newly_accepted.size.times do
|
29
|
+
socket = @newly_accepted.pop
|
30
|
+
mon = @nio.register(socket, :r)
|
31
|
+
mon.value = Worker.new(socket, @msg_q)
|
32
|
+
end
|
33
|
+
|
34
|
+
@nio.select do |m|
|
35
|
+
next if m.value.process
|
36
|
+
@closed << m.io
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def process
|
43
|
+
@count.times.each do
|
44
|
+
Thread.new do
|
45
|
+
loop{ @worker.work(@msg_q.deq) }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Worker
|
51
|
+
def initialize(socket, q)
|
52
|
+
@parser = Parser.new
|
53
|
+
@socket = socket
|
54
|
+
@q = q
|
55
|
+
end
|
56
|
+
|
57
|
+
def process
|
58
|
+
stream = @socket.read_nonblock(Parser::STREAM_MAX_LEN, exception: false)
|
59
|
+
return true if stream == :wait_readable
|
60
|
+
|
61
|
+
msgs = @parser.decode(stream)
|
62
|
+
last_msg = msgs.pop
|
63
|
+
|
64
|
+
msgs.each{ |msg| @q << msg }
|
65
|
+
if last_msg == Parser::LAST_MSG
|
66
|
+
@socket.close
|
67
|
+
return false
|
68
|
+
end
|
69
|
+
@q << last_msg
|
70
|
+
|
71
|
+
true
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
data/lib/plux/server.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require "nio"
|
2
|
-
require "plux/
|
2
|
+
require "plux/reactor"
|
3
3
|
|
4
4
|
module Plux
|
5
5
|
|
@@ -44,8 +44,8 @@ module Plux
|
|
44
44
|
UNIXServer.open(Plux.server_file(name)) do |serv|
|
45
45
|
parent.close
|
46
46
|
worker = Class.new(&block).new
|
47
|
-
|
48
|
-
loop{
|
47
|
+
reactor = Reactor.new(@thread, worker)
|
48
|
+
loop{ reactor.register(serv.accept) }
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
data/lib/plux/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: plux
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ken
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-09-
|
11
|
+
date: 2020-09-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -100,7 +100,7 @@ files:
|
|
100
100
|
- lib/plux.rb
|
101
101
|
- lib/plux/client.rb
|
102
102
|
- lib/plux/parser.rb
|
103
|
-
- lib/plux/
|
103
|
+
- lib/plux/reactor.rb
|
104
104
|
- lib/plux/server.rb
|
105
105
|
- lib/plux/version.rb
|
106
106
|
- plux.gemspec
|
data/lib/plux/reactors.rb
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
module Plux
|
2
|
-
class Reactors
|
3
|
-
def initialize(count, worker)
|
4
|
-
@lock = Mutex.new
|
5
|
-
@reactor_loops = count.times.each_with_object({}) do |r, hash|
|
6
|
-
hash[Reactor.new(worker, self)] = 0
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
def register(socket)
|
11
|
-
@lock.synchronize do
|
12
|
-
reactor = @reactor_loops.sort_by{ |_, v| v }.first.first
|
13
|
-
reactor.register(socket)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def timer(reactor, duration)
|
18
|
-
@lock.synchronize{ @reactor_loops[reactor] += duration }
|
19
|
-
end
|
20
|
-
|
21
|
-
class Reactor
|
22
|
-
def initialize(worker, reactors)
|
23
|
-
@worker = worker
|
24
|
-
@reactors = reactors
|
25
|
-
|
26
|
-
@nio = NIO::Selector.new
|
27
|
-
@newly_accepted = Queue.new
|
28
|
-
@closed = []
|
29
|
-
|
30
|
-
run
|
31
|
-
end
|
32
|
-
|
33
|
-
def register(socket)
|
34
|
-
@newly_accepted << socket
|
35
|
-
@nio.wakeup
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def run
|
41
|
-
Thread.new do
|
42
|
-
loop do
|
43
|
-
@closed.size.times{ @nio.deregister(@closed.pop) }
|
44
|
-
|
45
|
-
@newly_accepted.size.times do
|
46
|
-
socket = @newly_accepted.pop
|
47
|
-
mon = @nio.register(socket, :r)
|
48
|
-
mon.value = Worker.new(socket, @worker)
|
49
|
-
end
|
50
|
-
|
51
|
-
start = Time.now.to_i
|
52
|
-
|
53
|
-
next unless @nio.select do |m|
|
54
|
-
next if m.value.process
|
55
|
-
@closed << m.io
|
56
|
-
end
|
57
|
-
|
58
|
-
@reactors.timer(self, Time.now.to_i - start)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
class Worker
|
65
|
-
def initialize(socket, worker)
|
66
|
-
@parser = Parser.new
|
67
|
-
@socket = socket
|
68
|
-
@worker = worker
|
69
|
-
end
|
70
|
-
|
71
|
-
def process
|
72
|
-
10.times do
|
73
|
-
stream = @socket.read_nonblock(Parser::STREAM_MAX_LEN, exception: false)
|
74
|
-
return true if stream == :wait_readable
|
75
|
-
|
76
|
-
msgs = @parser.decode(stream)
|
77
|
-
last_msg = msgs.pop
|
78
|
-
|
79
|
-
msgs.each{ |msg| @worker.work(msg) }
|
80
|
-
if last_msg == Parser::LAST_MSG
|
81
|
-
@socket.close
|
82
|
-
return false
|
83
|
-
end
|
84
|
-
@worker.work(last_msg)
|
85
|
-
end
|
86
|
-
true
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
end
|
91
|
-
end
|