jobQueue 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -53,11 +53,16 @@ That's it. You might have look at tests, that come with the jobQueue gem.
53
53
 
54
54
  === Parallelize system commands
55
55
 
56
- Any string is expected to be a valid system command and executed via Ruby's system call, e.g.
56
+ Use a separate class for this and push string to it:
57
57
 
58
+ jq = SystemJobs.new(nThreads)
58
59
  jq.push('find ./src -name "*.rb"','find ./downloads -name "*.rb"')
59
60
 
60
- will start 2 parallel searches for ruby files.
61
+ will start 2 parallel searches for ruby files. This is implemented in the
62
+ prun.rb script, which comes with the jobQueue gem. To run each line of a shell
63
+ script on 10 threads, use:
64
+
65
+ prun.rb 10 jobs.sh
61
66
 
62
67
  == Support, Issues, Bugs, ...
63
68
 
@@ -69,9 +74,9 @@ As long there is no dedicataed project page, please use direct mail or the ruby-
69
74
 
70
75
  == License
71
76
 
72
- jobQueue makes use of the BSD License
77
+ jobQueue use the BSD License
73
78
 
74
- :include: LICENSE
79
+ :include LICENSE
75
80
 
76
81
 
77
82
  ---
data/bin/prun.rb CHANGED
@@ -1,19 +1,41 @@
1
1
  #!/usr/bin/env ruby
2
+ require 'optparse'
2
3
  require 'jobqueue'
3
4
  # ==============================================================================
4
5
  # Example script:
5
6
  # Read in a script and process line in parallel with a given number of threads:
6
- # Usage: prun.rb 10 myScript.sh
7
+ # Usage: prun.rb <num> myScript.sh
7
8
  # Attention: each line of the input script is regarded as a separate command
8
9
  # ==============================================================================
9
- unless ARGV.size == 2
10
- warn "provide number of threads and input data"
10
+
11
+ nTh = SystemJobs.maxnumber_of_processors
12
+ options = {:workers => nTh}
13
+ optparse = OptionParser.new do|opts|
14
+ opts.banner = "Usage: prun.rb [options] command-files"
15
+
16
+ opts.separator ""
17
+ opts.on('-j [num]',"Number of worker threads (default:#{nTh})") do |num|
18
+ options[:workers] = num
19
+ end
20
+ # This displays the help screen, all programs are
21
+ # assumed to have this option.
22
+ opts.on( '-h', '--help', 'Display this screen' ) do
23
+ puts opts
24
+ exit
25
+ end
26
+ end
27
+ optparse.parse!
28
+
29
+ if ARGV.empty?
30
+ warn "Provide an input file"
31
+ puts optparse.help
11
32
  exit
12
33
  end
13
- # read number of threads
14
- noTh = ARGV[0].to_i
15
- # read file line per line
16
- lines = File.open(ARGV[1]).readlines.map(&:chomp)
17
- q = SystemJobs.new(noTh)
18
- q.push(*lines)
19
- q.run
34
+
35
+ ARGV.each do|f|
36
+ # read file line per line
37
+ lines = File.open(f).readlines.map(&:chomp)
38
+ q = SystemJobs.new(nTh)
39
+ lines.each {|line| q.push(line) }
40
+ q.run
41
+ end
data/gemspec CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
 
3
3
  spec = Gem::Specification.new do |s|
4
4
  s.name = "jobQueue"
5
- s.version = '1.0.2'
5
+ s.version = '1.0.3'
6
6
  s.platform = Gem::Platform::RUBY
7
7
  s.bindir = 'bin'
8
8
  s.files = ["lib/jobqueue.rb","bin/prun.rb"] + ["gemspec","LICENSE","README.rdoc"]
@@ -14,7 +14,7 @@ spec = Gem::Specification.new do |s|
14
14
  s.homepage = "https://github.com/Try2Code/jobQueue"
15
15
  s.extra_rdoc_files = ["README.rdoc","LICENSE"]
16
16
  s.license = "BSD"
17
- s.test_files = "test/test_jobqueue.rb"
17
+ s.test_file = "test/test_jobqueue.rb"
18
18
  s.required_ruby_version = ">= 1.9"
19
19
  end
20
20
 
data/lib/jobqueue.rb CHANGED
@@ -9,24 +9,30 @@ require 'pp'
9
9
  # Sized Queue for limiting the number of parallel jobs
10
10
  # ==============================================================================
11
11
  class JobQueue
12
- attr_reader :size, :queue, :threads
12
+ attr_reader :workers, :threads
13
13
 
14
14
  # Create a new queue qith a given number of worker threads
15
- def initialize(size)
16
- @size = size
17
- @queue = Queue.new
15
+ def initialize(nWorkers)
16
+ @workers = nWorkers
17
+ @queue = Queue.new
18
18
  end
19
19
 
20
+ # borrow some useful methods from Queue class
21
+ [:size,:length,:clear,:empty?].each {|method|
22
+ define_method(method) { @queue.send(method) }
23
+ }
24
+
20
25
  # Put jobs into the queue. Use
21
26
  # proc,args for single methods
22
27
  # object,:method,args for sende messages to objects
23
- def push(*item)
24
- @queue << item
28
+ def push(*item,&block)
29
+ @queue << item unless item.empty?
30
+ @queue << [block] unless block.nil?
25
31
  end
26
32
 
27
33
  # Start workers to run through the queue
28
34
  def run
