floormanager 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "shoulda", ">= 0"
10
+ gem "bundler", "~> 1.0.0"
11
+ gem "jeweler", "~> 1.6.2"
12
+ gem "rcov", ">= 0"
13
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,20 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ jeweler (1.6.2)
6
+ bundler (~> 1.0)
7
+ git (>= 1.2.5)
8
+ rake
9
+ rake (0.9.2)
10
+ rcov (0.9.9)
11
+ shoulda (2.11.3)
12
+
13
+ PLATFORMS
14
+ ruby
15
+
16
+ DEPENDENCIES
17
+ bundler (~> 1.0.0)
18
+ jeweler (~> 1.6.2)
19
+ rcov
20
+ shoulda
data/Rakefile CHANGED
@@ -1,45 +1,52 @@
1
- require 'rubygems'
2
- require 'rake'
1
+ # encoding: utf-8
3
2
 
3
+ require 'rubygems'
4
+ require 'bundler'
4
5
  begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "floormanager"
8
- gem.summary = %Q{Handle threaded workers like a champ}
9
- gem.description = %Q{Simple ruby library for handling threaded workers operating on a queue}
10
- gem.email = "inge@elektronaut.no"
11
- gem.homepage = "http://github.com/elektronaut/floormanager"
12
- gem.authors = ["Inge Jørgensen"]
13
- gem.add_development_dependency "rspec", ">= 1.3.0"
14
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
- end
16
- Jeweler::GemcutterTasks.new
17
- rescue LoadError
18
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
19
11
  end
12
+ require 'rake'
20
13
 
21
- require 'spec/rake/spectask'
22
- Spec::Rake::SpecTask.new(:spec) do |spec|
23
- spec.libs << 'lib' << 'spec'
24
- spec.spec_files = FileList['spec/**/*_spec.rb']
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "floormanager"
18
+ gem.summary = %Q{Handle threaded workers like a champ}
19
+ gem.description = %Q{Simple ruby library for handling threaded workers operating on a queue}
20
+ gem.email = "inge@elektronaut.no"
21
+ gem.homepage = "http://github.com/elektronaut/floormanager"
22
+ gem.authors = ["Inge Jørgensen"]
23
+ # dependencies defined in Gemfile
25
24
  end
25
+ Jeweler::RubygemsDotOrgTasks.new
26
26
 
27
- Spec::Rake::SpecTask.new(:rcov) do |spec|
28
- spec.libs << 'lib' << 'spec'
29
- spec.pattern = 'spec/**/*_spec.rb'
30
- spec.rcov = true
27
+ require 'rake/testtask'
28
+ Rake::TestTask.new(:test) do |test|
29
+ test.libs << 'lib' << 'test'
30
+ test.pattern = 'test/**/test_*.rb'
31
+ test.verbose = true
31
32
  end
32
33
 
33
- task :spec => :check_dependencies
34
+ require 'rcov/rcovtask'
35
+ Rcov::RcovTask.new do |test|
36
+ test.libs << 'test'
37
+ test.pattern = 'test/**/test_*.rb'
38
+ test.verbose = true
39
+ test.rcov_opts << '--exclude "gems/*"'
40
+ end
34
41
 
35
- task :default => :spec
42
+ task :default => :test
36
43
 
37
44
  require 'rake/rdoctask'
38
45
  Rake::RDocTask.new do |rdoc|
39
46
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
40
47
 
41
48
  rdoc.rdoc_dir = 'rdoc'
42
- rdoc.title = "floormanager #{version}"
49
+ rdoc.title = "mygem #{version}"
43
50
  rdoc.rdoc_files.include('README*')
44
51
  rdoc.rdoc_files.include('lib/**/*.rb')
45
- end
52
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.3.0
data/examples/twitter.rb CHANGED
@@ -36,13 +36,13 @@ class Twitter
36
36
  workers.perform(:threads => @concurrency) do |query_string|
37
37
  retries = 0
38
38
  begin
39
- results = self.class.get('/search.json', :query => {:q => "\"#{query_string}\""})
39
+ results = self.class.get('/search.json', :query => {:q => "#{query_string}"})
40
40
  # Handle rate limiting
41
41
  if results.code == 420
42
42
  if result.headers['retry-after']
43
43
  retry_delay = result.headers['retry-after'].first.to_i
