parallelQueue 1.0.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 24af9cbe3c3f6100ad83835d65e0dd239b7fd571
4
+ data.tar.gz: 040fed41dad97007807acf19a58b05691ca9a21a
5
+ SHA512:
6
+ metadata.gz: 520aaa05828f84cf4247e1367074a680c4c13207750180f4d67aa0383660bcc2ca6bf527d72d1d1dbb230ce12570258f451e1bf39b0e4613827e19ca8a4201f1
7
+ data.tar.gz: e9f8e61f9f347e326da28ff0286c356ad0f9ece706bb404ecffba87f9b2e6d014cbfa4b1263bd153e56b152ed2dcc8e57004461153cc3a90ca9f6b9b99960fe6
data/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2011-2014, 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.
@@ -0,0 +1,111 @@
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 blocks, Procs and Lambdas
10
+ * Run instance and class methods
11
+ * Run shell commands
12
+ * Respect user definded locks
13
+
14
+ I started a python2 implementation of this, which can be installed via pip
15
+ (https://pypi.python.org/pypi/jobqueue). When its maature enough, I will use
16
+ the ruby version numbers for it.
17
+
18
+ == Installation
19
+
20
+ === Gem Installation
21
+
22
+ Download and install jobQueue with the following.
23
+
24
+ gem install jobQueue
25
+
26
+ === Requirements
27
+
28
+ JobQueue requires Ruby only, but versions 1.9.x are needed to make use of system threads.
29
+
30
+ == Usage
31
+
32
+ === Parallelize Ruby's blocks, procs, lambdas and things
33
+
34
+ Create a JobQueue with nThreads worker with:
35
+
36
+ jq = JobQueue.new(nThreads)
37
+
38
+ Use its push method to put in something to do
39
+
40
+ * For blocks:
41
+ jq.push do
42
+ myObject.method0(...)
43
+ myObject.method1(...)
44
+ myObject.method3(...)
45
+ end
46
+
47
+ * For procs and lambdas:
48
+
49
+ jp.push(myProc,arg0,arg1,...)
50
+
51
+ * For object methods:
52
+
53
+ jq.push([myObject,[:method,arg0,arg1,...])
54
+
55
+ * Same code can be used for class methods:
56
+
57
+ jq.push(myClass,[:myClassMethod,arg0,arg1,...])
58
+
59
+ To start the workers, call
60
+
61
+ jq.run
62
+
63
+ That's it. You might have look at tests, that come with the jobQueue gem.
64
+
65
+ === Parallelize system commands
66
+
67
+ Use a separate class for this and push string to it:
68
+
69
+ jq = SystemJobs.new(nThreads)
70
+ jq.push('find ./src -name "*.rb"','find ./downloads -name "*.rb"')
71
+
72
+ will start 2 parallel searches for ruby files. This is implemented in the
73
+ prun.rb script, which comes with the jobQueue gem. To run each line of a shell
74
+ script on 10 threads, use:
75
+
76
+ prun.rb -j 10 jobs.sh
77
+
78
+ The '-j' switch is optional. Default is the maximum number of cores. The script
79
+ accepts multiple files and processes one after another. Try '-h' for documentation.
80
+
81
+ == Support, Issues, Bugs, ...
82
+
83
+ please use personal mail, ruby-lang mailing list or github
84
+
85
+ == Changelog
86
+
87
+ * 1.0.11: prun.rb now ignores empty lines
88
+ * 1.0.10: more flexible logging control (new switches '-l' and '-b')
89
+ * 1.0.9: print out stdout and stderr from the jobs given to prun.rb, use '-D' to avoid printing
90
+ * 1.0.8: support AIX for getting the maximum number of processors, improve processor count for jruby and rbx
91
+
92
+ == Credits
93
+
94
+ [<b>Robert Klemme</b>] For the first hints: https://www.ruby-forum.com/topic/68001#86298
95
+
96
+ == License
97
+
98
+ jobQueue use the BSD License
99
+
100
+ :include LICENSE
101
+
102
+
103
+ ---
104
+
105
+ = Other stuff
106
+
107
+ Author:: Ralf Mueller <stark.dreamdetective@gmail.com>
108
+ Requires:: Ruby 1.9 or later
109
+ License:: Copyright 2011-2016 by Ralf Mueller
110
+ Released under BSD-style license. See the LICENSE
111
+ file included in the distribution.
@@ -0,0 +1,22 @@
1
+ require 'rubygems'
2
+
3
+ spec = Gem::Specification.new do |s|
4
+ s.name = "parallelQueue"
5
+ s.version = '1.0.0'
6
+ s.platform = Gem::Platform::RUBY
7
+ s.files = ["lib/parallelQueue.rb"] + ["gemspec.parallelQueue","LICENSE","README.rdoc"]
8
+ s.description = "Extension 'parallel': Interface for pushung blocks"
9
+ s.summary = "This is a small extension to the 'parallel' library. It \
10
+ allows to push abitrary blocks to a Queue and execute them in parallel, \
11
+ whereas 'parallel' needs predefined lambdas"
12
+ s.author = "Ralf Mueller"
13
+ s.email = "stark.dreamdetective@gmail.com"
14
+ s.homepage = "https://github.com/Try2Code/jobQueue"
15
+ s.extra_rdoc_files = ["README.rdoc","LICENSE"]
16
+ s.license = "ISC" #BSD-2-Clause
17
+ s.test_file = "test/test_parallelQueue.rb"
18
+ s.required_ruby_version = ">= 1.8"
19
+ s.has_rdoc = true
20
+ end
21
+
22
+ # vim:ft=ruby
@@ -0,0 +1,69 @@
1
+ require 'parallel'
2
+ # ==============================================================================
3
+ # Author: Ralf Mueller, ralf.mueller@mpimet.mpg.de
4
+ # suggestions from Robert Klemme (https://www.ruby-forum.com/topic/68001#86298)
5
+ #
6
+ # ==============================================================================
7
+
8
+ # ParallelQueue is nothing but a regular queue with the ability to store blocks
9
+ # or methods (plus aruments)
10
+ class ParallelQueue < Queue
11
+ alias :queue_push :push
12
+ include Parallel::ProcessorCount
13
+
14
+ # puts code to the queue as a
15
+ # * method: push(method,arg1,arg2,...)
16
+ # * block: push { ... }
17
+ def push (*item, &block)
18
+ queue_push(item ) unless item.empty?
19
+ queue_push([block]) unless block.nil?
20
+ end
21
+
22
+ # run things with the 'parallel' library - results are returned automatically
23
+ def run(workers=processor_count)
24
+ queue_push(Parallel::Stop)
25
+ Parallel.map(self,:in_threads => workers) {|task|
26
+ if task.size > 1
27
+ if task[0].kind_of? Proc
28
+ # Expects proc/lambda with arguments,e.g.
29
+ # [mysqrt,2.789]
30
+ # [myproc,x,y,z]
31
+ task[0].call(*task[1..-1])
32
+ else
33
+ # expect an object in task[0] and one of its methods with arguments
34
+ # in task[1] as a symbol
35
+ # e.g. [a,[:attribute=,1] or
36
+ # Math,:exp,0
37
+ task[0].send(task[1],*task[2..-1])
38
+ end
39
+ else
40
+ task[0].call
41
+ end
42
+ }
43
+ end
44
+
45
+ # run the given calls WITHOUT automatic result storage, but faster
46
+ def justRun(workers=processor_count)
47
+ @threads = (1..workers).map {|i|
48
+ Thread.new(self) {|q|
49
+ until ( q == ( task = q.deq ) )
50
+ if task.size > 1
51
+ if task[0].kind_of? Proc
52
+ # Expects proc/lambda with arguments, e.g. [mysqrt,2.789]
53
+ task[0].call(*task[1..-1])
54
+ else
55
+ # expect an object in task[0] and one of its methods with
56
+ # arguments in task[1] as a symbol
57
+ # e.g. [a,[:attribute=,1]
58
+ task[0].send(task[1],*task[2..-1])
59
+ end
60
+ else
61
+ task[0].call
62
+ end
63
+ end
64
+ }
65
+ }
66
+ @threads.size.times { self.enq self}
67
+ @threads.each {|t| t.join}
68
+ end
69
+ end
@@ -0,0 +1,57 @@
1
+ require 'minitest/autorun'
2
+ require 'parallel'
3
+ $:.unshift File.join(File.dirname(__FILE__),"..","lib")
4
+ require 'parallelQueue'
5
+
6
+ class TestParallelQueue < Minitest::Test
7
+
8
+ def test_blocks
9
+ q = ParallelQueue.new
10
+
11
+ itemsA = %w[a:3:b x:55:x K:981:foo:tra]
12
+ itemsB = %w[a|5|b x|11|x K|187|foo|tra]
13
+
14
+ itemsA.each {|item|
15
+ q.push {
16
+ item.split(':')[1].to_i
17
+ }
18
+ }
19
+ itemsB.each {|item|
20
+ q.push {
21
+ item.split('|')[1].to_i
22
+ }
23
+ }
24
+ results = q.run.sort
25
+ assert_equal([3,5,11,55,187,981],results)
26
+ end
27
+
28
+ def test_procs
29
+ q = ParallelQueue.new
30
+
31
+ myProc = lambda {|r| Math.sqrt(r)}
32
+ pressure = lambda {|z|
33
+ 1013.25*Math.exp((-1)*(1.602769777072154)*Math.log((Math.exp(z/10000.0)*213.15+75.0)/288.15))
34
+ }
35
+ temperature = lambda {|z|
36
+ 213.0+75.0*Math.exp((-1)*z/10000.0)-273.15
37
+ }
38
+ vectorLength = lambda {|x,y,z| Math.sqrt(x*x + y*y + z*z) }
39
+
40
+ q.push(myProc,4.0)
41
+ q.push(Math,:sqrt,16.0)
42
+ [0,10,20,50,100,200,500,1000].map(&:to_f).each {|z|
43
+ q.push(pressure,z)
44
+ q.push(temperature,z)
45
+ }
46
+ q.push(Math,:sqrt,529.0)
47
+ q.push(vectorLength,0,1,0)
48
+ q.push(vectorLength,0,1,1)
49
+ q.push(vectorLength,1,1,1)
50
+
51
+ results = q.run(2).map {|f| f.round(2)}
52
+ assert_equal(
53
+ [1.0,1.41,1.73,2.0, 4.0, 7.71, 11.19, 13.36, 14.1, 14.48, 14.7, 14.78, 14.85, 23.0, 898.6, 954.56, 989.45, 1001.29, 1007.26, 1010.85, 1012.05, 1013.25],
54
+ results.sort
55
+ )
56
+ end
57
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: parallelQueue
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Ralf Mueller
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-29 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: 'Extension ''parallel'': Interface for pushung blocks'
14
+ email: stark.dreamdetective@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files:
18
+ - README.rdoc
19
+ - LICENSE
20
+ files:
21
+ - LICENSE
22
+ - README.rdoc
23
+ - gemspec.parallelQueue
24
+ - lib/parallelQueue.rb
25
+ - test/test_parallelQueue.rb
26
+ homepage: https://github.com/Try2Code/jobQueue
27
+ licenses:
28
+ - ISC
29
+ metadata: {}
30
+ post_install_message:
31
+ rdoc_options: []
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '1.8'
39
+ required_rubygems_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ requirements: []
45
+ rubyforge_project:
46
+ rubygems_version: 2.5.1
47
+ signing_key:
48
+ specification_version: 4
49
+ summary: This is a small extension to the 'parallel' library. It allows
50
+ to push abitrary blocks to a Queue and execute them in parallel, whereas
51
+ 'parallel' needs predefined lambdas
52
+ test_files:
53
+ - test/test_parallelQueue.rb