pitchfork 0.11.1 → 0.12.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5dc129b2e6e6e940be0f9e388400a376614a65a125a64b68c73b919744c433b3
4
- data.tar.gz: b12e1d5f360edc7159567060c095b40510e8e89c54dae058882742c29c830f78
3
+ metadata.gz: 7bf3d38329b727807923b9d57bfa09f686e313e30b374542f703b9b27f8f6afb
4
+ data.tar.gz: b47932131e9873ac74617d9cabdd99d2d7c948dcd03564a544b51bd0449ad54c
5
5
  SHA512:
6
- metadata.gz: 4a43b0204dc0e77a4d28007dbfd89e9645724a4198ea6ec7ffa0895aefaf075bd42d4303c37d0f7e61afb550b665b78ab6b22ca9f934ef2d3721883acf0a68cd
7
- data.tar.gz: 7eb41807d6971ac948ee264b1f70fd2e16afcf8f289655073c876b752a53a405b9705e97509f5be82c519ee12694ecf1910b18a20cce8aad3ce9a4ffd3af9ac6
6
+ metadata.gz: d44f02f6db020cb66ccf17e7221bf86fbec3da47f2ddb9a3d00da5a857472e512f490b02e60f8394a95b595074ab86aa33f2d0822dab45f60090fc355a97bee9
7
+ data.tar.gz: 868ae5172e8bcee925528a12d3d332c40fb88fd2d6ca1394273ddb5cbe1fde92b0e17ace1abd3681620abffb325a381d6c6622885cdf21f965ade000180bc890
@@ -14,7 +14,7 @@ jobs:
14
14
  runs-on: ubuntu-latest
15
15
  steps:
16
16
  - name: Check out code
17
- uses: actions/checkout@v3
17
+ uses: actions/checkout@v4
18
18
 
19
19
  - name: Set up Ruby
20
20
  uses: ruby/setup-ruby@v1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Unreleased
2
2
 
