jobQueue 1.0.1 → 1.0.2

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