reifier 0.3.0 → 0.4.0

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: c728b806deb19da5dcfa300f0a686b0981d369d8
4
- data.tar.gz: 8f9b2057ca56169779e32e71037f12df61bacd4c
3
+ metadata.gz: aa60f4a229669e2c71cccd301f93309a67fa48d6
4
+ data.tar.gz: 731f667e0829f067924abbf80ed8d4f5e88f559c
5
5
  SHA512:
6
- metadata.gz: b63257d7a6c23bfaadddfa3e0f11e9905d8ce5c0059ef7444db6259f62591076f8a1f240fe49fa0c326411eb9db99c84f3bc68454c186b0505b798c56e50a231
7
- data.tar.gz: 0717702206a003c2749e7dd018928a3ad68a71635e78e1300ba18396762a38c7f1dc9128c83dd9efe5a036ee0e7aba556e9ef0e99a96277974b5e9f3b73dc321
6
+ metadata.gz: 167c3dff17ad61c8fa5a5be610939603df0516d61eedf96e1d3545ae3bf13701c60ba8a554f4eaf34a9685d37550707e76c649eb859e6d7ec9e6eed4495143d2
7
+ data.tar.gz: b04ce039f7d7a1a86589f3fecc8514d28a09a4ebbab06ddab4a3b3956ea9c292a21bbb17d2e387e29c1bd740e03b57cbdb266ad1927b5db452976980bd55e8c5
data/README.md CHANGED
@@ -6,9 +6,11 @@ reify
6
6
 
7
7
  (transitive) to consider or make (an abstract idea or concept) real or concrete
8
8
 
9
+ Reifier is a threaded and pre forked rack app server written in pure ruby.
10
+
9
11
  ## Is it any good?
10
12
 
