crap_server 0.0.4.0 → 0.0.4.1

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
  SHA1:
3
- metadata.gz: 09f1212512d245febe72024ad1751b4720dbba32
4
- data.tar.gz: 689ad5316946fbc2a52c48e7fe3b186458d9be27
3
+ metadata.gz: 153311cb4783062e2a2ff30c82bde05b90eabd31
4
+ data.tar.gz: c1b552c709961e5673f398f285e89d27e3767a4d
5
5
  SHA512:
6
- metadata.gz: e7888fd1485a6b2c06ade746640b6a94860a25ca099c1cebf0ffb4ea1e48d03dfab1ab2e2ab8b078100e240bc982dac7f37c4c9f79275b853acb0d1d526eff42
7
- data.tar.gz: e88ea89e7fd1c7b6185f695d61736af723a2707abef6e638d34377acb242e00f93dc5827095e8239522854762105aebcead9785b4d167ae3786a4a86ee8044f4
6
+ metadata.gz: 88a68cec8ed174dd4dcbffd60e84ab78d24cd1d34d6f5c4e54d62ff60ae4b3e046b84edd311fac55326a792c49a35c089ceae253de68695c9ce3c2faae754a99
7
+ data.tar.gz: 047d1427c76f4e6d5a82deaea1f0471231eefb2ebf315d83d59333b2339e7a6a1fdb815d7e44a218231d51b6d2523e6951dd838da51c02d9c831dc27a4c084b0
@@ -25,6 +25,7 @@ module CrapServer
25
25
  # Main method. This setup all the connections and make the logic of the app
26
26
  def run!(&block)
27
27
  begin
28
+ logger.info 'Initializing Crap Server'
28
29
  # Bup the maximum opened file to the maximum allowed by the system
29
30
  Process.setrlimit(:NOFILE, Process.getrlimit(:NOFILE)[1])
30
31
 
@@ -33,10 +34,11 @@ module CrapServer
33
34
 
34
35
 
35
36
  # Some log info to the user :)
36
- logger.info 'Initializing Crap Server'
37
37
  logger.info "Listening 0.0.0.0:#{config.port}"
38
38
  logger.debug "Maximum allowed waiting connections: #{Socket::SOMAXCONN}"
39
39
  logger.debug "Maximum number of allowed connections: #{Process.getrlimit(:NOFILE)[1]}" # Same as maximum of opened files
40
+ logger.debug "Number of threads per core: #{config.pool_size}"
41
+ logger.info 'Everything is ready. Have fun!'
40
42
  logger.info ''
41
43
 
42
44
  # Prefork and handle the connections in each process.
@@ -44,19 +46,18 @@ module CrapServer
44
46
  # Run loop. (basically, waiting until Ctrl+C)
45
47
  forker.run &block
46
48
 
47
- # NOTE: I think this line never will be executed
48
- close_connections
49
-
50
49
  # If any kind of error happens, we MUST close the sockets
51
50
  rescue => e
52
51
  logger.error "Error: #{e.message}"
53
52
  e.backtrace.each do |line|
54
53
  logger.error line
55
54
  end
56
- close_connections
55
+ # We don't need to close the socket, because are closed automatically by ruby
57
56
 
58
57
  rescue Interrupt
59
- close_connections
58
+ # We don't need to close the socket, because are closed automatically by ruby
59
+ # Leaved in black only to prevent error backtrace.
60
+ # The process are killed by CrapServer::Forker
60
61
  end
61
62
  end
62
63
 
@@ -68,25 +69,6 @@ module CrapServer
68
69
  start_ipv6_socket
69
70
  end
70
71
 
71
- # Close all the sockets.
72
- def close_connections
73
- logger.debug 'Closing all connections.'
74
- logger.debug 'Bye!'
75
- # If any kind of error happens, we MUST close the sockets
76
- if socket_ipv4
77
- # Shuts down communication on all copies of the connection.
78
- # socket_ipv4.shutdown
79
- # socket_ipv4.close
80
- end
81
-
82
- if socket_ipv6
83
- # Shuts down communication on all copies of the connection.
84
- # socket_ipv6.shutdown
85
- # socket_ipv6.close
86
- end
87
- # TODO: Close all opened sockets connections from other threads and processes
88
- end
89
-
90
72
  def start_ipv6_socket
91
73
  # :INET6 is to open an IPv6 connection
92
74
  # :STREAM is to open a TCP socket
@@ -147,11 +129,6 @@ module CrapServer
147
129
  @socket4 = value
148
130
  end
149
131
 
150
- # TCP Socket reader
151
- def reader(socket)
152
-
153
- end
154
-
155
132
  # Main configuration.
156
133
  # See Crap::Configure
157
134
  def config
@@ -10,24 +10,20 @@ module CrapServer
10
10
  def run(&block)
11
11
  begin
12
12
  @block_proc = block
13
- child_pids = []
13
+ @child_pids = []
14
14
  processor_count.times do
15
- child_pids << spawn_child
15
+ @child_pids << spawn_child
16
16
  end
17
17
 
18
- # We take care of our children. If someone kill one, me made another one.
19
- # PS: Is a hard work :P
20
- loop do
21
- pid = Process.wait
22
- child_pids.delete(pid)
23
- child_pids << spawn_child
24
- end
18
+ check_children
25
19
  # If someone kill us, we kill our children. Yes, is sad, but we must do it :'(
