plux 0.1.3 → 0.1.4

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: 472f8a38bccdb6c63b10b4291c4cd109598e8819222c4061dd673f3491d58344
4
- data.tar.gz: 489ce27db397a3df71058642b8f3dab80ac255cf1ace82f66c12d80980de4efc
3
+ metadata.gz: 06c8e6b4eae44651cb3ba6e01503710c25b1746e11ae2c339bbe37225200e5bc
4
+ data.tar.gz: 92c320fe5e1c92078bd87d09c78bb0e76224a5ed9e1fc18604056d8ccdb23eea
5
5
  SHA512:
6
- metadata.gz: 565721905d9e193557d56c78a323f35bd41e1650bb7592607534a6da3cf9f961d66801b2a169477f9b3b2019f06d45e1e08bcda6b146d855d5018b11ba5a6231
7
- data.tar.gz: 32d1c59b0a5b169e9ed33302d576dc3d87e42ba376d9f927f61a34d1f5b8bcdf44582fe11a547de0d62c1827158248dfb6293df8fd06cdaa5716f23bcb313741
6
+ metadata.gz: 8957056c62d9cc90a236e0bf2eb06d8d38cfd3cb8b1054d812c08741b672c0ebc2e3b545111ea5bf4825b3955e21cb748b1c6df727f2fc8748eb8eaa17c169d9
7
+ data.tar.gz: b7aed8c1662ab951728321576bd611bb5d402557e2d01d2b5943b644fec92b9eb0d312612bcdf725162f0647da4a54f7cc01ff3e3dc8e5a9b34c54fb6b1a66b5
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- plux (0.1.3)
4
+ plux (0.1.4)
5
+ nio4r (~> 2.0)
5
6
 
6
7
  GEM
7
8
  remote: https://rubygems.org/
@@ -9,6 +10,7 @@ GEM
9
10
  coderay (1.1.2)
10
11
  method_source (0.9.2)
11
12
  minitest (5.14.1)
13
+ nio4r (2.5.3)
12
14
  pry (0.12.2)
13
15
  coderay (~> 1.1.0)
14
16
  method_source (~> 0.9.0)
data/README.md CHANGED
@@ -21,9 +21,9 @@ Or install it yourself as:
21
21
  ## Usage
22
22
 
23
23
  ```ruby
24
- # start one and only process named 'abc',
24
+ # start one and only process named 'abc', with 2 threads in it (1 thread if not specified),
25
25
  # no matter the code below is called how many times in whatever processes/threads
26
- server = Plux.worker(:abc) do
26
+ server = Plux.worker(:abc, thread: 2) do
27
27
 
28
28
  # prepare resources like mq/db, to handle requests
29
29
  def initialize
@@ -36,8 +36,7 @@ server = Plux.worker(:abc) do
36
36
  end
37
37
  end
38
38
 
39
- # five threads will be started to handle these clients,
40
- # and finished once their counterparts call close
39
+ # the 2 threads will handle these 5 clients
41
40
  5.times do |n|
42
41
  Thread.new do
43
42
  client = server.connect
@@ -32,8 +32,8 @@ module Plux
32
32
  File.join(dir, "#{server_name}.so")
33
33
  end
34
34
 
35
- def worker(name, &block)
36
- Server.new(name).boot(block)
35
+ def worker(name, thread: 1, &block)
36
+ Server.new(name, thread: thread).boot(block)
37
37
  end
38
38
  end
39
39
 
@@ -0,0 +1,91 @@
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
@@ -1,3 +1,6 @@
1
+ require "nio"
2
+ require "plux/reactors"
3
+
1
4
  module Plux
2
5
 
3
6
  class Server
@@ -6,8 +9,9 @@ module Plux
6
9
  Active = {}
7
10
  at_exit{ Active.values.each(&:close) }
8
11
 
9
- def initialize(name)
12
+ def initialize(name, thread: )
10
13
  @name = name
14
+ @thread = thread
11
15
  end
12
16
 
13
17
  def boot(block)
@@ -40,10 +44,8 @@ module Plux
40
44
  UNIXServer.open(Plux.server_file(name)) do |serv|
41
45
  parent.close
42
46
  worker = Class.new(&block).new
43
- loop do
44
- socket = serv.accept
45
- Worker.new(socket, worker)
46
- end
47
+ reactors = Reactors.new(@thread, worker)
48
+ loop{ reactors.register(serv.accept) }
47
49
  end
48
50
  end
49
51
 
@@ -62,31 +64,6 @@ module Plux
62
64
  File.delete(Plux.send(file, name))
63
65
  end
64
66
  end
65
-
66
- class Worker
67
- def initialize(socket, worker)
68
- par = Parser.new
69
- t = Thread.new do
70
- loop do
71
- begin
72
- stream = socket.read_nonblock(Parser::STREAM_MAX_LEN)
73
- rescue IO::WaitReadable
74
- IO.select([socket])
75
- retry
76
- end
77
-
78
- msgs = par.decode(stream)
79
- last_msg = msgs.pop
80
-
81
- msgs.each{ |msg| worker.work(msg) }
82
- break if last_msg == Parser::LAST_MSG
83
- worker.work(last_msg)
84
- end
85
- socket.close
86
- end
87
- end
88
- end
89
-
90
67
  end
91
68
 
92
69
  end
@@ -1,3 +1,3 @@
1
1
  module Plux
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
@@ -23,4 +23,6 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "rake", "~> 10.0"
24
24
  spec.add_development_dependency "minitest", "~> 5.0"
25
25
  spec.add_development_dependency "pry"
26
+
27
+ spec.add_dependency "nio4r", "~> 2.0"
26
28
  end
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.3
4
+ version: 0.1.4
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-13 00:00:00.000000000 Z
11
+ date: 2020-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: nio4r
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.0'
69
83
  description:
70
84
  email:
71
85
  - block24block@gmail.com
@@ -86,6 +100,7 @@ files:
86
100
  - lib/plux.rb
87
101
  - lib/plux/client.rb
88
102
  - lib/plux/parser.rb
103
+ - lib/plux/reactors.rb
89
104
  - lib/plux/server.rb
90
105
  - lib/plux/version.rb
91
106
  - plux.gemspec