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.
- data/bin/prun.rb +1 -1
- data/gemspec +5 -3
- data/lib/jobqueue.rb +26 -20
- data/test/test_jobqueue.rb +151 -0
- metadata +8 -5
data/bin/prun.rb
CHANGED
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.
|
|
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 =
|
|
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
|
-
|
|
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
|
-
#
|
|
24
|
-
|
|
25
|
-
|
|
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.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
+
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
|
-
|
|
29
|
-
|
|
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
|