26
- rescue Interrupt
27
- child_pids.each do |cpid|
20
+ rescue ::Exception # If any kind of error happens, we must kill our children
21
+ @child_pids.each do |cpid|
28
22
  begin
29
23
  # We send Ctrl+C to the process
30
24
  Process.kill(:INT, cpid)
25
+ # If the process in not running or because any reason we have no privileges to kill him
26
+ # We just only don't care. In any case, we can do nothing
31
27
  rescue Errno::ESRCH
32
28
  end
33
29
  end
@@ -36,12 +32,12 @@ module CrapServer
36
32
  socket.shutdown
37
33
  socket.close
38
34
  end
39
-
40
35
  end
41
36
  end
42
37
 
43
38
  protected
44
39
 
40
+ # Spawn a new Thread Pool in each process
45
41
  def spawn_child
46
42
  fork do
47
43
  begin
@@ -52,6 +48,17 @@ module CrapServer
52
48
  end
53
49
  end
54
50
 
51
+ # The main loop that check if any process is killed. If one of them get killed, we spawn another one.
52
+ def check_children
53
+ # We take care of our children. If someone kill one, me made another one.
54
+ # PS: Is a hard work :P
55
+ loop do
56
+ pid = Process.wait
57
+ @child_pids.delete(pid)
58
+ @child_pids << spawn_child
59
+ end
60
+ end
61
+
55
62
  # Extracted from https://github.com/grosser/parallel/blob/master/lib/parallel.rb
56
63
  # Number of processors seen by the OS and used for process scheduling.
57
64
  #
@@ -1,3 +1,3 @@
1
1
  module CrapServer
2
- VERSION = '0.0.4.0'
2
+ VERSION = '0.0.4.1'
3
3
  end
@@ -9,6 +9,7 @@ describe CrapServer::Application do
9
9
  CrapServer::Application.class_eval do
10
10
  @logger = Dummy
11
11
  end
12
+ allow(CrapServer::Forker).to receive(:run).and_return(true)
12
13
  end
13
14
  context 'run!' do
14
15
 
@@ -23,6 +24,7 @@ describe CrapServer::Application do
23
24
  allow(Socket).to receive(:new) do |*args|
24
25
  Dummy
25
26
  end
27
+ allow_any_instance_of(CrapServer::Forker).to receive(:run).and_return(true)
26
28
  end
27
29
 
28
30
  it 'should bind IPv4 and IPv6' do
@@ -52,7 +54,13 @@ describe CrapServer::Application do
52
54
  CrapServer::Application.run! do
53
55
  end
54
56
  end
55
- end
56
57
 
58
+ it 'should execute the forker' do
59
+ expect_any_instance_of(CrapServer::Forker).to receive(:run).and_return(true)
60
+ CrapServer::Application.run! do
61
+ end
62
+ end
63
+ end
57
64
  end
65
+
58
66
  end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe CrapServer::Forker do
4
+ context 'run' do
5
+ before do
6
+ allow(Process).to receive(:wait).and_return(Dummy)
7
+ allow(Process).to receive(:kill).and_return(Dummy)
8
+ end
9
+
10
+ it 'should accept a block' do
11
+ expect(CrapServer::Forker.new(Dummy).method(:run).parameters[-1][1]).to eq(:block)
12
+ end
13
+
14
+ it 'should spawn one process per core' do
15
+ forker = CrapServer::Forker.new(Dummy)
16
+ cores = forker.send(:processor_count)
17
+ expect(forker).to receive(:spawn_child).exactly(cores).times().and_return(Dummy)
18
+ allow_any_instance_of(CrapServer::Forker).to receive(:check_children).and_return true
19
+ forker.run do
20
+ end
21
+ end
22
+
23
+ it 'if someone interrupt the application, we must kill our children' do
24
+ forker = CrapServer::Forker.new([Dummy, Dummy])
25
+ cores = forker.send(:processor_count)
26
+ allow(forker).to receive(:spawn_child).and_return(true)
27
+ allow_any_instance_of(CrapServer::Forker).to receive(:check_children).and_raise(Interrupt)
28
+ expect(Process).to receive(:kill).exactly(cores).times().and_return(true)
29
+ forker.run do
30
+ end
31
+ end
32
+ end
33
+
34
+ context 'spawn_child' do
35
+ pending 'check how to '
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ describe CrapServer::ThreadPool do
2
+
3
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crap_server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4.0
4
+ version: 0.0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andres Jose Borek
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-06 00:00:00.000000000 Z
11
+ date: 2014-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -61,7 +61,9 @@ files:
61
61
  - lib/crap_server/thread_pool.rb
62
62
  - lib/crap_server/version.rb
63
63
  - spec/application_spec.rb
64
+ - spec/forker_spec.rb
64
65
  - spec/spec_helper.rb
66
+ - spec/thread_pool_spec.rb
65
67
  homepage: https://rubygems.org/gems/crap_server
66
68
  licenses:
67
69
  - MIT
@@ -88,4 +90,6 @@ specification_version: 4
88
90
  summary: Really thin a non intuitive ruby server.
89
91
  test_files:
90
92
  - spec/application_spec.rb
93
+ - spec/forker_spec.rb
91
94
  - spec/spec_helper.rb
95
+ - spec/thread_pool_spec.rb