timeout 0.3.0 → 0.4.1

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: d65cc31f39a22fdc316cc89f8f8e4adb95131700972fca8f65cb79ab5c844858
4
- data.tar.gz: 9cb854b05e02484a179c83f56ddb3d85b885806148fd1350223d5406cc20c706
3
+ metadata.gz: 2c10c971f22da3b85c5219ff6c8d8f018de3b04ba2ae7c64c4f368bd9e2ebdb7
4
+ data.tar.gz: 26d74226d36fa316564ec6665218bb1665accbbe420305451285d0ff7799bc16
5
5
  SHA512:
6
- metadata.gz: d88ad9e1965efed376d164a1dd992f3aa423aab9bf3f6c0fdc482affc9895991ff542831ce6d8159771fa000d5e3e5c0679fedbfa73f94fe8c6548fe9f387714
7
- data.tar.gz: '00529ed0c665d1f24c466461ab4c9298d79db2a00f9d12993e1cda402543006f3cf9e88c6f5a36286bef5b97fbaa4f0894cd4b1715b5691bb883bb7e48f37d4f'
6
+ metadata.gz: a256682e2e237e067eb602add2644138a24cfbad1fce1c3d5b47173b8c1ae1184cff832799982bbff2127fdc2ff061ca2292047d41a15470c4c96b05975252c3
7
+ data.tar.gz: 4d7b2d79b6e75f5519cd3b55f010a14c8612e01ac4f859a8352e812242556f7b7f7ddbd53fdf793bfff7815ac6a080bbb71ce7690938890c93f8cda44002e6e6
data/Gemfile CHANGED
@@ -6,4 +6,5 @@ group :development do
6
6
  gem "bundler"
7
7
  gem "rake"
8
8
  gem "test-unit"
9
+ gem "test-unit-ruby-core"
9
10
  end
data/lib/timeout.rb CHANGED
@@ -23,29 +23,26 @@
23
23
  # Copyright:: (C) 2000 Information-technology Promotion Agency, Japan
24
24
 
25
25
  module Timeout
26
- VERSION = "0.3.0"
26
+ VERSION = "0.4.1"
27
+
28
+ # Internal error raised to when a timeout is triggered.
29
+ class ExitException < Exception
30
+ def exception(*)
31
+ self
32
+ end
33
+ end
27
34
 
28
35
  # Raised by Timeout.timeout when the block times out.
29
36
  class Error < RuntimeError
30
- attr_reader :thread
31
-
32
- def self.catch(*args)
33
- exc = new(*args)
34
- exc.instance_variable_set(:@thread, Thread.current)
35
- exc.instance_variable_set(:@catch_value, exc)
36
- ::Kernel.catch(exc) {yield exc}
37
- end
37
+ def self.handle_timeout(message)
38
+ exc = ExitException.new(message)
38
39
 
39
- def exception(*)
40
- # TODO: use Fiber.current to see if self can be thrown
41
- if self.thread == Thread.current
42
- bt = caller
43
- begin
44
- throw(@catch_value, bt)
45
- rescue UncaughtThrowError
46
- end
40
+ begin
41
+ yield exc
42
+ rescue ExitException => e
43
+ raise new(message) if exc.equal?(e)
44
+ raise
47
45
  end
48
- super
49
46
  end
50
47
  end
51
48
 
@@ -62,7 +59,7 @@ module Timeout
62
59
 
63
60
  def initialize(thread, timeout, exception_class, message)
64
61
  @thread = thread
65
- @deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + timeout
62
+ @deadline = GET_TIME.call(Process::CLOCK_MONOTONIC) + timeout
66
63
  @exception_class = exception_class
67
64
  @message = message
68
65
 
@@ -98,7 +95,7 @@ module Timeout
98
95
  private_constant :Request
99
96
 
100
97
  def self.create_timeout_thread
101
- Thread.new do
98
+ watcher = Thread.new do
102
99
  requests = []
103
100
  while true
104
101
  until QUEUE.empty? and !requests.empty? # wait to have at least one request
@@ -109,7 +106,7 @@ module Timeout
109
106
 
110
107
  now = 0.0
111
108
  QUEUE_MUTEX.synchronize do
112
- while (now = Process.clock_gettime(Process::CLOCK_MONOTONIC)) < closest_deadline and QUEUE.empty?
109
+ while (now = GET_TIME.call(Process::CLOCK_MONOTONIC)) < closest_deadline and QUEUE.empty?
113
110
  CONDVAR.wait(QUEUE_MUTEX, closest_deadline - now)
114
111
  end
115
112
  end
@@ -120,6 +117,10 @@ module Timeout
120
117
  requests.reject!(&:done?)
121
118
  end
122
119
  end
120
+ ThreadGroup::Default.add(watcher) unless watcher.group.enclosed?
121
+ watcher.name = "Timeout stdlib thread"
122
+ watcher.thread_variable_set(:"\0__detached_thread__", true)
123
+ watcher
123
124
  end
124
125
  private_class_method :create_timeout_thread
125
126
 
@@ -132,6 +133,12 @@ module Timeout
132
133
  end
133
134
  end
134
135
  end
136
+
137
+ # We keep a private reference so that time mocking libraries won't break
138
+ # Timeout.
139
+ GET_TIME = Process.method(:clock_gettime)
140
+ private_constant :GET_TIME
141
+
135
142
  # :startdoc:
136
143
 
137
144
  # Perform an operation in a block, raising an error if it takes longer than
@@ -185,8 +192,7 @@ module Timeout
185
192
  if klass
186
193
  perform.call(klass)
187
194
  else
188
- backtrace = Error.catch(&perform)
189
- raise Error, message, backtrace
195
+ Error.handle_timeout(message, &perform)
190
196
  end
191
197
  end
192
198
  module_function :timeout
data/timeout.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  name = File.basename(__FILE__, ".gemspec")
4
- version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
4
+ version = ["lib", Array.new(name.count("-")+1, ".").join("/")].find do |dir|
5
5
  break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
6
6
  /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
7
7
  end rescue nil
@@ -21,10 +21,12 @@ Gem::Specification.new do |spec|
21
21
  spec.metadata["homepage_uri"] = spec.homepage
22
22
  spec.metadata["source_code_uri"] = spec.homepage
23
23
 
24
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
25
- `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ spec.required_ruby_version = '>= 2.6.0'
25
+
26
+ spec.files = Dir.chdir(__dir__) do
27
+ `git ls-files -z`.split("\x0").reject do |f|
28
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features|rakelib)/|\.(?:git|travis|circleci)|appveyor|Rakefile)})
29
+ end
26
30
  end
27
- spec.bindir = "exe"
28
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
31
  spec.require_paths = ["lib"]
30
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timeout
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yukihiro Matsumoto
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-25 00:00:00.000000000 Z
11
+ date: 2023-11-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Auto-terminate potentially long-running operations in Ruby.
14
14
  email:
@@ -17,15 +17,9 @@ executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
- - ".github/dependabot.yml"
21
- - ".github/workflows/test.yml"
22
- - ".gitignore"
23
20
  - Gemfile
24
21
  - LICENSE.txt
25
22
  - README.md
26
- - Rakefile
27
- - bin/console
28
- - bin/setup
29
23
  - lib/timeout.rb
30
24
  - timeout.gemspec
31
25
  homepage: https://github.com/ruby/timeout
@@ -43,14 +37,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
43
37
  requirements:
44
38
  - - ">="
45
39
  - !ruby/object:Gem::Version
46
- version: '0'
40
+ version: 2.6.0
47
41
  required_rubygems_version: !ruby/object:Gem::Requirement
48
42
  requirements:
49
43
  - - ">="
50
44
  - !ruby/object:Gem::Version
51
45
  version: '0'
52
46
  requirements: []
53
- rubygems_version: 3.3.7
47
+ rubygems_version: 3.5.0.dev
54
48
  signing_key:
55
49
  specification_version: 4
56
50
  summary: Auto-terminate potentially long-running operations in Ruby.
@@ -1,6 +0,0 @@
1
- version: 2
2
- updates:
3
- - package-ecosystem: 'github-actions'
4
- directory: '/'
5
- schedule:
6
- interval: 'weekly'
@@ -1,22 +0,0 @@
1
- name: test
2
-
3
- on: [push, pull_request]
4
-
5
- jobs:
6
- build:
7
- name: build (${{ matrix.ruby }} / ${{ matrix.os }})
8
- strategy:
9
- fail-fast: false
10
- matrix:
11
- ruby: [ '3.0', 2.7, 2.6, 2.5, 2.4, head, jruby, truffleruby-head ]
12
- os: [ ubuntu-latest, macos-latest ]
13
- runs-on: ${{ matrix.os }}
14
- steps:
15
- - uses: actions/checkout@v3
16
- - name: Set up Ruby
17
- uses: ruby/setup-ruby@v1
18
- with:
19
- ruby-version: ${{ matrix.ruby }}
20
- bundler-cache: true # 'bundle install' and cache gems
21
- - name: Run test
22
- run: bundle exec rake test
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
- Gemfile.lock
data/Rakefile DELETED
@@ -1,17 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
3
-
4
- Rake::TestTask.new(:test) do |t|
5
- t.libs << "test/lib"
6
- t.ruby_opts << "-rhelper"
7
- t.test_files = FileList["test/**/test_*.rb"]
8
- end
9
-
10
- task :sync_tool do
11
- require 'fileutils'
12
- FileUtils.cp "../ruby/tool/lib/core_assertions.rb", "./test/lib"
13
- FileUtils.cp "../ruby/tool/lib/envutil.rb", "./test/lib"
14
- FileUtils.cp "../ruby/tool/lib/find_executable.rb", "./test/lib"
15
- end
16
-
17
- task :default => :test
data/bin/console DELETED
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "timeout"
5
-
6
- require "irb"
7
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install