44
44
  else
45
- retry_delay = 60
45
+ retry_delay = @retry_delay
46
46
  end
47
47
  workers.halt(retry_delay) # Halt all workers for the retry delay
48
48
  retry
data/floormanager.gemspec CHANGED
@@ -1,61 +1,64 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{floormanager}
8
- s.version = "0.2.1"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Inge J\303\270rgensen"]
12
- s.date = %q{2010-05-14}
12
+ s.date = %q{2011-06-17}
13
13
  s.description = %q{Simple ruby library for handling threaded workers operating on a queue}
14
14
  s.email = %q{inge@elektronaut.no}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
- "README.rdoc"
17
+ "README.rdoc"
18
18
  ]
19
19
  s.files = [
20
20
  ".document",
21
- ".gitignore",
22
- "LICENSE",
23
- "README.rdoc",
24
- "Rakefile",
25
- "VERSION",
26
- "examples/twitter.rb",
27
- "floormanager.gemspec",
28
- "lib/floormanager.rb",
29
- "lib/floormanager/queue.rb",
30
- "lib/floormanager/result.rb",
31
- "lib/floormanager/states.rb",
32
- "lib/floormanager/workers.rb",
33
- "spec/floormanager_spec.rb",
34
- "spec/spec.opts",
35
- "spec/spec_helper.rb"
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "LICENSE",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "examples/twitter.rb",
28
+ "floormanager.gemspec",
29
+ "lib/floormanager.rb",
30
+ "lib/floormanager/queue.rb",
31
+ "lib/floormanager/result.rb",
32
+ "lib/floormanager/states.rb",
33
+ "lib/floormanager/workers.rb",
34
+ "test/helper.rb",
35
+ "test/test_floormanager.rb"
36
36
  ]
