pitchfork 0.12.0 → 0.14.0

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +7 -3
  3. data/.ruby-version +1 -0
  4. data/CHANGELOG.md +12 -0
  5. data/Dockerfile +1 -1
  6. data/Gemfile.lock +3 -5
  7. data/benchmark/README.md +1 -1
  8. data/benchmark/cow_benchmark.rb +1 -0
  9. data/docs/CONFIGURATION.md +39 -1
  10. data/docs/MIGRATING_FROM_UNICORN.md +34 -0
  11. data/docs/WHY_MIGRATE.md +5 -0
  12. data/examples/constant_caches.ru +1 -0
  13. data/examples/echo.ru +1 -0
  14. data/examples/hello.ru +1 -0
  15. data/examples/pitchfork.conf.minimal.rb +1 -0
  16. data/examples/pitchfork.conf.rb +1 -0
  17. data/examples/pitchfork.conf.service.rb +27 -0
  18. data/exe/pitchfork +5 -4
  19. data/ext/pitchfork_http/epollexclusive.h +2 -2
  20. data/ext/pitchfork_http/extconf.rb +3 -0
  21. data/ext/pitchfork_http/memory_page.c +223 -0
  22. data/ext/pitchfork_http/pitchfork_http.c +213 -211
  23. data/ext/pitchfork_http/pitchfork_http.rl +3 -1
  24. data/lib/pitchfork/children.rb +21 -15
  25. data/lib/pitchfork/configurator.rb +13 -0
  26. data/lib/pitchfork/const.rb +1 -0
  27. data/lib/pitchfork/flock.rb +1 -0
  28. data/lib/pitchfork/http_parser.rb +18 -72
  29. data/lib/pitchfork/http_response.rb +4 -3
  30. data/lib/pitchfork/http_server.rb +181 -62
  31. data/lib/pitchfork/launcher.rb +1 -0
  32. data/lib/pitchfork/message.rb +11 -6
  33. data/lib/pitchfork/select_waiter.rb +1 -0
  34. data/lib/pitchfork/shared_memory.rb +16 -14
  35. data/lib/pitchfork/socket_helper.rb +2 -1
  36. data/lib/pitchfork/stream_input.rb +6 -5
  37. data/lib/pitchfork/tee_input.rb +3 -2
  38. data/lib/pitchfork/tmpio.rb +1 -0
  39. data/lib/pitchfork/version.rb +1 -1
  40. data/lib/pitchfork/worker.rb +44 -15
  41. data/lib/pitchfork.rb +1 -20
  42. data/pitchfork.gemspec +0 -1
  43. metadata +7 -18
  44. data/lib/pitchfork/app/old_rails/static.rb +0 -59
@@ -1,11 +1,12 @@
1
1
  # -*- encoding: binary -*-
2
+ # frozen_string_literal: true
2
3
  require 'pitchfork/shared_memory'
3
4
 
4
5
  module Pitchfork
5
6
  # This class and its members can be considered a stable interface
6
7
  # and will not change in a backwards-incompatible fashion between
7
8
  # releases of pitchfork. Knowledge of this class is generally not
8
- # not needed for most users of pitchfork.
9
+ # needed for most users of pitchfork.
9
10
  #
10
11
  # Some users may want to access it in the after_worker_fork/after_mold_fork hooks.
11
12
  # See the Pitchfork::Configurator RDoc for examples.
@@ -23,20 +24,7 @@ module Pitchfork
23
24
  @to_io = @master = nil
24
25
  @exiting = false
25
26
  @requests_count = 0
26
- if nr
27
- @deadline_drop = SharedMemory.worker_deadline(nr)
28
- self.deadline = 0
29
- else
30
- promoted!(nil)
31
- end
32
- end
33
-
34
- def meminfo
35
- @meminfo ||= MemInfo.new(pid) if pid
36
- end
37
-
38
- def refresh
39
- meminfo&.update
27
+ init_deadline
40
28
  end
41
29
 
42
30
  def exiting?
@@ -93,6 +81,10 @@ module Pitchfork
93
81
  send_message_nonblock(Message::SpawnWorker.new(new_worker.nr))
94
82
  end
95
83
 
84
+ def spawn_service(_new_service)
85
+ send_message_nonblock(Message::SpawnService.new)
86
+ end
87
+
96
88
  def promote!(timeout)
