delayed-threaded 0.16.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 32e63adc06acd90d954baed1e872c113239941d9
4
+ data.tar.gz: bb4d43d6376e85f84efe0945c14149143ca59140
5
+ SHA512:
6
+ metadata.gz: 46418908010e3463ca50d1c6a17d069670869b40cb220f2c3729b6924b89b99006ddf07a1e0259f7b2429b5d01e690be9bf8bd9692494c6c39cb3848f9a92403
7
+ data.tar.gz: f50279911f6e6024570079a3f6715a72136d9853e53949ebad1f62591422656881b0eee64fd1db29ab505d2bdfb0d68d46c55f77e9393b3ddeac4bfc9a769db2
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /tmp/
8
+ /test/db/*.db
9
+ Gemfile.lock
data/.travis.yml ADDED
@@ -0,0 +1,21 @@
1
+ sudo: false
2
+ language: ruby
3
+ jdk:
4
+ - oraclejdk8
5
+ rvm:
6
+ - jruby-1.7.26
7
+ - jruby-9.1.16.0
8
+ before_install: gem install bundler -v 1.16.1
9
+ env:
10
+ - delayed_job="~>4.1.5" activerecord="~>4.2"
11
+ - delayed_job="~>4.0.6" activerecord="~>4.2"
12
+ - delayed_job="~>3.0" # activerecord="~>3.2"
13
+ - delayed_job="~>4.1" activerecord="~>4.2.6"
14
+ matrix:
15
+ allow_failures:
16
+ #- rvm: jruby-head
17
+ include:
18
+ - rvm: jruby-9.1.17.0
19
+ env: delayed_job="~>4.1.5" activerecord="~>5.0.5"
20
+ - rvm: jruby-9.1.17.0
21
+ env: delayed_job="~>4.1.5" activerecord="~>5.1.6"
data/Gemfile ADDED
@@ -0,0 +1,36 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ if ENV['delayed_job']
6
+ if ENV['delayed_job'] == 'master'
7
+ gem 'delayed_job', :git => 'git://github.com/collectiveidea/delayed_job.git'
8
+ gem 'delayed_job_active_record', :require => nil
9
+ else
10
+ gem 'delayed_job', version = ENV['delayed_job']
11
+ unless version =~ /~?\s?2\.\d/ # delayed_job_active_record only for DJ >= 3.0
12
+ gem 'delayed_job_active_record', :require => nil
13
+ end
14
+ if version =~ /~?\s?4\.[1]/ # add_dependency "delayed_job", ">= 4.1"
15
+ gem 'delayed_cron_job', :require => nil
16
+ end
17
+ end
18
+ else
19
+ gem 'delayed_job'
20
+ gem 'delayed_job_active_record', :require => nil
21
+ gem 'delayed_cron_job', :require => nil
22
+ end
23
+
24
+ if ENV['activerecord']
25
+ gem 'activerecord', version = ENV['activerecord'], :require => nil
26
+ if version =~ /~?\s?4\.[12]/
27
+ gem 'activerecord-jdbc-adapter', '~> 1.3.20', :require => nil, :platform => :jruby
28
+ else
29
+ gem 'activerecord-jdbc-adapter', :require => nil, :platform => :jruby
30
+ end
31
+ else
32
+ gem 'activerecord', :require => nil # for tests
33
+ gem 'activerecord-jdbc-adapter', :require => nil, :platform => :jruby
34
+ end
35
+
36
+ gem 'jdbc-sqlite3', '~> 3.20.1', :platform => :jruby
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2018 Karol Bucek
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOa AND
17
+ NONINFRINGEMENT. IN NO EVENT SaALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # Delayed::Threaded
2
+
3
+ Allows to start [DJ][0] in the same process using `Thread.new { ... }`
4
+
5
+ Extracted from [JRuby-Rack-Worker][1]: an effort to run Ruby workers in threads
6
+ with Java (JRuby-Rack) deployments (previously known as `Delayed::JRubyWorker`).
7
+
8
+ **NOTE: JRuby only, for now (PRs welcome)!**
9
+
10
+ ## Installation
11
+
12
+ ```ruby
13
+ gem 'delayed-threaded'
14
+ ```
15
+
16
+ and `bundle` or install it yourself as `gem install delayed-threaded`.
17
+
18
+ ## Usage
19
+
20
+ ```ruby
21
+ def start_worker
22
+ options = { :quiet => true }
23
+ options[:queues] = (ENV['QUEUES'] || ENV['QUEUE'] || '').split(',')
24
+ options[:min_priority] = ENV['MIN_PRIORITY']
25
+ options[:max_priority] = ENV['MAX_PRIORITY']
26
+ # beyond `rake delayed:work` compatibility :
27
+ if read_ahead = ENV['READ_AHEAD'] # DEFAULT_READ_AHEAD = 5
28
+ options[:read_ahead] = read_ahead.to_i
29
+ end
30
+ if sleep_delay = ENV['SLEEP_DELAY'] # DEFAULT_SLEEP_DELAY = 5
31
+ options[:sleep_delay] = sleep_delay.to_f
32
+ end
33
+
34
+ worker = Delayed::Threaded::Worker.new(options)
35
+ worker.start
36
+ rescue Exception => e
37
+ msg = "FATAL #{e.inspect}"
38
+ if backtrace = e.backtrace
39
+ msg << ":\n #{backtrace.join("\n ")}"
40
+ end
41
+ STDERR.puts(msg)
42
+ end
43
+
44
+ Thread.new { start_worker }
45
+ ```
46
+
47
+ ## Development
48
+
49
+ After checking out the repo, run `bin/setup` to install dependencies.
50
+ Then, run `rake test` to run the tests. You can also run `bin/console` for an
51
+ interactive prompt that will allow you to experiment.
52
+
53
+ To install this gem onto your local machine, run `bundle exec rake install`.
54
+
55
+ ## Copyright
56
+
57
+ Copyright (c) 2018 [Karol Bucek](http://kares.org).
58
+ See LICENSE (http://en.wikipedia.org/wiki/MIT_License) for details.
59
+
60
+ [0]: https://github.com/collectiveidea/delayed_job
61
+ [1]: https://github.com/kares/jruby-rack-worker
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "delayed/threaded"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "delayed-threaded"
5
+ spec.authors = ["Karol Bucek"]
6
+ spec.email = ["self@kares.org"]
7
+ spec.licenses = ['MIT']
8
+
9
+ path = File.expand_path('lib/delayed/threaded/version.rb', File.dirname(__FILE__))
10
+ spec.version = File.read(path).match( /.*VERSION\s*=\s*['"](.*)['"]/m )[1]
11
+
12
+ spec.summary = %q{Making Delayed::Job a polite (thread-safe) in process citizen.}
13
+ spec.description = "Allows to start DJ in the same process using Thread.new { ... } "
14
+ spec.homepage = "https://github.com/kares/delayed-threaded"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|temp)/})
18
+ end
19
+ spec.bindir = 'exe'
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.add_dependency "delayed_job", ">= 3.0", "< 4.2"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.16"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ spec.add_development_dependency "test-unit", "~> 2.5.3"
28
+ spec.add_development_dependency "test-unit-context"
29
+ spec.add_development_dependency "mocha"
30
+ end
@@ -0,0 +1,4 @@
1
+ module Delayed
2
+ # @deprecated
3
+ JRubyWorker = Threaded::Worker
4
+ end
@@ -0,0 +1,33 @@
1
+ module Delayed
2
+ module Threaded
3
+ module SleepCalculator
4
+
5
+ def sleep(time)
6
+ Kernel.sleep calc_sleep_time(time)
7
+ end
8
+
9
+ private
10
+
11
+ @@last = java.util.concurrent.atomic.AtomicLong.new
12
+
13
+ def calc_sleep_time(time)
14
+ count = thread_count rescue nil
15
+ return time if ! count || count <= 1 || time <= 0
16
+
17
+ last = @@last.get_and_set now = java.lang.System.current_time_millis
18
+ return time if ( now - last ) > time * 1000
19
+
20
+ # time / count.to_f - optimal pause time between threads
21
+ diff = ( time / count.to_f ) - ( now - last ) * 0.001
22
+ # converge to ~ pauses between worker threads (might add up to 10% to sleep time)
23
+ diff > 0 ? ( time + diff / 5.0 ) : time
24
+ # (now - last) * 0.001 < opt_pause ? ( time + time / 11.1 ) : time
25
+ end
26
+
27
+ def thread_count
28
+ $worker_manager ? $worker_manager.thread_count : false
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ require 'thread'
2
+
3
+ module Delayed
4
+ module Threaded
5
+ module SyncLifecycle
6
+
7
+ def self.extended(base)
8
+ klass = base.singleton_class
9
+ klass.send :alias_method, :setup_lifecycle_impl, :setup_lifecycle
10
+ klass.send :alias_method, :setup_lifecycle, :setup_lifecycle_sync
11
+ klass.send :private, :setup_lifecycle_impl
12
+ end
13
+
14
+ def setup_lifecycle_sync
15
+ # not really necessary, but a plugin might expect setup to run exactly once
16
+ (@lifecycle ||= nil) || synchronize do
17
+ unless @lifecycle
18
+ setup_lifecycle_impl
19
+ #@lifecycle = Delayed::Lifecycle.new
20
+ #lifecycle = @lifecycle
21
+ end
22
+ @lifecycle # make sure returns lifecycle (for DJ < 4.1 compat layer)
23
+ end
24
+ end
25
+
26
+ MUTEX = Mutex.new
27
+ private_constant :MUTEX if respond_to?(:private_constant)
28
+
29
+ def synchronize(&block); MUTEX.synchronize(&block) end
30
+ private :synchronize
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,5 @@
1
+ module Delayed
2
+ module Threaded
3
+ VERSION = '0.16.0'
4
+ end
5
+ end
@@ -0,0 +1,172 @@
1
+ require 'java'
2
+ require 'delayed_job' unless defined?(Delayed::Worker)
3
+ require 'socket' # due Socket.gethostname in Delayed::Worker#name
4
+
5
+ require 'delayed/threaded/sleep_calculator'
6
+ require 'delayed/threaded/sync_lifecycle'
7
+
8
+ module Delayed::Threaded
9
+ # Threaded DJ worker implementation.
10
+ # - inspired by Delayed::Command
11
+ # - no daemons dependency + thread-safe
12
+ class Worker < Delayed::Worker
13
+
14
+ include SleepCalculator
15
+
16
+ # @override to return the same as Delayed::Worker.lifecycle (uses class instance state)
17
+ def self.lifecycle; Delayed::Worker.lifecycle end
18
+
19
+ # @override since `initialize` (DJ 4.1) does: `self.class.setup_lifecycle`
20
+ def self.setup_lifecycle; Delayed::Worker.setup_lifecycle end
21
+
22
+ unless defined? Delayed::Worker.setup_lifecycle
23
+ # adapt DJ 3.0/4.0 :
24
+ # def self.lifecycle
25
+ # @lifecycle ||= Delayed::Lifecycle.new
26
+ # end
27
+ def superclass.lifecycle
28
+ @lifecycle ||= setup_lifecycle
29
+ end
30
+ def superclass.setup_lifecycle
31
+ @lifecycle = Delayed::Lifecycle.new
32
+ end
33
+ end
34
+
35
+ # @patch make sure concurrent worker threads do not cause multiple initializations
36
+ Delayed::Worker.extend SyncLifecycle if Delayed.const_defined? :Lifecycle
37
+
38
+ THREAD_LOCAL_ACCESSORS = [
39
+ :min_priority, :max_priority, :sleep_delay, :read_ahead, :queues, :exit_on_complete
40
+ ]
41
+ private_constant :THREAD_LOCAL_ACCESSORS if respond_to?(:private_constant)
42
+ # due Delayed::Worker#initialize(options = {}) :
43
+ #
44
+ # [:min_priority, :max_priority, :sleep_delay, :read_ahead, :queues, :exit_on_complete].each do |option|
45
+ # self.class.send("#{option}=", options[option]) if options.key?(option)
46
+ # end
47
+
48
+ class Config
49
+ attr_accessor *THREAD_LOCAL_ACCESSORS
50
+ def key?(name); ! instance_variable_get(:"@#{name}").nil? end
51
+ end
52
+
53
+ THREAD_LOCAL_ACCESSORS.each do |name|
54
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
55
+ def self.#{name}=(val)
56
+ (Thread.current[:delayed_threaded_worker_config] ||= Config.new).#{name} = val
57
+ end
58
+ def self.#{name}
59
+ if (config = Thread.current[:delayed_threaded_worker_config]) && config.key?(:#{name})
60
+ config.#{name}
61
+ else
62
+ superclass.#{name}
63
+ end
64
+ end
65
+ EOS
66
+ end
67
+ # e.g. :
68
+ #
69
+ # def self.min_priority=(value)
70
+ # (Thread.current[:delayed_jruby_worker_config] ||= Config.new).min_priority = value
71
+ # end
72
+ #
73
+ # def self.min_priority
74
+ # if (config = Thread.current[:delayed_jruby_worker_config]) && config.key?(:min_priority)
75
+ # config.min_priority
76
+ # else
77
+ # Worker.min_priority
78
+ # end
79
+ # end
80
+
81
+ def name
82
+ if (@name ||= nil).nil?
83
+ # super - [prefix]host:hostname pid:process_pid
84
+ begin
85
+ @name = "#{super} thread:#{thread_id}".freeze
86
+ rescue
87
+ @name = "#{@name_prefix}thread:#{thread_id}".freeze
88
+ end
89
+ end
90
+ @name
91
+ end
92
+
93
+ def to_s; name; end
94
+
95
+ def thread_id
96
+ # NOTE: JRuby might set a bit long name for Thread.new { ... } code e.g.
97
+ # RubyThread-1: /home/[...]/src/test/ruby/delayed/jruby_worker_test.rb:163
98
+ if name = java.lang.Thread.currentThread.getName
99
+ if name.size > 100 && match = name.match(/(.*?)\:\s.*?[\/\\]+/)
100
+ match[1]
101
+ else
102
+ name
103
+ end
104
+ end
105
+ end
106
+
107
+ def exit!
108
+ return if @exit # #stop?
109
+ say "Stoping job worker"
110
+ @exit = true # #stop
111
+ if Delayed.const_defined?(:Job) && Delayed::Job.respond_to?(:clear_locks!)
112
+ Delayed::Job.clear_locks!(name)
113
+ end
114
+ end
115
+
116
+ unless defined? Delayed::Lifecycle # DJ 2.x (< 3.0)
117
+ require 'benchmark'
118
+ # in case DJ 2.1 loads AS 3.x we're need `[1,2].sum` :
119
+ require 'active_support/core_ext/enumerable' rescue nil
120
+
121
+ def start
122
+ say "Starting job worker"
123
+ trap
124
+
125
+ loop do
126
+ result = nil
127
+
128
+ realtime = Benchmark.realtime do
129
+ result = work_off
130
+ end
131
+
132
+ count = result.sum
133
+
134
+ break if @exit
135
+
136
+ if count.zero?
137
+ sleep(self.class.sleep_delay)
138
+ else
139
+ say "#{count} jobs processed at %.4f j/s, %d failed ..." % [count / realtime, result.last]
140
+ end
141
+
142
+ break if @exit
143
+ end
144
+ end
145
+
146
+ def stop?; !!@exit; end
147
+ def stop; @exit = true; end
148
+
149
+ end
150
+
151
+ protected
152
+
153
+ def trap(name = nil)
154
+ # catch invocations from #start traps TERM and INT
155
+ at_exit { exit! } if ! name || name.to_s == 'TERM'
156
+ end
157
+
158
+ end
159
+
160
+ end
161
+
162
+ Dir.chdir( Rails.root ) if defined?(Rails.root) && Dir.getwd.to_s != Rails.root.to_s
163
+
164
+ if ! Delayed::Worker.backend && ! Delayed.const_defined?(:Lifecycle)
165
+ Delayed::Worker.guess_backend # deprecated on DJ since 3.0
166
+ end
167
+
168
+ # NOTE: no explicit logger configuration - DJ logger defaults to Rails.logger
169
+ # if this is not desired - e.g. one wants script/delayed_job's logger behavior
170
+ # it's more correct to configure in an initializer rather then forcing the use
171
+ # of delayed_job.log (like Delayed::Command does) ...
172
+ # Delayed::Worker.logger = Logger.new(File.join(Rails.root, 'log', 'delayed_job.log'))
@@ -0,0 +1,5 @@
1
+ require 'delayed/threaded/version'
2
+
3
+ require 'delayed/threaded/worker'
4
+
5
+ require 'delayed/threaded/compat'
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: delayed-threaded
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.16.0
5
+ platform: ruby
6
+ authors:
7
+ - Karol Bucek
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-05-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '3.0'
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: '4.2'
22
+ name: delayed_job
23
+ prerelease: false
24
+ type: :runtime
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '4.2'
33
+ - !ruby/object:Gem::Dependency
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - "~>"
37
+ - !ruby/object:Gem::Version
38
+ version: '1.16'
39
+ name: bundler
40
+ prerelease: false
41
+ type: :development
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.16'
47
+ - !ruby/object:Gem::Dependency
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: '10.0'
53
+ name: rake
54
+ prerelease: false
55
+ type: :development
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '10.0'
61
+ - !ruby/object:Gem::Dependency
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: 2.5.3
67
+ name: test-unit
68
+ prerelease: false
69
+ type: :development
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 2.5.3
75
+ - !ruby/object:Gem::Dependency
76
+ requirement: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ name: test-unit-context
82
+ prerelease: false
83
+ type: :development
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ requirement: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ name: mocha
96
+ prerelease: false
97
+ type: :development
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ description: 'Allows to start DJ in the same process using Thread.new { ... } '
104
+ email:
105
+ - self@kares.org
106
+ executables: []
107
+ extensions: []
108
+ extra_rdoc_files: []
109
+ files:
110
+ - ".gitignore"
111
+ - ".travis.yml"
112
+ - Gemfile
113
+ - LICENSE
114
+ - README.md
115
+ - Rakefile
116
+ - bin/console
117
+ - bin/setup
118
+ - delayed-threaded.gemspec
119
+ - lib/delayed/threaded.rb
120
+ - lib/delayed/threaded/compat.rb
121
+ - lib/delayed/threaded/sleep_calculator.rb
122
+ - lib/delayed/threaded/sync_lifecycle.rb
123
+ - lib/delayed/threaded/version.rb
124
+ - lib/delayed/threaded/worker.rb
125
+ homepage: https://github.com/kares/delayed-threaded
126
+ licenses:
127
+ - MIT
128
+ metadata: {}
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubyforge_project:
145
+ rubygems_version: 2.6.14.1
146
+ signing_key:
147
+ specification_version: 4
148
+ summary: Making Delayed::Job a polite (thread-safe) in process citizen.
149
+ test_files: []