plux 0.1.3 → 0.1.4

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