jobQueue 1.0.1 → 1.0.2

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.
Files changed (5) hide show
  1. data/bin/prun.rb +1 -1
  2. data/gemspec +5 -3
  3. data/lib/jobqueue.rb +26 -20
  4. data/test/test_jobqueue.rb +151 -0
  5. metadata +8 -5
data/bin/prun.rb CHANGED
@@ -14,6 +14,6 @@ end
14
14
  noTh = ARGV[0].to_i
15
15
  # read file line per line
16
16
  lines = File.open(ARGV[1]).readlines.map(&:chomp)
17
- q = JobQueue.new(noTh)
17
+ q = SystemJobs.new(noTh)
18
18
  q.push(*lines)
19
19
  q.run
data/gemspec CHANGED
@@ -2,17 +2,19 @@ require 'rubygems'
2
2
 
3
3
  spec = Gem::Specification.new do |s|
4
4
  s.name = "jobQueue"
5
- s.version = '1.0.1'
5
+ s.version = '1.0.2'
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"]
9
9
  s.executables << 'prun.rb'
10
10
  s.description = "Run Shell commands or Ruby methods in parallel"
11
- s.summary = s.description
11
+ s.summary = "Run Shell commands or Ruby methods in parallel"
12
12
  s.author = "Ralf Mueller"
13
13
  s.email = "stark.dreamdetective@gmail.com"
14
- # s.homepage = "http://
14
+ s.homepage = "https://github.com/Try2Code/jobQueue"
15
15
  s.extra_rdoc_files = ["README.rdoc","LICENSE"]
16
+ s.license = "BSD"
17
+ s.test_files = "test/test_jobqueue.rb"
16
18
  s.required_ruby_version = ">= 1.9"
17
19
  end
18
20
 
data/lib/jobqueue.rb CHANGED
@@ -18,12 +18,10 @@ class JobQueue
18
18
  end
19
19
 
20
20
  # Put jobs into the queue. Use
21
- # strings for system commands
22
21
  # proc,args for single methods
23
- # [object,[:methods,args]] for sende messages to objects
24
- #
25
- def push(*items)
26
- items.each {|it| @queue << it}
22
+ # object,:method,args for sende messages to objects
23
+ def push(*item)
24
+ @queue << item
27
25
  end
28
26
 
29
27
  # Start workers to run through the queue
