pitchfork 0.1.0 → 0.1.2

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: 990697289cbe2c021f74571daada6e866a7ad796df6c855be4852d106ad84b7d
4
- data.tar.gz: a8dd04579e7f955075ee96c95ff003f82de2897ba9f96839ddb05c7e701f45ce
3
+ metadata.gz: 7e837b05925916feb0b10fb28b2ddfbc8bb476aa77091217cbb012fd0c98f6c0
4
+ data.tar.gz: 5b89fafb322999c204408a642e39547a652b61968bd2eae4b1c87b77ae51baec
5
5
  SHA512:
6
- metadata.gz: 746fa1aaff6dd152e5d1b210088f1cdf2e3388d841fd302347919a470afd09e8a0188099a89280e6368d0dff8afe62c884140d332fa45dfdd3bed23b57d386df
7
- data.tar.gz: 6586706a8d2c5eb31fae62a822f5f7c405356ddab44c8f2add1ff3e994715ac724be0c666cc26d38acec5922ce10c3967c03c2d9a9580447ba3a8198e5d0667f
6
+ metadata.gz: df56d4c6bb70b5735e4859c1186b3e754210b84dfd457f804d6f93f2ac804205f351bd2ef557a09f05fa39896bb29180c6974ef9c74a062c8ddbb32506bc5c36
7
+ data.tar.gz: 93791c5474ec82f7470270f371df480ff7178ab903ee59799ddd975d0154841234895bce720c911b0fafba78016f36cc7fbac7210b7025417bff5fde898da0b8
data/CHANGELOG.md ADDED
@@ -0,0 +1,13 @@
1
+ # Unreleased
2
+
3
+ # 0.1.2
4
+
5
+ - Improve Ruby 3.2 and Rack 3 compatibility.
6
+
7
+ # 0.1.1
8
+
9
+ - Fix `extconf.rb` to move the extension in the right place on gem install. (#18)
10
+
11
+ # 0.1.0
12
+
13
+ Initial release
data/Gemfile CHANGED
@@ -6,4 +6,8 @@ gem 'minitest'
6
6
  gem 'rake'
7
7
  gem 'rake-compiler'
8
8
 
9
+ group :benchmark do
10
+ gem "puma"
11
+ end
12
+
9
13
  gemspec
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pitchfork (0.1.0)
4
+ pitchfork (0.1.2)
5
5
  rack (>= 2.0)
6
6
  raindrops (~> 0.7)
7
7
 
@@ -9,7 +9,10 @@ GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
11
  minitest (5.16.3)
12
- rack (3.0.0)
12
+ nio4r (2.5.8)
13
+ puma (5.6.5)
14
+ nio4r (~> 2.0)
15
+ rack (3.0.4.1)
13
16
  raindrops (0.20.0)
14
17
  rake (13.0.6)
15
18
  rake-compiler (1.2.0)
@@ -23,6 +26,7 @@ PLATFORMS
23
26
  DEPENDENCIES
24
27
  minitest
25
28
  pitchfork!
29
+ puma
26
30
  rake
27
31
  rake-compiler
28
32
 
data/LICENSE CHANGED
@@ -1,11 +1,10 @@
1
- Unicorn is copyrighted free software by all contributors, see logs in
1
+ Pitchfork is copyrighted free software by all contributors, see logs in
2
2
  revision control for names and email addresses of all of them.
3
3
 
4
4
  You can redistribute it and/or modify it under either the terms of the
5
5
  GNU General Public License (GPL) as published by the Free Software
6
6
  Foundation (FSF), either version 2 of the License, or (at your option)
7
- any later version. We currently prefer the GPLv3 or later for
8
- derivative works, but the GPLv2 is fine.
7
+ any later version.
9
8
 
10
9
  The complete texts of the GPLv2 and GPLv3 are below:
11
10
  GPLv2 - https://www.gnu.org/licenses/gpl-2.0.txt
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  `pitchfork` is a preforking HTTP server for Rack applications designed
4
4
  to minimize memory usage by maximizing Copy-on-Write performance.
5
5
 
6
- Like [`unicorn`](https://yhbt.net/unicorn/README.html) (which `pitchfork` is a derivative of), is it designed to
6
+ Like [`unicorn`](https://yhbt.net/unicorn/README.html) (of which `pitchfork` is a derivative), it is designed to
7
7
  only serve fast clients on low-latency, high-bandwidth connections and take
8
8
  advantage of features in Unix/Unix-like kernels. Slow clients should
9
9
  only be served by placing a reverse proxy capable of fully buffering
@@ -99,6 +99,16 @@ compatibility with existing applications.
99
99
  Most command-line options for other Rack applications (above) are also
100
100
  supported. Run `pitchfork -h` to see command-line options.
101
101
 
102
+ ## Relation to Unicorn
103
+
104
+ Pitchfork initially started as a Unicorn patch, however some of Unicorn features
105
+ as well as Unicorn policy of supporting extremely old Ruby version made it challenging.
106
+
107
+ Forking was the occasion to significantly reduce the complexity.
108
+
109
+ However some large parts of Pitchfork like the HTTP parser are still mostly unchanged from Unicorn, and Unicorn
110
+ is fairly stable these days. As such we aim to backport any Unicorn patches that may apply to Pitchfork and vice versa.
111
+
102
112
  ## License
103
113
 
104
114
  pitchfork is copyright 2022 Shopify Inc and all contributors.
@@ -108,8 +118,7 @@ Unicorn is copyright 2009-2018 by all contributors (see logs in git).
108
118
  It is based on Mongrel 1.1.5.
109
119
  Mongrel is copyright 2007 Zed A. Shaw and contributors.
110
120
 
111
- pitchfork is licensed under (your choice) of the GPLv2 or later
112
- (GPLv3+ preferred), or Ruby (1.8)-specific terms.
121
+ pitchfork is licensed under the GPLv2 or later or Ruby (1.8)-specific terms.
113
122
  See the included LICENSE file for details.
114
123
 
115
124
  ## Thanks
@@ -0,0 +1,32 @@
1
+ # Benchmarks
2
+
3
+ ## Copy on Write Efficiency
4
+
5
+ This benchmark aimed to compare real memory usage of differnet servers.
6
+
7
+ For instance, Puma 2 workers + 2 threads:
8
+
9
+ ```bash
10
+ $ PORT=9292 bundle exec benchmark/cow_benchmark.rb puma -w 2 -t 2 --preload
11
+ Booting server...
12
+ Warming the app with ab...
13
+ Memory Usage:
14
+ Single Worker Memory Usage: 207.5 MiB
15
+ Total Cluster Memory Usage: 601.6 MiB
16
+ ```
17
+
18
+ Pitchfork 4 workers:
19
+
20
+ ```bash
21
+ $ PORT=8080 bundle exec benchmark/cow_benchmark.rb pitchfork -c examples/pitchfork.conf.minimal.rb
22
+ Booting server...
23
+ Warming the app with ab...
24
+ Memory Usage:
25
+ Single Worker Memory Usage: 62.6 MiB
26
+ Total Cluster Memory Usage: 320.3 MiB
27
+ ```
28
+
29
+ The `constant_caches.ru` application is specifically crafted to demonstrate how shared memory regions
30
+ get invalidated as applications execute more and more code.
31
+
32
+ It is an extreme example for benchmark purposes.
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ require "net/http"
3
+
4
+ app_path = File.expand_path('../examples/constant_caches.ru', __dir__)
5
+
6
+ puts "Booting server..."
7
+ pid = Process.spawn(*ARGV, app_path, out: File::NULL, err: File::NULL)
8
+ sleep 5
9
+ app_url = "http://localhost:#{ENV.fetch('PORT')}/"
10
+ puts "Warming the app with ab..."
11
+ system("ab", "-c", "4", "-n", "500", app_url, out: File::NULL, err: File::NULL)
12
+ sleep 3
13
+ puts "Memory Usage:"
14
+ puts Net::HTTP.get(URI(app_url))
15
+
16
+ Process.kill("TERM", pid)
17
+ Process.wait
@@ -1,4 +1,4 @@
1
- require "pitchfork/mem_info"
1
+ require_relative "../lib/pitchfork/mem_info"
2
2
 
3
3
  module App
4
4
  CONST_NUM = Integer(ENV.fetch("NUM", 100_000))
@@ -1,5 +1,5 @@
1
1
  # Minimal sample configuration file for Pitchfork
2
2
 
3
- listen 2007 # by default Pitchfork listens on port 8080
3
+ # listen 2007 # by default Pitchfork listens on port 8080
4
4
  worker_processes 4 # this should be >= nr_cpus
5
5
  refork_after [50, 100, 1000]
@@ -11,4 +11,4 @@ else
11
11
  end
12
12
 
13
13
  have_func('epoll_create1', %w(sys/epoll.h))
14
- create_makefile("pitchfork_http")
14
+ create_makefile("pitchfork/pitchfork_http")
@@ -20,6 +20,18 @@ module Pitchfork
20
20
  "#{code} #{STATUS_CODES[code]}\r\n\r\n"
21
21
  end
22
22
 
23
+ def append_header(buf, key, value)
24
+ case value
25
+ when Array # Rack 3
26
+ value.each { |v| buf << "#{key}: #{v}\r\n" }
27
+ when /\n/ # Rack 2
28
+ # avoiding blank, key-only cookies with /\n+/
29
+ value.split(/\n+/).each { |v| buf << "#{key}: #{v}\r\n" }
30
+ else
31
+ buf << "#{key}: #{value}\r\n"
32
+ end
33
+ end
34
+
23
35
  # writes the rack_response to socket as an HTTP response
24
36
  def http_response_write(socket, status, headers, body,
25
37
  req = Pitchfork::HttpParser.new)
@@ -41,12 +53,7 @@ module Pitchfork
41
53
  # key in Rack < 1.5
42
54
  hijack = value
43
55
  else
44
- if value =~ /\n/
45
- # avoiding blank, key-only cookies with /\n+/
46
- value.split(/\n+/).each { |v| buf << "#{key}: #{v}\r\n" }
47
- else
48
- buf << "#{key}: #{value}\r\n"
49
- end
56
+ append_header(buf, key, value)
50
57
  end
51
58
  end
52
59
  socket.write(buf << "\r\n".freeze)
@@ -572,22 +572,11 @@ module Pitchfork
572
572
  end
573
573
 
574
574
  def e103_response_write(client, headers)
575
- response = if @request.response_start_sent
576
- "103 Early Hints\r\n"
577
- else
578
- "HTTP/1.1 103 Early Hints\r\n"
579
- end
580
-
581
- headers.each_pair do |k, vs|
582
- next if !vs || vs.empty?
583
- values = vs.to_s.split("\n".freeze)
584
- values.each do |v|
585
- response << "#{k}: #{v}\r\n"
586
- end
587
- end
588
- response << "\r\n".freeze
589
- response << "HTTP/1.1 ".freeze if @request.response_start_sent
590
- client.write(response)
575
+ rss = @request.response_start_sent
576
+ buf = rss ? "103 Early Hints\r\n" : "HTTP/1.1 103 Early Hints\r\n"
577
+ headers.each { |key, value| append_header(buf, key, value) }
578
+ buf << (rss ? "\r\nHTTP/1.1 ".freeze : "\r\n".freeze)
579
+ client.write(buf)
591
580
  end
592
581
 
593
582
  def e100_response_write(client, env)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pitchfork
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.2"
5
5
  module Const
6
6
  UNICORN_VERSION = '6.1.0'
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pitchfork
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean Boussier
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-05 00:00:00.000000000 Z
11
+ date: 2023-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: raindrops
@@ -53,6 +53,7 @@ files:
53
53
  - ".gitattributes"
54
54
  - ".github/workflows/ci.yml"
55
55
  - ".gitignore"
56
+ - CHANGELOG.md
56
57
  - COPYING
57
58
  - Dockerfile
58
59
  - Gemfile
@@ -60,6 +61,8 @@ files:
60
61
  - LICENSE
61
62
  - README.md
62
63
  - Rakefile
64
+ - benchmark/README.md
65
+ - benchmark/cow_benchmark.rb
63
66
  - docs/Application_Timeouts.md
64
67
  - docs/CONFIGURATION.md
65
68
  - docs/DESIGN.md