37
37
  s.homepage = %q{http://github.com/elektronaut/floormanager}
38
- s.rdoc_options = ["--charset=UTF-8"]
39
38
  s.require_paths = ["lib"]
40
- s.rubygems_version = %q{1.3.6}
39
+ s.rubygems_version = %q{1.3.7}
41
40
  s.summary = %q{Handle threaded workers like a champ}
42
- s.test_files = [
43
- "spec/floormanager_spec.rb",
44
- "spec/spec_helper.rb",
45
- "examples/twitter.rb"
46
- ]
47
41
 
48
42
  if s.respond_to? :specification_version then
49
43
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
50
44
  s.specification_version = 3
51
45
 
52
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
53
- s.add_development_dependency(%q<rspec>, [">= 1.3.0"])
46
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
48
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
49
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.2"])
50
+ s.add_development_dependency(%q<rcov>, [">= 0"])
54
51
  else
55
- s.add_dependency(%q<rspec>, [">= 1.3.0"])
52
+ s.add_dependency(%q<shoulda>, [">= 0"])
53
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
54
+ s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
55
+ s.add_dependency(%q<rcov>, [">= 0"])
56
56
  end
57
57
  else
58
- s.add_dependency(%q<rspec>, [">= 1.3.0"])
58
+ s.add_dependency(%q<shoulda>, [">= 0"])
59
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
60
+ s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
61
+ s.add_dependency(%q<rcov>, [">= 0"])
59
62
  end
60
63
  end
61
64
 
@@ -14,22 +14,18 @@ module FloorManager
14
14
  @queue << {
15
15
  :item => item,
16
16
  :value => nil,
17
- :state => States::PENDING
17
+ :state => States::PENDING,
18
+ :index => @queue.length
18
19
  }
19
20
  end
20
21
  alias :<< :add
21
22
 
22
- # Get the value of an item in the queue
23
- def get_value(key)
24
- (item = get_item(key)) ? item[:value] : nil
23
+ # Get an item in the queue
24
+ def get_item(index)
25
+ @queue[index]
25
26
  end
26
- alias :[] :get_value
27
+ alias :[] :get_item
27
28
 
28
- # Returns all the items in the queue
29
- def keys
30
- @queue.map{|i| i[:item]}
31
- end
32
-
33
29
  # Returns each item with value, hash style
34
30
  def each
35
31
  @queue.each{|item| yield item[:item], item[:value]}
@@ -40,7 +36,7 @@ module FloorManager
40
36
  if pending?
41
37
  item = pending_items.first
42
38
  item[:state] = States::CHECKED_OUT
43
- item[:item]
39
+ item
44
40
  else
45
41
  nil
46
42
  end
@@ -48,13 +44,11 @@ module FloorManager
48
44
 
49
45
  # Check in an item with a new value, optionally with a state
50
46
  # (which defaults to SUCCESS)
51
- def checkin(item, value, state=States::SUCCESS)
52
- if keys.include?(item)
53
- item = get_item(item)
54
- item[:value] = value
55
- item[:state] = state
47
+ def checkin(item, state=States::SUCCESS)
48
+ if item.kind_of?(Hash) && @queue[item[:index]][:item] == item[:item]
49
+ @queue[item[:index]] = item.merge({:state => state})
56
50
  else
57
- invalid_key!
51
+ invalid_item!
58
52
  end
59
53
  end
60
54
 
@@ -98,41 +92,11 @@ module FloorManager
98
92
  failed_items.map{|i| i[:item]}
99
93
  end
100
94
 
101
- # Get the state of an item
102
- def state(key)
103
- (item = get_item(key)) ? item[:state] : invalid_key!
104
- end
105
-
106
- # Is this item processed?
107
- def processed?(key)
108
- state(key) > States::PENDING
109
- end
110
-
111
- # Is this item checked out?
112
- def checked_out?(key)
113
- state(key) == States::CHECKED_OUT
114
- end
115
-
116
- # Did this item fail?
117
- def failed?(key)
118
- state(key) == States::FAILED
119
- end
120
-
121
- # Did this item succeed?
122
- def success?(key)
123
- state(key) == States::SUCCESS
124
- end
125
-
126
- # Is this item completed?
127
- def completed?(key)
128
- state(key) >= States::FAILED
129
- end
130
-
131
95
  private
132
96
 
133
97
  # Handle invalid keys
134
- def invalid_key!
135
- raise ArgumentError, "Invalid key: #{item.inspect}"
98
+ def invalid_item!
99
+ raise ArgumentError, "Invalid item: #{item.inspect}"
136
100
  end
137
101
 
138
102
  # Get an item by key
@@ -9,21 +9,26 @@ module FloorManager
9
9
  attr_reader :queue
10
10
 
11
11
  def perform(options={})
12
- options = {:threads => 1}.merge(options)
12
+ options = {:threads => 1, :timeout => false}.merge(options)
13
13
  threads = (0...options[:threads]).to_a.map do |thread_id|
14
14
  Thread.new do
15
15
  until queue.done?
16
16
  if item = checkout
17
- result = yield(item)
17
+ result = yield(item[:item])
18
18
  result = Result.new(result, (result.state rescue States::SUCCESS))
19
- checkin(item, result, result.state)
19
+ item[:value] = result
20
+ checkin(item, result.state)
20
21
  else
21
22
  Thread.pass
22
23
  end
23
24
  end
24
25
  end
25
26
  end
26
- threads.each{|t| t.join}
27
+ if options[:timeout]
28
+ threads.each{|t| t.join(options[:timeout])}
29
+ else
30
+ threads.each{|t| t.join}
31
+ end
27
32
  @queue
28
33
  end
29
34
 
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'floormanager'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,32 @@
1
+ require 'helper'
2
+
3
+ class TestFloorManager < Test::Unit::TestCase
4
+
5
+ context "a processed queue" do
6
+ setup do
7
+ workers = FloorManager::Workers.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
8
+ @results = workers.perform(:threads => 5) do |number|
9
+ number * 10
10
+ end
11
+ end
12
+
13
+ should "process a queue" do
14
+ @results.each do |original, result|
15
+ assert_equal (original * 10), result
16
+ end
17
+ end
18
+ end
19
+
20
+ context 'a queue with non-unique items' do
21
+ setup do
22
+ @queue = FloorManager::Queue.new(['a', 'a', 'b', 'c'])
23
+ end
24
+
25
+ should "not hang" do
26
+ FloorManager::Workers.new(@queue).perform(:threads => 5) do |item|
27
+ end
28
+ assert true # The processes will simply hang here if not
29
+ end
30
+ end
31
+
32
+ end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: floormanager
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 19
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
- - 2
8
- - 1
9
- version: 0.2.1
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
10
11
  platform: ruby
11
12
  authors:
12
13
  - "Inge J\xC3\xB8rgensen"
@@ -14,23 +15,69 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-05-14 00:00:00 +02:00
18
+ date: 2011-06-17 00:00:00 +02:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
- name: rspec
22
+ type: :development
22
23
  prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
+ name: shoulda
25
+ version_requirements: &id001 !ruby/object:Gem::Requirement
26
+ none: false
24
27
  requirements:
25
28
  - - ">="
26
29
  - !ruby/object:Gem::Version
30
+ hash: 3
31
+ segments:
32
+ - 0
33
+ version: "0"
34
+ requirement: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ type: :development
37
+ prerelease: false
38
+ name: bundler
39
+ version_requirements: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 23
27
45
  segments:
28
46
  - 1
29
- - 3
30
47
  - 0
31
- version: 1.3.0
48
+ - 0
49
+ version: 1.0.0
50
+ requirement: *id002
51
+ - !ruby/object:Gem::Dependency
32
52
  type: :development
33
- version_requirements: *id001
53
+ prerelease: false
54
+ name: jeweler
55
+ version_requirements: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ hash: 11
61
+ segments:
62
+ - 1
63
+ - 6
64
+ - 2
65
+ version: 1.6.2
66
+ requirement: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ type: :development
69
+ prerelease: false
70
+ name: rcov
71
+ version_requirements: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ hash: 3
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ requirement: *id004
34
81
  description: Simple ruby library for handling threaded workers operating on a queue
35
82
  email: inge@elektronaut.no
36
83
  executables: []
@@ -42,7 +89,8 @@ extra_rdoc_files:
42
89
  - README.rdoc
43
90
  files:
44
91
  - .document
45
- - .gitignore
92
+ - Gemfile
93
+ - Gemfile.lock
46
94
  - LICENSE
47
95
  - README.rdoc
48
96
  - Rakefile
@@ -54,40 +102,41 @@ files:
54
102
  - lib/floormanager/result.rb
55
103
  - lib/floormanager/states.rb
56
104
  - lib/floormanager/workers.rb
57
- - spec/floormanager_spec.rb
58
- - spec/spec.opts
59
- - spec/spec_helper.rb
105
+ - test/helper.rb
106
+ - test/test_floormanager.rb
60
107
  has_rdoc: true
61
108
  homepage: http://github.com/elektronaut/floormanager
62
109
  licenses: []
63
110
 
64
111
  post_install_message:
65
- rdoc_options:
66
- - --charset=UTF-8
112
+ rdoc_options: []
113
+
67
114
  require_paths:
68
115
  - lib
69
116
  required_ruby_version: !ruby/object:Gem::Requirement
117
+ none: false
70
118
  requirements:
71
119
  - - ">="
72
120
  - !ruby/object:Gem::Version
121
+ hash: 3
73
122
  segments:
74
123
  - 0
75
124
  version: "0"
76
125
  required_rubygems_version: !ruby/object:Gem::Requirement
126
+ none: false
77
127
  requirements:
78
128
  - - ">="
79
129
  - !ruby/object:Gem::Version
130
+ hash: 3
80
131
  segments:
81
132
  - 0
82
133
  version: "0"
83
134
  requirements: []
84
135
 
85
136
  rubyforge_project:
86
- rubygems_version: 1.3.6
137
+ rubygems_version: 1.3.7
87
138
  signing_key:
88
139
  specification_version: 3
89
140
  summary: Handle threaded workers like a champ
90
- test_files:
91
- - spec/floormanager_spec.rb
92
- - spec/spec_helper.rb
93
- - examples/twitter.rb
141
+ test_files: []
142
+
data/.gitignore DELETED
@@ -1,21 +0,0 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- pkg
20
-
21
- ## PROJECT::SPECIFIC
@@ -1,7 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe "Floormanager" do
4
- it "fails" do
5
- fail "hey buddy, you should probably rename this file and start specing for real"
6
- end
7
- end
data/spec/spec.opts DELETED
@@ -1 +0,0 @@
1
- --color
data/spec/spec_helper.rb DELETED
@@ -1,9 +0,0 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__))
2
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
- require 'floormanager'
4
- require 'spec'
5
- require 'spec/autorun'
6
-
7
- Spec::Runner.configure do |config|
8
-
9
- end