pitchfork 0.12.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
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)