@@ -31,23 +29,17 @@ class JobQueue
31
29
  @threads = (1..@size).map {|i|
32
30
  Thread.new(@queue) {|q|
33
31
  until ( q == ( task = q.deq ) )
34
- if task.kind_of? String
35
- system(task)
36
- elsif task.kind_of? Proc
37
- task.call
38
- elsif task.kind_of? Array
39
- if task.size > 1
40
- if not task[1].kind_of? Array
41
- # Expects proc/lambda with arguments, e.g. [mysqrt,2.789]
42
- task[0].call(*task[1..-1])
43
- else
44
- # expect an object in task[0] and one of its methods with arguments in task[1] as a symbol
45
- # e.g. [a,[:attribute=,1]
46
- task[0].send(task[1][0],*task[1][1..-1])
47
- end
32
+ if task.size > 1
33
+ if task[0].kind_of? Proc
34
+ # Expects proc/lambda with arguments, e.g. [mysqrt,2.789]
35
+ task[0].call(*task[1..-1])
48
36
  else
49
- warn 'provide 2d arrays'
37
+ # expect an object in task[0] and one of its methods with arguments in task[1] as a symbol
38
+ # e.g. [a,[:attribute=,1]
39
+ task[0].send(task[1],*task[2..-1])
50
40
  end
41
+ else
42
+ task[0].call
51
43
  end
52
44
  end
53
45
  }
@@ -81,3 +73,17 @@ class JobQueue
81
73
  end
82
74
  end
83
75
 
76
+ # Special class for runing operating system commands with Ruby's system call
77
+ class SystemJobs < JobQueue
78
+ def run
79
+ @threads = (1..@size).map {|i|
80
+ Thread.new(@queue) {|q|
81
+ until ( q == ( task = q.deq ) )
82
+ IO.popen(task).read
83
+ end
84
+ }
85
+ }
86
+ @threads.size.times { @queue.enq @queue}
87
+ @threads.each {|t| t.join}
88
+ end
89
+ end
@@ -0,0 +1,151 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),"..","lib")
2
+ require 'test/unit'
3
+ require 'jobqueue'
4
+
5
+
6
+ NTHREDs = ENV['NTHREDs'].nil? ? 4 : ENV['NTHREDs']
7
+
8
+ class A
9
+ attr_accessor :i,:j,:k,:h
10
+ @@lock = Mutex.new
11
+
12
+ def initialize
13
+ @i, @j, @k = nil,nil,nil
14
+ @h = {}
15
+ end
16
+ def seti(i)
17
+ @i = i
18
+ end
19
+ def seth(v)
20
+ @@lock.synchronize{ @h[v] = 2*v}
21
+ end
22
+ end
23
+ class B
24
+ @@val = 0
25
+ def B.set(val)
26
+ @@val = val
27
+ end
28
+ def B.get
29
+ @@val
30
+ end
31
+ end
32
+ module C
33
+ def C.sqrt(v)
34
+ Math.sqrt(v)
35
+ end
36
+ end
37
+
38
+ class TestJobQueue < Test::Unit::TestCase
39
+
40
+ def setup
41
+ @jq = JobQueue.new(NTHREDs)
42
+ @jqSer = JobQueue.new(1)
43
+ @sysjq = SystemJobs.new(NTHREDs)
44
+ end
45
+
46
+ def test_system_cmds
47
+ cmds = %w[date ls echo true]
48
+ 7.times { @sysjq.push(cmds[(4*rand).floor])}
49
+ 20.times { @sysjq.push('ls')}
50
+ @sysjq.run
51
+ end
52
+
53
+ def test_proc_simple
54
+ halo = lambda { puts "halo"}
55
+ 11.times { @jq.push(halo) }
56
+ @jq.run
57
+ end
58
+ def test_proc
59
+ sqrt = lambda {|v| puts Math.sqrt(v)}
60
+ norm = lambda {|x,y| puts Math.sqrt(x*x + y*y)}
61
+ 10.times { @jq.push(sqrt,rand)}
62
+ 10.times { @jq.push(norm,rand,rand)}
63
+ @jq.run
64
+ end
65
+ def test_method
66
+ a = A.new
67
+ assert_equal(nil,a.i)
68
+ assert_equal(nil,a.j)
69
+ assert_equal(nil,a.k)
70
+ i = 10
71
+ @jq.push(a,:seti,i)
72
+ @jq.run
73
+ assert_equal(i,a.i)
74
+ i = 11
75
+ @jq.push(a,:seti,i)
76
+ @jq.run
77
+ assert_equal(i,a.i)
78
+ (0..77).each {|i| @jq.push(a,:seth,i) }
79
+ @jq.run
80
+ (0..77).each {|i| assert_equal(2*i,a.h[i]) }
81
+ a.h.clear;assert_equal({},a.h)
82
+ end
83
+ def test_accessor
84
+ a = A.new
85
+ assert_equal(nil,a.i)
86
+ assert_equal(nil,a.j)
87
+ assert_equal(nil,a.k)
88
+ # try ruby style accessors
89
+ @jqSer.push(a,:i=,1)
90
+ @jqSer.push(a,:j=,2)
91
+ @jqSer.push(a,:k=,3)
92
+ @jqSer.run
93
+ assert_equal(1,a.i)
94
+ assert_equal(2,a.j)
95
+ assert_equal(3,a.k)
96
+ @jq.push(a,:i=,10)
97
+ @jq.push(a,:j=,20)
98
+ @jq.push(a,:k=,30)
99
+ @jq.run
100
+ assert_equal(10,a.i)
101
+ assert_equal(20,a.j)
102
+ assert_equal(30,a.k)
103
+ end
104
+
105
+ def test_class_methods
106
+ @jq.push(B,:set,1)
107
+ @jq.run
108
+ assert_equal(1,B.get)
109
+ end
110
+ def test_module
111
+ @jq.push(C,:sqrt,10)
112
+ @jq.push(C,:sqrt,100)
113
+ @jq.push(C,:sqrt,1000)
114
+ @jq.run
115
+ end
116
+ def test_lock
117
+ lockfill = lambda {|myhash,value,lock|
118
+ lock.synchronize { myhash[value] = value}
119
+ }
120
+ fill = lambda {|myhash,value| myhash[value] = value}
121
+ a = A.new
122
+ a.seth(1)
123
+ assert_equal(2,a.h[1])
124
+
125
+ (0..1000).each {|i| @jq.push(fill,a.h,i) }
126
+ @jq.run
127
+ assert_not_equal(a.h.keys, a.h.keys.sort)
128
+ (0..20).each {|i| assert_equal(i,a.h[i])}
129
+ a.h.clear;assert_equal({},a.h)
130
+
131
+ lock = Mutex.new
132
+ (0..20).each {|i| @jq.push(lockfill,a.h,i,lock) }
133
+ @jq.run
134
+ end
135
+
136
+ def test_max
137
+ assert_equal(8,@jq.number_of_processors) if `hostname`.chomp == 'thingol'
138
+ end
139
+
140
+ def test_push
141
+ a = A.new
142
+ @jq.push(a,:seth,1)
143
+ @jq.push(a,:i=,77)
144
+ @jq.push($stdout,:puts,"halo")
145
+ @jq.push(Math,:sqrt,22)
146
+ @jq.push(lambda { puts "halo"})
147
+ @jq.run
148
+ assert_equal(2,a.h[1])
149
+ assert_equal(77,a.i)
150
+ end
151
+ 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.1
4
+ version: 1.0.2
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-12 00:00:00.000000000 Z
12
+ date: 2011-12-14 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
@@ -25,8 +25,10 @@ files:
25
25
  - gemspec
26
26
  - LICENSE
27
27
  - README.rdoc
28
- homepage:
29
- licenses: []
28
+ - test/test_jobqueue.rb
29
+ homepage: https://github.com/Try2Code/jobQueue
30
+ licenses:
31
+ - BSD
30
32
  post_install_message:
31
33
  rdoc_options: []
32
34
  require_paths:
@@ -49,4 +51,5 @@ rubygems_version: 1.8.11
49
51
  signing_key:
50
52
  specification_version: 3
51
53
  summary: Run Shell commands or Ruby methods in parallel
52
- test_files: []
54
+ test_files:
55
+ - test/test_jobqueue.rb