97
89
  @generation += 1
98
90
  promoted!(timeout)
@@ -110,6 +102,10 @@ module Pitchfork
110
102
  @mold
111
103
  end
112
104
 
105
+ def service?
106
+ false
107
+ end
108
+
113
109
  def to_io # IO.select-compatible
114
110
  @to_io.to_io
115
111
  end
@@ -219,6 +215,15 @@ module Pitchfork
219
215
 
220
216
  private
221
217
 
218
+ def init_deadline
219
+ if nr
220
+ @deadline_drop = SharedMemory.worker_deadline(@nr)
221
+ self.deadline = 0
222
+ else
223
+ promoted!(nil)
224
+ end
225
+ end
226
+
222
227
  def pipe=(socket)
223
228
  raise ArgumentError, "pipe can't be nil" unless socket
224
229
  Info.keep_io(socket)
@@ -240,4 +245,28 @@ module Pitchfork
240
245
  success
241
246
  end
242
247
  end
248
+
249
+ class Service < Worker
250
+ def initialize(pid: nil, generation: 0)
251
+ super(nil, pid: pid, generation: generation)
252
+ end
253
+
254
+ def service?
255
+ true
256
+ end
257
+
258
+ def register_to_master(control_socket)
259
+ create_socketpair!
260
+ message = Message::ServiceSpawned.new(@pid, generation, @master)
261
+ control_socket.sendmsg(message)
262
+ @master.close
263
+ end
264
+
265
+ private
266
+
267
+ def init_deadline
268
+ @deadline_drop = SharedMemory.service_deadline
269
+ self.deadline = 0
270
+ end
271
+ end
243
272
  end
data/lib/pitchfork.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: binary -*-
2
+ # frozen_string_literal: true
2
3
  require 'etc'
3
4
  require 'stringio'
4
- require 'raindrops'
5
5
  require 'io/wait'
6
6
 
7
7
  begin
@@ -119,25 +119,6 @@ module Pitchfork
119
119
  exc.backtrace.each { |line| logger.error(line) }
120
120
  end
121
121
 
122
- F_SETPIPE_SZ = 1031 if RUBY_PLATFORM =~ /linux/
123
-
124
- def pipe # :nodoc:
125
- IO.pipe.each do |io|
126
- # shrink pipes to minimize impact on /proc/sys/fs/pipe-user-pages-soft
127
- # limits.
128
- if defined?(F_SETPIPE_SZ)
129
- begin
130
- io.fcntl(F_SETPIPE_SZ, Raindrops::PAGE_SIZE)
131
- rescue Errno::EINVAL
132
- # old kernel
133
- rescue Errno::EPERM
134
- # resizes fail if Linux is close to the pipe limit for the user
135
- # or if the user does not have permissions to resize
136
- end
137
- end
138
- end
139
- end
140
-
141
122
  def socketpair
142
123
  pair = UNIXSocket.socketpair(@socket_type).map { |s| MessageSocket.new(s) }
143
124
  pair[0].close_write
data/pitchfork.gemspec CHANGED
@@ -19,7 +19,6 @@ Gem::Specification.new do |s|
19
19
 
20
20
  s.required_ruby_version = ">= 2.5.0"
21
21
 
22
- s.add_dependency(%q<raindrops>, '~> 0.7')
23
22
  s.add_dependency(%q<rack>, '>= 2.0')
24
23
 
25
24
  # Note: To avoid ambiguity, we intentionally avoid the SPDX-compatible
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pitchfork
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean Boussier
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-03-14 00:00:00.000000000 Z
11
+ date: 2024-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: raindrops
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '0.7'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '0.7'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: rack
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -54,6 +40,7 @@ files:
54
40
  - ".gitattributes"
55
41
  - ".github/workflows/ci.yml"
56
42
  - ".gitignore"
43
+ - ".ruby-version"
57
44
  - CHANGELOG.md
58
45
  - COPYING
59
46
  - Dockerfile
@@ -68,6 +55,7 @@ files:
68
55
  - docs/CONFIGURATION.md
69
56
  - docs/DESIGN.md
70
57
  - docs/FORK_SAFETY.md
58
+ - docs/MIGRATING_FROM_UNICORN.md
71
59
  - docs/PHILOSOPHY.md
72
60
  - docs/REFORKING.md
73
61
  - docs/SIGNALS.md
@@ -79,6 +67,7 @@ files:
79
67
  - examples/nginx.conf
80
68
  - examples/pitchfork.conf.minimal.rb
81
69
  - examples/pitchfork.conf.rb
70
+ - examples/pitchfork.conf.service.rb
82
71
  - examples/unicorn.socket
83
72
  - exe/pitchfork
84
73
  - ext/pitchfork_http/CFLAGS
@@ -90,11 +79,11 @@ files:
90
79
  - ext/pitchfork_http/extconf.rb
91
80
  - ext/pitchfork_http/global_variables.h
92
81
  - ext/pitchfork_http/httpdate.c
82
+ - ext/pitchfork_http/memory_page.c
93
83
  - ext/pitchfork_http/pitchfork_http.c
94
84
  - ext/pitchfork_http/pitchfork_http.rl
95
85
  - ext/pitchfork_http/pitchfork_http_common.rl
96
86
  - lib/pitchfork.rb
97
- - lib/pitchfork/app/old_rails/static.rb
98
87
  - lib/pitchfork/children.rb
99
88
  - lib/pitchfork/chunked.rb
100
89
  - lib/pitchfork/configurator.rb
@@ -138,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
127
  - !ruby/object:Gem::Version
139
128
  version: '0'
140
129
  requirements: []
141
- rubygems_version: 3.5.5
130
+ rubygems_version: 3.5.9
142
131
  signing_key:
143
132
  specification_version: 4
144
133
  summary: Rack HTTP server for fast clients and Unix
@@ -1,59 +0,0 @@
1
- # -*- encoding: binary -*-
2
- # :enddoc:
3
- # This code is based on the original Rails handler in Mongrel
4
- # Copyright (c) 2005 Zed A. Shaw
5
- # Copyright (c) 2009 Eric Wong
6
- # You can redistribute it and/or modify it under the same terms as Ruby 1.8 or
7
- # the GPLv3
8
-
9
- # Static file handler for Rails < 2.3. This handler is only provided
10
- # as a convenience for developers. Performance-minded deployments should
11
- # use nginx (or similar) for serving static files.
12
- #
13
- # This supports page caching directly and will try to resolve a
14
- # request in the following order:
15
- #
16
- # * If the requested exact PATH_INFO exists as a file then serve it.
17
- # * If it exists at PATH_INFO+rest_operator+".html" exists
18
- # then serve that.
19
- #
20
- # This means that if you are using page caching it will actually work
21
- # with Pitchfork and you should see a decent speed boost (but not as
22
- # fast as if you use a static server like nginx).
23
- class Pitchfork::App::OldRails::Static < Struct.new(:app, :root, :file_server)
24
- FILE_METHODS = { 'GET' => true, 'HEAD' => true }
25
-
26
- # avoid allocating new strings for hash lookups
27
- REQUEST_METHOD = 'REQUEST_METHOD'
28
- REQUEST_URI = 'REQUEST_URI'
29
- PATH_INFO = 'PATH_INFO'
30
-
31
- def initialize(app)
32
- self.app = app
33
- self.root = "#{::RAILS_ROOT}/public"
34
- self.file_server = ::Rack::File.new(root)
35
- end
36
-
37
- def call(env)
38
- # short circuit this ASAP if serving non-file methods
39
- FILE_METHODS.include?(env[REQUEST_METHOD]) or return app.call(env)
40
-
41
- # first try the path as-is
42
- path_info = env[PATH_INFO].chomp("/")
43
- if File.file?("#{root}/#{::Rack::Utils.unescape(path_info)}")
44
- # File exists as-is so serve it up
45
- env[PATH_INFO] = path_info
46
- return file_server.call(env)
47
- end
48
-
49
- # then try the cached version:
50
- path_info << ActionController::Base.page_cache_extension
51
-
52
- if File.file?("#{root}/#{::Rack::Utils.unescape(path_info)}")
53
- env[PATH_INFO] = path_info
54
- return file_server.call(env)
55
- end
56
-
57
- app.call(env) # call OldRails
58
- end
59
- end if defined?(Pitchfork::App::OldRails)