jobQueue 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +27 -0
- data/README.rdoc +85 -0
- data/bin/prun.rb +19 -0
- data/gemspec +19 -0
- data/lib/jobqueue.rb +83 -0
- metadata +52 -0
data/LICENSE
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
Copyright (c) 2011, Ralf Mueller (stark.dreamdetective@googlemail.com)
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
* Redistributions of source code must retain the above copyright notice,
|
8
|
+
this list of conditions and the following disclaimer.
|
9
|
+
|
10
|
+
* Redistributions in binary form must reproduce the above copyright
|
11
|
+
notice, this list of conditions and the following disclaimer in the
|
12
|
+
documentation and/or other materials provided with the distribution.
|
13
|
+
|
14
|
+
* The names of its contributors may not be used to endorse or promote
|
15
|
+
products derived from this software without specific prior written
|
16
|
+
permission.
|
17
|
+
|
18
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
22
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
= JobQueue - Let run your jobs in parallel
|
2
|
+
|
3
|
+
This package contains jobQueue:
|
4
|
+
* A simple class to parallalize your work on a user definend number of threads
|
5
|
+
* A ruby script, which uses the above class to run each line of a shell script
|
6
|
+
|
7
|
+
jobQueue can do the following things:
|
8
|
+
|
9
|
+
* Run shell commands
|
10
|
+
* Run instance and class methods
|
11
|
+
* Run Procs and Lambdas
|
12
|
+
* Respect user definded locks
|
13
|
+
|
14
|
+
== Installation
|
15
|
+
|
16
|
+
=== Gem Installation
|
17
|
+
|
18
|
+
Download and install jobQueue with the following.
|
19
|
+
|
20
|
+
gem install jobQueue
|
21
|
+
|
22
|
+
=== Requirements
|
23
|
+
|
24
|
+
JobQueue requires Ruby only, but versions 1.9.x are needed to make use of system threads.
|
25
|
+
|
26
|
+
== Usage
|
27
|
+
|
28
|
+
=== Parallelize Ruby's procs, lambdas and things
|
29
|
+
|
30
|
+
Create a JobQueue with nThreads worker with:
|
31
|
+
|
32
|
+
jq = JobQueue.new(nThreads)
|
33
|
+
|
34
|
+
Use its push method to put in something to do
|
35
|
+
|
36
|
+
* For procs and lambdas:
|
37
|
+
|
38
|
+
jp.push(myProc,arg0,arg1,...)
|
39
|
+
|
40
|
+
* For object methods:
|
41
|
+
|
42
|
+
jq.push([myObject,[:method,arg0,arg1,...])
|
43
|
+
|
44
|
+
* Same code can be used for class methods:
|
45
|
+
|
46
|
+
jq.push(myClass,[:myClassMethod,arg0,arg1,...])
|
47
|
+
|
48
|
+
To start the workers, call
|
49
|
+
|
50
|
+
jq.run
|
51
|
+
|
52
|
+
That's it. You might have look at tests, that come with the jobQueue gem.
|
53
|
+
|
54
|
+
=== Parallelize system commands
|
55
|
+
|
56
|
+
Any string is expected to be a valid system command and executed via Ruby's system call, e.g.
|
57
|
+
|
58
|
+
jq.push('find ./src -name "*.rb"','find ./downloads -name "*.rb"')
|
59
|
+
|
60
|
+
will start 2 parallel searches for ruby files.
|
61
|
+
|
62
|
+
== Support, Issues, Bugs, ...
|
63
|
+
|
64
|
+
As long there is no dedicataed project page, please use direct mail or the ruby-lang mailing list.
|
65
|
+
|
66
|
+
== Credits
|
67
|
+
|
68
|
+
[<b>Robert Klemme</b>] For the first hints: https://www.ruby-forum.com/topic/68001#86298
|
69
|
+
|
70
|
+
== License
|
71
|
+
|
72
|
+
jobQueue makes use of the BSD License
|
73
|
+
|
74
|
+
:include: LICENSE
|
75
|
+
|
76
|
+
|
77
|
+
---
|
78
|
+
|
79
|
+
= Other stuff
|
80
|
+
|
81
|
+
Author:: Ralf Mueller <stark.dreamdetective@gmail.com>
|
82
|
+
Requires:: Ruby 1.9 or later
|
83
|
+
License:: Copyright 2011 by Ralf Mueller
|
84
|
+
Released under BSD-style license. See the LICENSE
|
85
|
+
file included in the distribution.
|
data/bin/prun.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'jobqueue'
|
3
|
+
# ==============================================================================
|
4
|
+
# Example script:
|
5
|
+
# Read in a script and process line in parallel with a given number of threads:
|
6
|
+
# Usage: prun.rb 10 myScript.sh
|
7
|
+
# Attention: each line of the input script is regarded as a separate command
|
8
|
+
# ==============================================================================
|
9
|
+
unless ARGV.size == 2
|
10
|
+
warn "provide number of threads and input data"
|
11
|
+
exit
|
12
|
+
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 = JobQueue.new(noTh)
|
18
|
+
q.push(*lines)
|
19
|
+
q.run
|
data/gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
spec = Gem::Specification.new do |s|
|
4
|
+
s.name = "jobQueue"
|
5
|
+
s.version = '1.0.1'
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.bindir = 'bin'
|
8
|
+
s.files = ["lib/jobqueue.rb","bin/prun.rb"] + ["gemspec","LICENSE","README.rdoc"]
|
9
|
+
s.executables << 'prun.rb'
|
10
|
+
s.description = "Run Shell commands or Ruby methods in parallel"
|
11
|
+
s.summary = s.description
|
12
|
+
s.author = "Ralf Mueller"
|
13
|
+
s.email = "stark.dreamdetective@gmail.com"
|
14
|
+
# s.homepage = "http://
|
15
|
+
s.extra_rdoc_files = ["README.rdoc","LICENSE"]
|
16
|
+
s.required_ruby_version = ">= 1.9"
|
17
|
+
end
|
18
|
+
|
19
|
+
# vim:ft=ruby
|
data/lib/jobqueue.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'thread'
|
3
|
+
require 'pp'
|
4
|
+
# ==============================================================================
|
5
|
+
# Author: Ralf Mueller, ralf.mueller@zmaw.de
|
6
|
+
# suggestions from Robert Klemme (https://www.ruby-forum.com/topic/68001#86298)
|
7
|
+
#
|
8
|
+
# ==============================================================================
|
9
|
+
# Sized Queue for limiting the number of parallel jobs
|
10
|
+
# ==============================================================================
|
11
|
+
class JobQueue
|
12
|
+
attr_reader :size, :queue, :threads
|
13
|
+
|
14
|
+
# Create a new queue qith a given number of worker threads
|
15
|
+
def initialize(size)
|
16
|
+
@size = size
|
17
|
+
@queue = Queue.new
|
18
|
+
end
|
19
|
+
|
20
|
+
# Put jobs into the queue. Use
|
21
|
+
# strings for system commands
|
22
|
+
# 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}
|
27
|
+
end
|
28
|
+
|
29
|
+
# Start workers to run through the queue
|
30
|
+
def run
|
31
|
+
@threads = (1..@size).map {|i|
|
32
|
+
Thread.new(@queue) {|q|
|
33
|
+
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
|
48
|
+
else
|
49
|
+
warn 'provide 2d arrays'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
}
|
54
|
+
}
|
55
|
+
@threads.size.times { @queue.enq @queue}
|
56
|
+
@threads.each {|t| t.join}
|
57
|
+
end
|
58
|
+
|
59
|
+
# Get the maximum number of parallel runs
|
60
|
+
def number_of_processors
|
61
|
+
if RUBY_PLATFORM =~ /linux/
|
62
|
+
return `cat /proc/cpuinfo | grep processor | wc -l`.to_i
|
63
|
+
elsif RUBY_PLATFORM =~ /darwin/
|
64
|
+
return `sysctl -n hw.logicalcpu`.to_i
|
65
|
+
elsif RUBY_PLATFORM =~ /(win32|mingw|cygwin)/
|
66
|
+
# this works for windows 2000 or greater
|
67
|
+
require 'win32ole'
|
68
|
+
wmi = WIN32OLE.connect("winmgmts://")
|
69
|
+
wmi.ExecQuery("select * from Win32_ComputerSystem").each do |system|
|
70
|
+
begin
|
71
|
+
processors = system.NumberOfLogicalProcessors
|
72
|
+
rescue
|
73
|
+
processors = 0
|
74
|
+
end
|
75
|
+
return [system.NumberOfProcessors, processors].max
|
76
|
+
end
|
77
|
+
elseif RUBY_PLATFORM =~ /java/
|
78
|
+
return Runtime.getRuntime().availableProcessors().to_i
|
79
|
+
end
|
80
|
+
raise "can't determine 'number_of_processors' for '#{RUBY_PLATFORM}'"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
metadata
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jobQueue
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ralf Mueller
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-12-12 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Run Shell commands or Ruby methods in parallel
|
15
|
+
email: stark.dreamdetective@gmail.com
|
16
|
+
executables:
|
17
|
+
- prun.rb
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files:
|
20
|
+
- README.rdoc
|
21
|
+
- LICENSE
|
22
|
+
files:
|
23
|
+
- lib/jobqueue.rb
|
24
|
+
- bin/prun.rb
|
25
|
+
- gemspec
|
26
|
+
- LICENSE
|
27
|
+
- README.rdoc
|
28
|
+
homepage:
|
29
|
+
licenses: []
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.9'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
requirements: []
|
47
|
+
rubyforge_project:
|
48
|
+
rubygems_version: 1.8.11
|
49
|
+
signing_key:
|
50
|
+
specification_version: 3
|
51
|
+
summary: Run Shell commands or Ruby methods in parallel
|
52
|
+
test_files: []
|