threadz 0.1.3 → 1.0.0.beta

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.
data/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ 1.0.0.beta
2
+ ==========
3
+ Removing rcov and jeweler dependencies, fixing rspec at 1.x, adding some
4
+ documentation, bumping to 1.x major version.
5
+
1
6
  0.1.0
2
7
  =====
3
8
  Initial release
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in threadz.gemspec
4
+ gemspec
5
+ gem "rake"
@@ -0,0 +1,18 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ threadz (1.0.0.beta)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ rake (0.9.2.2)
10
+ rspec (1.3.2)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ rake
17
+ rspec (~> 1.0)
18
+ threadz!
data/Rakefile CHANGED
@@ -1,12 +1,10 @@
1
- # Adapted from the rake Rakefile.
2
-
3
1
  require 'rubygems'
4
2
  require 'rake/testtask'
5
- require 'rake/rdoctask'
6
- require 'rake/gempackagetask'
3
+ require 'rdoc/task'
4
+ require 'rubygems/package_task'
7
5
  require 'rubygems/source_info_cache'
8
6
  require 'spec/rake/spectask'
9
-
7
+ require "bundler/gem_tasks"
10
8
 
11
9
  spec = Gem::Specification.load(File.join(File.dirname(__FILE__), 'threadz.gemspec'))
12
10
 
@@ -14,22 +12,6 @@ desc "Default Task"
14
12
  task 'default' => ['spec', 'rdoc']
15
13
 
16
14
 
17
- desc "If you're building from sources, run this task first to setup the necessary dependencies"
18
- task 'setup' do
19
- windows = Config::CONFIG['host_os'] =~ /windows|cygwin|bccwin|cygwin|djgpp|mingw|mswin|wince/i
20
- rb_bin = File.expand_path(Config::CONFIG['ruby_install_name'], Config::CONFIG['bindir'])
21
- spec.dependencies.select { |dep| Gem::SourceIndex.from_installed_gems.search(dep).empty? }.each do |missing|
22
- dep = Gem::Dependency.new(missing.name, missing.version_requirements)
23
- spec = Gem::SourceInfoCache.search(dep, true, true).last
24
- fail "#{dep} not found in local or remote repository!" unless spec
25
- puts "Installing #{spec.full_name} ..."
26
- args = [rb_bin, '-S', 'gem', 'install', spec.name, '-v', spec.version.to_s]
27
- args.unshift('sudo') unless windows || ENV['GEM_HOME']
28
- sh args.map{ |a| a.inspect }.join(' ')
29
- end
30
- end
31
-
32
-
33
15
  desc "Run all test cases"
34
16
  task 'spec' do |task|
35
17
  exec 'spec -c -f n spec/*.rb spec/basic/*.rb'
@@ -57,80 +39,9 @@ task 'spec-stress', [:times] do |task, args|
57
39
  puts "Done!"
58
40
  end
59
41
 
60
- # Create the documentation.
61
42
  Rake::RDocTask.new do |rdoc|
62
43
  rdoc.main = 'README.rdoc'
63
44
  rdoc.rdoc_files.include('README.rdoc', 'lib/**/*.rb')
64
45
  rdoc.title = "Threadz Thread Pool"
65
46
  rdoc.rdoc_dir = 'doc'
66
47
  end
67
-
68
-
69
- gem = Rake::GemPackageTask.new(spec) do |pkg|
70
- pkg.need_tar = true
71
- pkg.need_zip = true
72
- end
73
-
74
- desc "Install the package locally"
75
- task 'install'=>['setup', 'package'] do |task|
76
- rb_bin = File.expand_path(Config::CONFIG['ruby_install_name'], Config::CONFIG['bindir'])
77
- args = [rb_bin, '-S', 'gem', 'install', "pkg/#{spec.name}-#{spec.version}.gem"]
78
- windows = Config::CONFIG['host_os'] =~ /windows|cygwin|bccwin|cygwin|djgpp|mingw|mswin|wince/i
79
- args.unshift('sudo') unless windows || ENV['GEM_HOME']
80
- sh args.map{ |a| a.inspect }.join(' ')
81
- end
82
-
83
- desc "Uninstall previously installed packaged"
84
- task 'uninstall' do |task|
85
- rb_bin = File.expand_path(Config::CONFIG['ruby_install_name'], Config::CONFIG['bindir'])
86
- args = [rb_bin, '-S', 'gem', 'install', spec.name, '-v', spec.version.to_s]
87
- windows = Config::CONFIG['host_os'] =~ /windows|cygwin|bccwin|cygwin|djgpp|mingw|mswin|wince/i
88
- args.unshift('sudo') unless windows || ENV['GEM_HOME']
89
- sh args.map{ |a| a.inspect }.join(' ')
90
- end
91
-
92
-
93
- task 'release'=>['setup', 'test', 'package'] do
94
-
95
- require 'rubyforge'
96
- changes = File.read('CHANGELOG')[/\d+.\d+.\d+.*\n((:?^[^\n]+\n)*)/]
97
- File.open '.changes', 'w' do |file|
98
- file.write changes
99
- end
100
-
101
- puts "Uploading #{spec.name} #{spec.version}"
102
- files = Dir['pkg/*.{gem,tgz,zip}']
103
- rubyforge = RubyForge.new
104
- rubyforge.configure
105
- rubyforge.login
106
- rubyforge.userconfig.merge! 'release_changes'=>'.changes', 'preformatted'=>true
107
- rubyforge.add_release spec.rubyforge_project.downcase, spec.name.downcase, spec.version.to_s, *files
108
- rm_f '.changes'
109
- puts "Release #{spec.version} uploaded"
110
- end
111
-
112
- task 'clobber' do
113
- rm_f '.changes'
114
- end
115
-
116
- desc "Run all examples with RCov"
117
- Spec::Rake::SpecTask.new('spec:rcov') do |t|
118
- t.spec_files = FileList['spec/**/*.rb']
119
- t.rcov = true
120
- t.rcov_opts = ['--exclude', 'spec']
121
- end
122
-
123
- begin
124
- require 'jeweler'
125
- Jeweler::Tasks.new do |gemspec|
126
- gemspec.name = "threadz"
127
- gemspec.summary = "An easy Ruby threadpool library."
128
- gemspec.description = "A Ruby threadpool library to handle threadpools and make batch jobs easier."
129
- gemspec.email = "nanodeath@gmail.com"
130
- gemspec.homepage = "http://github.com/nanodeath/threadz"
131
- gemspec.authors = ["Max Aller"]
132
- end
133
- Jeweler::GemcutterTasks.new
134
- rescue LoadError
135
- puts "Jeweler not available. Install it with: sudo gem install jeweler"
136
- end
@@ -19,5 +19,17 @@
19
19
 
20
20
  require 'thread'
21
21
 
22
+ require "threadz/version"
23
+
24
+ module Threadz
25
+ DEBUG = ENV['THREADZ_DEBUG'] == "1"
26
+
27
+ def Threadz.dputs(string)
28
+ puts(string) if DEBUG
29
+ end
30
+ end
31
+
32
+ Threadz::dputs("Loading threadz")
33
+
22
34
  ['atomic_integer', 'sleeper', 'directive', 'batch', 'thread_pool'].each { |lib| require File.join(File.dirname(__FILE__), 'threadz', lib) }
23
35
 
@@ -5,11 +5,11 @@ module Threadz
5
5
  # The ThreadPool class contains all the threads available to whatever context
6
6
  # has access to it.
7
7
  class ThreadPool
8
- # Default setting for kill threshold
8
+ # Default setting for kill threshold: 10
9
9
  KILL_THRESHOLD = 10
10
- # Setting for how much to decrement current kill score by for each queued job
10
+ # Setting for how much to decrement current kill score by for each queued job: 1
11
11
  THREADS_BUSY_SCORE = 1
12
- # Setting for how much to increment current kill score by for *each* idle thread
12
+ # Setting for how much to increment current kill score by for *each* idle thread: 1
13
13
  THREADS_IDLE_SCORE = 1
14
14
 
15
15
  # Creates a new thread pool into which you can queue jobs.
@@ -24,6 +24,12 @@ module Threadz
24
24
  # pool is checked. If there is more than one idle thread (and we're above minimum size), the
25
25
  # kill score is incremented by THREADS_IDLE_SCORE for each idle thread. If there are no idle threads
26
26
  # (and we're below maximum size) the kill score is decremented by THREADS_KILL_SCORE for each queued job.
27
+ # If the thread pool is being perfectly utilized (no queued work or idle workers), the kill score will decay
28
+ # and lose 10% of its value.
29
+ # In the default case of kill_threshold=10, if the thread pool is overworked for 10 consecutive checks (that is,
30
+ # 1 second), a new thread will be created and the counter reset. Similarly, if the thread pool is underutilized
31
+ # for 10 consecutive checks, an idle thread will be culled. If you want the thread pool to scale more quickly with
32
+ # demand, try lowering the kill_threshold value.
27
33
  def initialize(opts={})
28
34
  @min_size = opts[:initial_size] || 10 # documented
29
35
  @max_size = opts[:maximum_size] || @min_size * 5 # documented
@@ -45,8 +51,9 @@ module Threadz
45
51
  # Push a process onto the job queue for the thread pool to pick up.
46
52
  # Note that using this method, you can't keep track of when the job
47
53
  # finishes. If you care about when it finishes, use batches.
48
- def process(&block)
49
- @queue << block
54
+ def process(callback = nil, &block)
55
+ callback ||= block
56
+ @queue << callback
50
57
  nil
51
58
  end
52
59
 
@@ -110,10 +117,10 @@ module Threadz
110
117
  @killscore > 0 ? kill_thread : spawn_thread
111
118
  @killscore = 0
112
119
  end
113
- puts "killscore: #{@killscore}. waiting: #{@queue.num_waiting}. threads length: #{@worker_threads_count.value}. min/max: [#{@min_size}, #{@max_size}]" if $DEBUG
120
+ Threadz.dputs "killscore: #{@killscore}. waiting: #{@queue.num_waiting}. threads length: #{@worker_threads_count.value}. min/max: [#{@min_size}, #{@max_size}]"
114
121
  sleep 0.1
115
122
  end
116
123
  end
117
124
  end
118
125
  end
119
- end
126
+ end
@@ -0,0 +1,4 @@
1
+ module Threadz
2
+ VERSION = "1.0.0.beta"
3
+ end
4
+
@@ -7,16 +7,16 @@ describe Threadz do
7
7
  # This test should always fail, but there is a small chance it won't...
8
8
 
9
9
  i = 0
10
- n = 10_000
11
- threads = 10
10
+ n = 100_000
11
+ threads = 100
12
12
  t = []
13
13
  threads.times do
14
14
  t << Thread.new do
15
- sleep 0.05
15
+ sleep 0.1
16
16
  n.times { i += 1 }
17
17
  end
18
18
  t << Thread.new do
19
- sleep 0.05
19
+ sleep 0.1
20
20
  n.times { i -= 1 }
21
21
  end
22
22
  end
@@ -7,7 +7,7 @@ describe Threadz do
7
7
  @T = Threadz::ThreadPool.new
8
8
  end
9
9
 
10
- it "should support process" do
10
+ it "should support process and accept a block" do
11
11
  i = 0
12
12
  3.times do
13
13
  @T.process { i += 1}
@@ -17,12 +17,37 @@ describe Threadz do
17
17
  i.should == 3
18
18
  end
19
19
 
20
+ it "should support process and accept an arg that responds to :call" do
21
+ i = 0
22
+ 3.times do
23
+ @T.process(Proc.new { i += 1} )
24
+ end
25
+ sleep 0.1
26
+
27
+ i.should == 3
28
+ end
29
+
20
30
  it "should support creating batches" do
21
31
  i = 0
22
32
 
23
33
  lambda { @T.new_batch }.should_not raise_error
24
34
  lambda { @T.new_batch(:latent => true) }.should_not raise_error
25
35
  end
36
+
37
+ it "should not crash when killing threads" do
38
+ i = 0
39
+ b = @T.new_batch(:latent => true)
40
+ 5000.times do
41
+ b << lambda { i += 1 }
42
+ b << lambda { i -= 1 }
43
+ b << [lambda { i += 2}, lambda { i -= 1}]
44
+ end
45
+
46
+ b.start
47
+ b.wait_until_done
48
+
49
+ 50.times { sleep 0.1 }
50
+ end
26
51
 
27
52
  describe Threadz::Batch do
28
53
  it "should support jobs" do
@@ -195,4 +220,4 @@ describe Threadz do
195
220
  end
196
221
  end
197
222
  end
198
- end
223
+ end
@@ -1,61 +1,22 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
1
  # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "threadz/version"
5
4
 
6
5
  Gem::Specification.new do |s|
7
- s.name = %q{threadz}
8
- s.version = "0.1.3"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Max Aller"]
12
- s.date = %q{2010-02-01}
6
+ s.name = "threadz"
7
+ s.version = Threadz::VERSION
8
+ s.authors = ["Max Aller"]
9
+ s.email = ["nanodeath@gmail.com"]
10
+ s.homepage = "http://github.com/nanodeath/threadz"
11
+ s.summary = %q{An easy Ruby threadpool library.}
13
12
  s.description = %q{A Ruby threadpool library to handle threadpools and make batch jobs easier.}
14
- s.email = %q{nanodeath@gmail.com}
15
- s.extra_rdoc_files = [
16
- "README.rdoc"
17
- ]
18
- s.files = [
19
- ".gitignore",
20
- "CHANGELOG",
21
- "MIT-LICENSE",
22
- "README.rdoc",
23
- "Rakefile",
24
- "VERSION",
25
- "lib/threadz.rb",
26
- "lib/threadz/atomic_integer.rb",
27
- "lib/threadz/batch.rb",
28
- "lib/threadz/directive.rb",
29
- "lib/threadz/sleeper.rb",
30
- "lib/threadz/thread_pool.rb",
31
- "spec/atomic_integer_spec.rb",
32
- "spec/basic/thread_pool_spec.rb",
33
- "spec/performance/batch_spec.rb",
34
- "spec/spec_helper.rb",
35
- "spec/threadz_spec.rb",
36
- "threadz.gemspec"
37
- ]
38
- s.homepage = %q{http://github.com/nanodeath/threadz}
39
- s.rdoc_options = ["--charset=UTF-8"]
40
- s.require_paths = ["lib"]
41
- s.rubygems_version = %q{1.3.5}
42
- s.summary = %q{An easy Ruby threadpool library.}
43
- s.test_files = [
44
- "spec/atomic_integer_spec.rb",
45
- "spec/threadz_spec.rb",
46
- "spec/performance/batch_spec.rb",
47
- "spec/spec_helper.rb",
48
- "spec/basic/thread_pool_spec.rb"
49
- ]
50
13
 
51
- if s.respond_to? :specification_version then
52
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
53
- s.specification_version = 3
14
+ s.rubyforge_project = "threadz"
54
15
 
55
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
56
- else
57
- end
58
- else
59
- end
60
- end
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
61
20
 
21
+ s.add_development_dependency "rspec", "~> 1.0"
22
+ end
metadata CHANGED
@@ -1,76 +1,76 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: threadz
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.3
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0.beta
5
+ prerelease: 6
5
6
  platform: ruby
6
- authors:
7
+ authors:
7
8
  - Max Aller
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
-
12
- date: 2010-02-01 00:00:00 -08:00
13
- default_executable:
14
- dependencies: []
15
-
12
+ date: 2011-12-22 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &74613530 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *74613530
16
25
  description: A Ruby threadpool library to handle threadpools and make batch jobs easier.
17
- email: nanodeath@gmail.com
26
+ email:
27
+ - nanodeath@gmail.com
18
28
  executables: []
19
-
20
29
  extensions: []
21
-
22
- extra_rdoc_files:
23
- - README.rdoc
24
- files:
30
+ extra_rdoc_files: []
31
+ files:
25
32
  - .gitignore
26
33
  - CHANGELOG
34
+ - Gemfile
35
+ - Gemfile.lock
27
36
  - MIT-LICENSE
28
37
  - README.rdoc
29
38
  - Rakefile
30
- - VERSION
31
39
  - lib/threadz.rb
32
40
  - lib/threadz/atomic_integer.rb
33
41
  - lib/threadz/batch.rb
34
42
  - lib/threadz/directive.rb
35
43
  - lib/threadz/sleeper.rb
36
44
  - lib/threadz/thread_pool.rb
45
+ - lib/threadz/version.rb
37
46
  - spec/atomic_integer_spec.rb
38
47
  - spec/basic/thread_pool_spec.rb
39
48
  - spec/performance/batch_spec.rb
40
49
  - spec/spec_helper.rb
41
50
  - spec/threadz_spec.rb
42
51
  - threadz.gemspec
43
- has_rdoc: true
44
52
  homepage: http://github.com/nanodeath/threadz
45
53
  licenses: []
46
-
47
54
  post_install_message:
48
- rdoc_options:
49
- - --charset=UTF-8
50
- require_paths:
55
+ rdoc_options: []
56
+ require_paths:
51
57
  - lib
52
- required_ruby_version: !ruby/object:Gem::Requirement
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- version: "0"
57
- version:
58
- required_rubygems_version: !ruby/object:Gem::Requirement
59
- requirements:
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- version: "0"
63
- version:
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>'
68
+ - !ruby/object:Gem::Version
69
+ version: 1.3.1
64
70
  requirements: []
65
-
66
- rubyforge_project:
67
- rubygems_version: 1.3.5
71
+ rubyforge_project: threadz
72
+ rubygems_version: 1.8.13
68
73
  signing_key:
69
74
  specification_version: 3
70
75
  summary: An easy Ruby threadpool library.
71
- test_files:
72
- - spec/atomic_integer_spec.rb
73
- - spec/threadz_spec.rb
74
- - spec/performance/batch_spec.rb
75
- - spec/spec_helper.rb
76
- - spec/basic/thread_pool_spec.rb
76
+ test_files: []
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.1.3