29
- @threads = (1..@size).map {|i|
35
+ @threads = (1..@workers).map {|i|
30
36
  Thread.new(@queue) {|q|
31
37
  until ( q == ( task = q.deq ) )
32
38
  if task.size > 1
@@ -49,34 +55,41 @@ class JobQueue
49
55
  end
50
56
 
51
57
  # Get the maximum number of parallel runs
52
- def number_of_processors
53
- if RUBY_PLATFORM =~ /linux/
54
- return `cat /proc/cpuinfo | grep processor | wc -l`.to_i
55
- elsif RUBY_PLATFORM =~ /darwin/
56
- return `sysctl -n hw.logicalcpu`.to_i
57
- elsif RUBY_PLATFORM =~ /(win32|mingw|cygwin)/
58
- # this works for windows 2000 or greater
59
- require 'win32ole'
60
- wmi = WIN32OLE.connect("winmgmts://")
61
- wmi.ExecQuery("select * from Win32_ComputerSystem").each do |system|
62
- begin
63
- processors = system.NumberOfLogicalProcessors
64
- rescue
65
- processors = 0
58
+ def JobQueue.maxnumber_of_processors
59
+ case RUBY_ENGINE
60
+ when 'jruby'
61
+ return Runtime.getRuntime().availableProcessors().to_i
62
+ # processors = java.lang.Runtime.getRuntime.availableProcessors
63
+ when 'ironruby'
64
+ return System::Environment.ProcessorCount
65
+ when 'ruby'
66
+ case RUBY_PLATFORM
67
+ when /linux/
68
+ return `cat /proc/cpuinfo | grep processor | wc -l`.to_i
69
+ when /darwin/
70
+ return `sysctl -n hw.logicalcpu`.to_i
71
+ when /(win32|mingw|cygwin)/
72
+ # this works for windows 2000 or greater
73
+ require 'win32ole'
74
+ wmi = WIN32OLE.connect("winmgmts://")
75
+ wmi.ExecQuery("select * from Win32_ComputerSystem").each do |system|
76
+ begin
77
+ processors = system.NumberOfLogicalProcessors
78
+ rescue
79
+ processors = 0
80
+ end
81
+ return [system.NumberOfProcessors, processors].max
66
82
  end
67
- return [system.NumberOfProcessors, processors].max
68
83
  end
69
- elseif RUBY_PLATFORM =~ /java/
70
- return Runtime.getRuntime().availableProcessors().to_i
71
84
  end
72
- raise "can't determine 'number_of_processors' for '#{RUBY_PLATFORM}'"
85
+ raise "Cannot determine the number of available Processors for RUBY_PLATFORM:'#{RUBY_PLATFORM}' and RUBY_ENGINE:#{RUBY_ENGINE}"
73
86
  end
74
87
  end
75
88
 
76
89
  # Special class for runing operating system commands with Ruby's system call
77
90
  class SystemJobs < JobQueue
78
91
  def run
79
- @threads = (1..@size).map {|i|
92
+ @threads = (1..@workers).map {|i|
80
93
  Thread.new(@queue) {|q|
81
94
  until ( q == ( task = q.deq ) )
82
95
  IO.popen(task).read
@@ -43,6 +43,19 @@ class TestJobQueue < Test::Unit::TestCase
43
43
  @sysjq = SystemJobs.new(NTHREDs)
44
44
  end
45
45
 
46
+ def test_queue_methods
47
+ assert_equal(NTHREDs,@jq.workers)
48
+ assert_equal(0,@jq.size)
49
+ assert_equal(0,@jq.length)
50
+ assert(@jq.empty?,"jobQueue is not empty")
51
+ 4.times { @jq.push(Math,:sqrt,rand) }
52
+ assert_equal(4,@jq.size)
53
+ @jq.clear
54
+ assert(@jq.empty?,"jobQueue is not empty")
55
+ 4.times { @jq.push(Math,:sqrt,rand) }
56
+ @jq.run
57
+ assert(@jq.empty?,"jobQueue is not empty")
58
+ end
46
59
  def test_system_cmds
47
60
  cmds = %w[date ls echo true]
48
61
  7.times { @sysjq.push(cmds[(4*rand).floor])}
@@ -134,7 +147,9 @@ class TestJobQueue < Test::Unit::TestCase
134
147
  end
135
148
 
136
149
  def test_max
137
- assert_equal(8,@jq.number_of_processors) if `hostname`.chomp == 'thingol'
150
+ assert_equal(8,JobQueue.maxnumber_of_processors) if `hostname`.chomp == 'thingol'
151
+ assert_equal(JobQueue.maxnumber_of_processors,SystemJobs.maxnumber_of_processors)
152
+ pp SystemJobs.maxnumber_of_processors
138
153
  end
139
154
 
140
155
  def test_push
@@ -148,4 +163,39 @@ class TestJobQueue < Test::Unit::TestCase
148
163
  assert_equal(2,a.h[1])
149
164
  assert_equal(77,a.i)
150
165
  end
166
+
167
+ def test_block
168
+ a = A.new
169
+ @jq.push { a.i = 111 }
170
+ @jq.run
171
+ assert_equal(111,a.i)
172
+
173
+ size = 100
174
+ (0..size).each {|i|
175
+ @jq.push do
176
+ a.h[i] = i*i
177
+ end
178
+ }
179
+ @jq.run
180
+ (0..size).each {|i| assert_equal(i*i,a.h[i]) }
181
+ end
182
+
183
+ def test_block_vs_method
184
+ a = A.new
185
+ size = 100
186
+ # use blocks
187
+ (0..size).each {|i|
188
+ @jq.push do
189
+ a.h[i] = i*i
190
+ end
191
+ }
192
+ @jq.run
193
+ (0..size).each {|i| assert_equal(i*i,a.h[i]) }
194
+ a.h.clear
195
+
196
+ # use method
197
+ (0..size).each {|i| @jq.push(a,:seth,i) }
198
+ @jq.run
199
+ (0..size).each {|i| assert_equal(2*i,a.h[i]) }
200
+ end
151
201
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jobQueue
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-14 00:00:00.000000000 Z
12
+ date: 2011-12-15 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Run Shell commands or Ruby methods in parallel
15
15
  email: stark.dreamdetective@gmail.com