3
+ # 0.12.0
4
+
5
+ - Disable IO tracking on Rubies older than 3.2.3 to avoid running into https://bugs.ruby-lang.org/issues/19531.
6
+ This Ruby bug can lead to memory corruption that cause VM crashes when calling various IO methods.
7
+ - Implement `rack.response_finished` (#97).
8
+ - Don't break the `rack.after_reply` callback chain if one callback raises (#97).
9
+
3
10
  # 0.11.1
4
11
 
5
12
  - Fix Ruby 3.4-dev compatibility.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pitchfork (0.11.1)
4
+ pitchfork (0.12.0)
5
5
  rack (>= 2.0)
6
6
  raindrops (~> 0.7)
7
7
 
@@ -732,7 +732,7 @@ module Pitchfork
732
732
  end
733
733
  end
734
734
 
735
- env["rack.after_reply"] = []
735
+ env["rack.response_finished"] = env["rack.after_reply"] = []
736
736
 
737
737
  status, headers, body = @app.call(env)
738
738
 
@@ -758,11 +758,21 @@ module Pitchfork
758
758
  client.close # flush and uncork socket immediately, no keepalive
759
759
  end
760
760
  env
761
- rescue => e
762
- handle_error(client, e)
761
+ rescue => application_error
762
+ handle_error(client, application_error)
763
763
  env
764
764
  ensure
765
- env["rack.after_reply"].each(&:call) if env
765
+ if env
766
+ env["rack.response_finished"].each do |callback|
767
+ if callback.arity == 0
768
+ callback.call
769
+ else
770
+ callback.call(env, status, headers, application_error)
771
+ end
772
+ rescue => callback_error
773
+ Pitchfork.log_error(@logger, "rack.after_reply error", callback_error)
774
+ end
775
+ end
766
776
  timeout_handler.finished
767
777
  env
768
778
  end
@@ -4,9 +4,6 @@ require 'pitchfork/shared_memory'
4
4
 
5
5
  module Pitchfork
6
6
  module Info
7
- @workers_count = 0
8
- @fork_safe = true
9
-
10
7
  class WeakSet # :nodoc
11
8
  def initialize
12
9
  @map = ObjectSpace::WeakMap.new
@@ -27,42 +24,68 @@ module Pitchfork
27
24
  end
28
25
  end
29
26
 
30
- @kept_ios = WeakSet.new
27
+ if RUBY_VERSION < "3.2.3" && RUBY_ENGINE == "ruby"
28
+ class << self
29
+ def keep_io(io)
30
+ io # noop
31
+ end
31
32
 
32
- class << self
33
- attr_accessor :workers_count
33
+ def keep_ios(ios)
34
+ ios # noop
35
+ end
34
36
 
35
- def keep_io(io)
36
- raise ArgumentError, "#{io.inspect} doesn't respond to :to_io" unless io.respond_to?(:to_io)
37
- @kept_ios << io
38
- io
39
- end
37
+ def close_all_ios!
38
+ raise NoMethodError, <<~MSG
39
+ Your Ruby version is subject to a bug that prevent `.close_all_ios!` from working.
40
+ See: https://bugs.ruby-lang.org/issues/19531.
40
41
 
41
- def keep_ios(ios)
42
- ios.each { |io| keep_io(io) }
42
+ Consider upgrading to Ruby 3.2.3+
43
+ MSG
44
+ end
43
45
  end
46
+ else
47
+ @kept_ios = WeakSet.new
48
+
49
+ class << self
50
+ def keep_io(io)
51
+ raise ArgumentError, "#{io.inspect} doesn't respond to :to_io" unless io.respond_to?(:to_io)
52
+ @kept_ios << io
53
+ io
54
+ end
44
55
 
45
- def close_all_ios!
46
- ignored_ios = [$stdin, $stdout, $stderr, STDIN, STDOUT, STDERR].uniq.compact
47
-
48
- @kept_ios.each do |io_like|
49
- ignored_ios << (io_like.is_a?(IO) ? io_like : io_like.to_io)
56
+ def keep_ios(ios)
57
+ ios.each { |io| keep_io(io) }
50
58
  end
51
59
 
52
- ObjectSpace.each_object(IO) do |io|
53
- if io_open?(io) && io_autoclosed?(io) && !ignored_ios.include?(io)
54
- if io.is_a?(TCPSocket)
55
- # If we inherited a TCP Socket, calling #close directly could send FIN or RST.
56
- # So we first reopen /dev/null to avoid that.
57
- io.reopen(File::NULL)
58
- end
59
- begin
60
- io.close
61
- rescue Errno::EBADF
60
+ def close_all_ios!
61
+ ignored_ios = [$stdin, $stdout, $stderr, STDIN, STDOUT, STDERR].uniq.compact
62
+
63
+ @kept_ios.each do |io_like|
64
+ ignored_ios << (io_like.is_a?(IO) ? io_like : io_like.to_io)
65
+ end
66
+
67
+ ObjectSpace.each_object(IO) do |io|
68
+ if io_open?(io) && io_autoclosed?(io) && !ignored_ios.include?(io)
69
+ if io.is_a?(TCPSocket)
70
+ # If we inherited a TCP Socket, calling #close directly could send FIN or RST.
71
+ # So we first reopen /dev/null to avoid that.
72
+ io.reopen(File::NULL)
73
+ end
74
+ begin
75
+ io.close
76
+ rescue Errno::EBADF
77
+ end
62
78
  end
63
79
  end
64
80
  end
65
81
  end
82
+ end
83
+
84
+ @workers_count = 0
85
+ @fork_safe = true
86
+
87
+ class << self
88
+ attr_accessor :workers_count
66
89
 
67
90
  def fork_safe?
68
91
  @fork_safe
@@ -14,6 +14,7 @@ module Pitchfork
14
14
  FD = Struct.new(:index)
15
15
 
16
16
  def initialize(socket)
17
+ raise ArgumentError, "expected a socket, got: #{socket.inspect}" unless socket
17
18
  @socket = socket
18
19
  end
19
20
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pitchfork
4
- VERSION = "0.11.1"
4
+ VERSION = "0.12.0"
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.11.1
4
+ version: 0.12.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-06 00:00:00.000000000 Z
11
+ date: 2024-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: raindrops