11
- [Yes](http://news.ycombinator.com/item?id=3067434), no really just a fun project use it in production when u want :P
13
+ [Yes](http://news.ycombinator.com/item?id=3067434), no really just a fun project use it in production if you want :P
12
14
 
13
15
  ## Y u no benchmark?!
14
16
 
@@ -39,7 +41,7 @@ Use it through rackup:
39
41
 
40
42
  ## Available Options
41
43
 
42
- You can adapt the ThreadPool sized with following option:
44
+ You can adapt the ThreadPool size with following option:
43
45
 
44
46
  $ rackup -s reifier -O Threads=8
45
47
 
@@ -47,6 +49,16 @@ Also the amount of workers is adaptable:
47
49
 
48
50
  $ rackup -s reifier -O Workers=5
49
51
 
52
+ ## Config File
53
+
54
+ You can also use a config file for these and more settings.
55
+
56
+ When you are using `rails s` reifier tries to load the file from `Rails.root/config/reifier.rb`
57
+
58
+ When you are using any other rack app it tries to load the file from `Dir.pwd/config/reifier.rb`
59
+
60
+ See the [example config](examples/reifier.rb)
61
+
50
62
  ## Development
51
63
 
52
64
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -0,0 +1,2 @@
1
+ threads 8 # Using a thread pool size of 8
2
+ workers 9 # Using 9 worker processes
@@ -5,20 +5,22 @@ module Rack
5
5
  module Handler
6
6
  module Reifier
7
7
  DEFAULT_OPTIONS = {
8
- Workers: 3,
8
+ Workers: 1,
9
9
  Threads: 16
10
10
  }.freeze
11
11
 
12
12
  def self.run(app, options = {})
13
13
  options = DEFAULT_OPTIONS.merge(options)
14
- puts "Reifier #{::Reifier::VERSION} starting.."
14
+ puts "======= Reifier #{::Reifier::VERSION} starting ======="
15
15
  server = ::Reifier::Server.new(app, options)
16
+ server.load_configuration
16
17
  server.start
17
18
  end
18
19
 
19
20
  def self.valid_options
20
21
  {
21
- 'Threads=THREADS' => 'Number of threads (default: 5)'
22
+ 'Threads=THREADS' => 'Number of threads (default: 16)',
23
+ 'Workers=WORKERS' => 'Number of workers (default: 1)'
22
24
  }
23
25
  end
24
26
  end
@@ -2,16 +2,17 @@ module Reifier
2
2
  class Request
3
3
  attr_reader :request_method, :request_path, :protocol, :request_uri
4
4
 
5
- def initialize(options)
5
+ def initialize(socket, options)
6
+ @socket = socket
6
7
  @body = StringIO.new('')
7
8
  @options = options
8
9
  end
9
10
 
10
- def handle(socket)
11
- handle_request_line(socket)
12
- handle_headers(socket)
11
+ def handle
12
+ handle_request_line
13
+ handle_headers
13
14
 
14
- handle_body(socket) if request_with_body?
15
+ handle_body if request_with_body?
15
16
  end
16
17
 
17
18
  def rack_env
@@ -34,7 +35,9 @@ module Reifier
34
35
  'SERVER_PROTOCOL' => @protocol,
35
36
  'SERVER_SOFTWARE' => "Reifier #{Reifier::VERSION}",
36
37
  'SERVER_NAME' => @options[:Host],
37
- 'SERVER_PORT' => @options[:Port].to_s
38
+ 'SERVER_PORT' => @options[:Port].to_s,
39
+ 'HTTP_VERSION' => @protocol,
40
+ 'REMOTE_ADDR' => @socket.addr.last
38
41
  }
39
42
 
40
43
  @headers.each do |k, v|
@@ -52,12 +55,12 @@ module Reifier
52
55
 
53
56
  private
54
57
 
55
- def handle_request_line(socket)
58
+ def handle_request_line
56
59
  # It is possible that gets returns nil
57
60
  # "Returns nil if called at end of file" see http://ruby-doc.org/core-2.3.0/IO.html#method-i-gets
58
- request_line = socket.gets
61
+ request_line = @socket.gets
59
62
  raise EOFError unless request_line
60
- raise HTTPParseError unless request_line.include?('HTTP')
63
+ raise HTTPParseError, "Received #{request_line.inspect}" unless request_line.include?('HTTP')
61
64
 
62
65
  request_line_array = request_line.split
63
66
 
@@ -69,10 +72,10 @@ module Reifier
69
72
  @request_uri = request_line_array[1]
70
73
  end
71
74
 
72
- def handle_headers(socket)
75
+ def handle_headers
73
76
  @headers = {}
74
77
 
75
- while (line = socket.gets)
78
+ while (line = @socket.gets)
76
79
  break if line == CRLF
77
80
  if line.include?('Host')
78
81
  @headers['HOST'] = line.gsub('Host: ', '').strip.chomp
@@ -84,8 +87,8 @@ module Reifier
84
87
  end
85
88
  end
86
89
 
87
- def handle_body(socket)
88
- @body = StringIO.new(socket.readpartial(@headers['CONTENT_LENGTH'].to_i))
90
+ def handle_body
91
+ @body = StringIO.new(@socket.readpartial(@headers['CONTENT_LENGTH'].to_i))
89
92
  end
90
93
 
91
94
  def request_with_body?
@@ -2,17 +2,18 @@ module Reifier
2
2
  class Response
3
3
  attr_accessor :status, :headers, :body, :protocol
4
4
 
5
- def initialize
5
+ def initialize(socket)
6
+ @socket = socket
6
7
  @response = ''
7
8
  end
8
9
 
9
- def handle(socket)
10
+ def handle
10
11
  handle_request_line
11
12
  handle_headers
12
13
  handle_body
13
14
 
14
- socket.write @response
15
- socket.close
15
+ @socket.write @response
16
+ @socket.close
16
17
  end
17
18
 
18
19
  def <<(rack_return)
@@ -14,7 +14,7 @@ module Reifier
14
14
  end
15
15
 
16
16
  Signal.trap 'SIGINT' do
17
- puts "Cleaning up #{child_pids.length} Workers"
17
+ puts "\n======= Cleaning up #{child_pids.length} Workers =======\n"
18
18
  child_pids.each do |cpid|
19
19
  begin
20
20
  Process.kill(:INT, cpid)
@@ -40,12 +40,31 @@ module Reifier
40
40
  end
41
41
  end
42
42
 
43
+ def load_configuration
44
+ if defined?(Rails)
45
+ path = Rails.root.join('config/reifier.rb')
46
+ else
47
+ path = Dir.pwd + '/reifier.rb'
48
+ end
49
+
50
+ return unless File.exist?(path)
51
+
52
+ lines = File.read(path).split("\n")
53
+
54
+ lines.each do |line|
55
+ option = line.split.first.capitalize
56
+ value = line.split.last
57
+
58
+ @options[option.to_sym] = value
59
+ end
60
+
61
+ puts "======= Loaded settings from #{path} =======\n"
62
+ end
63
+
43
64
  private
44
65
 
45
66
  def spawn_worker(server)
46
67
  fork do
47
- Thread.abort_on_exception = true
48
-
49
68
  pool = Concurrent::FixedThreadPool.new(@options[:Threads])
50
69
 
51
70
  loop do
@@ -54,36 +73,26 @@ module Reifier
54
73
 
55
74
  pool.post do
56
75
  begin
57
- request = Request.new(@options)
58
- response = Response.new
76
+ request = Request.new(socket, @options)
77
+ response = Response.new(socket)
59
78
 
60
- request.handle(socket)
79
+ request.handle
61
80
 
62
81
  response.protocol = request.protocol
63
82
  response << @app.call(request.rack_env)
64
83
 
65
- response.handle(socket)
66
-
67
- log_request request, response if development?
84
+ response.handle
68
85
  rescue Exception => e
69
- log "\nError: #{e.class}\nMessage: #{e.message}\n\nBacktrace:\n\t#{e.backtrace.join("\n\t")}" if development?
70
86
  socket.close
87
+
88
+ STDERR.puts ERROR_HEADER
89
+ STDERR.puts "#{e.class}: #{e}"
90
+ STDERR.puts e.backtrace
91
+ STDERR.puts ERROR_FOOTER
71
92
  end
72
93
  end
73
94
  end
74
95
  end
75
96
  end
76
-
77
- def development?
78
- @options[:environment] == 'development'
79
- end
80
-
81
- def log(message)
82
- puts "[#{Time.now}] #{message}"
83
- end
84
-
85
- def log_request(request, response)
86
- puts "[#{Time.now}] \"#{request.request_method} #{request.request_path} #{request.protocol}\" #{response.status}"
87
- end
88
97
  end
89
98
  end
@@ -1,3 +1,3 @@
1
1
  module Reifier
2
- VERSION = "0.3.0".freeze
2
+ VERSION = "0.4.0".freeze
3
3
  end
data/lib/reifier.rb CHANGED
@@ -80,4 +80,6 @@ module Reifier
80
80
  PUT = 'PUT'.freeze
81
81
 
82
82
  HTTPParseError = Class.new(StandardError)
83
+ ERROR_HEADER = '=============================== FATAL SERVER ERROR =============================='.freeze
84
+ ERROR_FOOTER = "=================================================================================\n\n\n".freeze
83
85
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benny Klotz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-02-16 00:00:00.000000000 Z
11
+ date: 2016-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -137,6 +137,7 @@ files:
137
137
  - Rakefile
138
138
  - bin/console
139
139
  - bin/setup
140
+ - examples/reifier.rb
140
141
  - lib/rack/handler/reifier.rb
141
142
  - lib/reifier.rb
142
143
  - lib/reifier/request.rb