webrick-high-performance 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright 2005 Eric Hodel, The Robot Co-op. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright
10
+ notice, this list of conditions and the following disclaimer in the
11
+ documentation and/or other materials provided with the distribution.
12
+ 3. Neither the names of the authors nor the names of their contributors
13
+ may be used to endorse or promote products derived from this software
14
+ without specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
17
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
20
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
22
+ OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+
@@ -0,0 +1,5 @@
1
+ LICENSE
2
+ Manifest.txt
3
+ README
4
+ Rakefile
5
+ lib/webrick/highperformanceserver.rb
data/README ADDED
@@ -0,0 +1,54 @@
1
+ = WEBrick High Performance
2
+
3
+ Rubyforge Project:
4
+
5
+ http://rubyforge.org/projects/rctools/
6
+
7
+ Documentation:
8
+
9
+ http://dev.robotcoop.com/Libraries/webrick-high-performance/
10
+
11
+ == About
12
+
13
+ WEBrick High Performance adds a new HTTP server class that takes advantage of
14
+ sendfile(2) and fork(2) to drastically improve static file server performance.
15
+
16
+ Since HighPerformanceServer is a forking webserver it may also speed up regular
17
+ WEBrick servlets by spreading load across multiple CPUs.
18
+
19
+ The sendfile(2) system call allows web server writers to offload the job of
20
+ transfering files from the disk to the socket onto the kernel. The work of
21
+ parsing HTTP headers is very easy and very fast and WEBrick is nearly fast
22
+ enough to match Apache.
23
+
24
+ When additional work is needed to look up or validate file access (for example,
25
+ the file is stored in MogileFS) it is more performant to write the code in Ruby
26
+ and use HighPerformanceServer than to write a FastCGI handler and easier than writing an Apache module.
27
+
28
+ == Installing webrick-high-performance
29
+
30
+ webrick-high-performance depends upon socket_sendfile, and as of 1.0.0
31
+ socket_sendfile is only known to work on FreeBSD.
32
+
33
+ So if you've got FreeBSD you only need to install the gem:
34
+
35
+ $ sudo gem install webrick-high-performance
36
+
37
+ == Using webrick-high-performance
38
+
39
+ #!/usr/local/bin/ruby -w
40
+
41
+ require 'rubygems'
42
+ require 'webrick'
43
+ require 'webrick/highperformanceserver'
44
+
45
+ config = {}
46
+ config[:Port] = 8000
47
+ config[:Root] = File.expand_path '~/public_html'
48
+
49
+ WEBrick::HighPerformanceServer.create config do |server|
50
+ trap 'INT' do server.shutdown end
51
+ trap 'TERM' do server.shutdown end
52
+ server.start
53
+ end
54
+
@@ -0,0 +1,69 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/gempackagetask'
6
+
7
+ $VERBOSE = nil
8
+
9
+ spec = Gem::Specification.new do |s|
10
+ s.name = 'webrick-high-performance'
11
+ s.version = '1.0.0'
12
+ s.summary = 'A high-performance WEBrick server'
13
+ s.description = 'A high-performance WEBrick server that takes advantage of sendfile(2) and fork(2) to serve static files really fast.'
14
+ s.author = 'Eric Hodel'
15
+ s.email = 'eric@robotcoop.com'
16
+
17
+ s.has_rdoc = true
18
+ s.files = File.read('Manifest.txt').split($/)
19
+ s.require_path = 'lib'
20
+
21
+ s.test_files = Dir.glob('test/test_*.rb')
22
+
23
+ s.add_dependency 'socket_sendfile', '>= 1.1.0'
24
+ s.add_dependency 'socket_accept_filter', '>= 1.0.0'
25
+ end
26
+
27
+ desc 'Run tests'
28
+ task :default => [ :test ]
29
+
30
+ Rake::TestTask.new('test') do |t|
31
+ t.libs << 'test'
32
+ t.pattern = 'test/test_*.rb'
33
+ t.verbose = true
34
+ end
35
+
36
+ desc 'Update Manifest.txt'
37
+ task :update_manifest do
38
+ sh "find . -type f | sed -e 's%./%%' | egrep -v 'svn|swp|~' | egrep -v '^(doc|pkg)/' | sort > Manifest.txt"
39
+ end
40
+
41
+ desc 'Generate RDoc'
42
+ Rake::RDocTask.new :rdoc do |rd|
43
+ rd.rdoc_dir = 'doc'
44
+ rd.rdoc_files.add 'lib', 'README', 'LICENSE'
45
+ rd.main = 'README'
46
+ rd.options << '-d' if `which dot` =~ /\/dot/
47
+ end
48
+
49
+ desc 'Generate RDoc for dev.robotcoop.com'
50
+ Rake::RDocTask.new :dev_rdoc do |rd|
51
+ rd.rdoc_dir = '../../../www/trunk/dev/html/Libraries/webrick-high-performance'
52
+ rd.rdoc_files.add 'lib', 'README', 'LICENSE'
53
+ rd.main = 'README'
54
+ rd.options << '-d' if `which dot` =~ /\/dot/
55
+ end
56
+
57
+ desc 'Build Gem'
58
+ Rake::GemPackageTask.new spec do |pkg|
59
+ pkg.need_tar = true
60
+ end
61
+
62
+ desc 'Clean up'
63
+ task :clean => [ :clobber_rdoc, :clobber_package ]
64
+
65
+ desc 'Clean up'
66
+ task :clobber => [ :clean ]
67
+
68
+ # vim: syntax=Ruby
69
+
@@ -0,0 +1,156 @@
1
+ require 'webrick'
2
+ require 'socket_accept_filter' rescue LoadError
3
+ require 'socket_sendfile'
4
+
5
+ class WEBrick::HTTPResponse # :nodoc:
6
+
7
+ alias old_send_body_io send_body_io
8
+ alias old_chunked? chunked?
9
+
10
+ def chunked?
11
+ return @body.is_a?(File) ? false : @chunked
12
+ end
13
+
14
+ ##
15
+ # Copied from WEBrick::HTTPResponse to add sendfile support.
16
+
17
+ def send_body_io(socket)
18
+ socket.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1 # HACK yuck
19
+
20
+ if @request_method == "HEAD"
21
+ # do nothing
22
+ elsif @body.kind_of? File
23
+ socket.sendfile @body
24
+ elsif chunked?
25
+ while buf = @body.read(BUFSIZE)
26
+ next if buf.empty?
27
+ data = ""
28
+ data << format("%x", buf.size) << CRLF
29
+ data << buf << CRLF
30
+ _write_data(socket, data)
31
+ @sent_size += buf.size
32
+ end
33
+ _write_data(socket, "0#{CRLF}#{CRLF}")
34
+ else
35
+ size = @header['content-length'].to_i
36
+ _send_file(socket, @body, 0, size)
37
+ @sent_size = size
38
+ end
39
+ ensure
40
+ @body.close
41
+ end
42
+
43
+ end
44
+
45
+ module WEBrick::Config
46
+
47
+ ##
48
+ # HighPerformanceServer default configuration.
49
+
50
+ HighPerformance = HTTP.dup.update(
51
+ :RequestTimeout => 2,
52
+ :Processes => 8
53
+ )
54
+
55
+ end
56
+
57
+ ##
58
+ # A high performance WEBrick server that takes advantage of sendfile(2) and
59
+ # fork(2) to drastically increase the performance of serving static files.
60
+ #
61
+ # Instead of starting a HighPerformanceServer like a regular HTTPServer, use
62
+ # HighPerformanceServer::create.
63
+
64
+ class WEBrick::HighPerformanceServer < WEBrick::HTTPServer
65
+
66
+ ##
67
+ # This process starts up a bunch of listeners than forks children to do the
68
+ # actual work.
69
+
70
+ @listeners = []
71
+
72
+ class << self
73
+
74
+ ##
75
+ # Server sockets for my children.
76
+
77
+ attr_accessor :listeners
78
+
79
+ ##
80
+ # Creates :Processes new HighPerformanceServers all listening on the same
81
+ # server sockets.
82
+ #
83
+ # +config+ and +default+ work the same as they do for HTTPServer.
84
+ #
85
+ # yields each forked child's server object. The server will not be
86
+ # started nor will signals be caught.
87
+ #
88
+ # Returns the pids of the created HighPerformanceServer children.
89
+ #
90
+ # Typical usage:
91
+ #
92
+ # WEBrick::HighPerformanceServer.create do |server|
93
+ # server.mount '/', WEBrick::HTTPServlet::FileHandler,
94
+ # '/usr/local/www/data'
95
+ # trap 'INT' do server.shutdown end
96
+ # trap 'TERM' do server.shutdown end
97
+ # server.start
98
+ # end
99
+
100
+ def create(config = {}, default = WEBrick::Config::HighPerformance)
101
+ config = default.dup.update config
102
+ bind_address = config[:BindAddress]
103
+ port = config[:Port]
104
+ processes = config[:Processes]
105
+ config[:Logger] ||= WEBrick::Log.new
106
+
107
+ @listeners = WEBrick::Utils.create_listeners bind_address, port
108
+ if @listeners.first.respond_to? :set_accept_filter then
109
+ @listeners.each do |server|
110
+ server.set_accept_filter 'httpready'
111
+ end
112
+ end
113
+
114
+ pids = []
115
+
116
+ processes.times do
117
+ pids << fork do
118
+ server = self.new config, default
119
+ yield server
120
+ end
121
+ end
122
+
123
+ return pids
124
+ end
125
+
126
+ end
127
+
128
+ ##
129
+ # Only need to override default.
130
+
131
+ def initialize(config = {}, default = WEBrick::Config::HighPerformance)
132
+ super config, default
133
+ end
134
+
135
+ ##
136
+ # HighPerformanceServer doesn't log. Oh you want access logs? Well tough!
137
+
138
+ def access_log(*args)
139
+ end
140
+
141
+ ##
142
+ # Our listeners have already been created, so suck them in from the class.
143
+
144
+ def listen(address, port)
145
+ @listeners = self.class.listeners
146
+ end
147
+
148
+ ##
149
+ # Don't close the listeners, just stop.
150
+
151
+ def shutdown
152
+ stop
153
+ end
154
+
155
+ end
156
+
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11.6
3
+ specification_version: 1
4
+ name: webrick-high-performance
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2006-03-24 00:00:00 -08:00
8
+ summary: A high-performance WEBrick server
9
+ require_paths:
10
+ - lib
11
+ email: eric@robotcoop.com
12
+ homepage:
13
+ rubyforge_project:
14
+ description: A high-performance WEBrick server that takes advantage of sendfile(2) and fork(2) to serve static files really fast.
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Eric Hodel
31
+ files:
32
+ - LICENSE
33
+ - Manifest.txt
34
+ - README
35
+ - Rakefile
36
+ - lib/webrick/highperformanceserver.rb
37
+ test_files: []
38
+
39
+ rdoc_options: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ executables: []
44
+
45
+ extensions: []
46
+
47
+ requirements: []
48
+
49
+ dependencies:
50
+ - !ruby/object:Gem::Dependency
51
+ name: socket_sendfile
52
+ version_requirement:
53
+ version_requirements: !ruby/object:Gem::Version::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: 1.1.0
58
+ version:
59
+ - !ruby/object:Gem::Dependency
60
+ name: socket_accept_filter
61
+ version_requirement:
62
+ version_requirements: !ruby/object:Gem::Version::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 1.0.0
67
+ version: