threadz 0.1.3 → 1.0.0.beta

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