forkify 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ === 0.0.1 / 2009-06-23
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
data/Manifest.txt ADDED
@@ -0,0 +1,8 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/forkify.rb
6
+ test/test_forkify.rb
7
+ examples/a.rb
8
+ examples/b.rb
data/README.txt ADDED
@@ -0,0 +1,54 @@
1
+ = forkify
2
+
3
+ * http://github.com/dakrone/forkify
4
+
5
+ == DESCRIPTION:
6
+
7
+ forkify.rb makes it easy to process a bunch of data using 'n'
8
+ worker processes. It is based off of forkoff and threadify by Ara Howard.
9
+ It aims to be safe to use on Ruby 1.8.6+ and Ruby 1.9.1+
10
+
11
+ == FEATURES/PROBLEMS:
12
+
13
+ * forkify is _extremely_ beta quality currently.
14
+ * NOTE: Hash forkifing returns a 2-dimensional array.
15
+ * Spawn processes easily!
16
+
17
+ == SYNOPSIS:
18
+
19
+ enumerable = %w( a b c d )
20
+ enumerable.forkify(2) { 'process this block using two worker processes' }
21
+ enumerable.forkify { 'process this block using the default of 5 processes' }
22
+
23
+ == REQUIREMENTS:
24
+
25
+ * None
26
+
27
+ == INSTALL:
28
+
29
+ * sudo gem install forkify
30
+
31
+ == LICENSE:
32
+
33
+ (The MIT License)
34
+
35
+ Copyright (c) 2009 Lee Hinman
36
+
37
+ Permission is hereby granted, free of charge, to any person obtaining
38
+ a copy of this software and associated documentation files (the
39
+ 'Software'), to deal in the Software without restriction, including
40
+ without limitation the rights to use, copy, modify, merge, publish,
41
+ distribute, sublicense, and/or sell copies of the Software, and to
42
+ permit persons to whom the Software is furnished to do so, subject to
43
+ the following conditions:
44
+
45
+ The above copyright notice and this permission notice shall be
46
+ included in all copies or substantial portions of the Software.
47
+
48
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
49
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
50
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
51
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
52
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
53
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
54
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/forkify.rb'
6
+
7
+ FORKIFY_VERSION = "0.0.1"
8
+
9
+ Hoe.spec('forkify') do |p|
10
+ p.version = FORKIFY_VERSION
11
+ p.rubyforge_name = 'hinmanm'
12
+ p.developer('Lee Hinman', 'lee@writequit.org')
13
+ end
14
+
15
+ # vim: syntax=Ruby
data/examples/a.rb ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'forkify'
4
+
5
+ r = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].forkify(6) { |num|
6
+ puts num
7
+ sleep(1)
8
+ num * 2
9
+ }
10
+
11
+ puts "Results: #{r.inspect}"
12
+
13
+ # This should take a little longer than 2 seconds, instead of longer than 12
14
+ # It could be done faster by changing processes => 12 to run in ~1 second.
data/examples/b.rb ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'forkify'
4
+
5
+ r = { :a => 1, :b => 2, :c => 3 }.forkify { |k, v|
6
+ puts "#{k}, #{v}"
7
+ sleep(1)
8
+ [k, v]
9
+ }
10
+
11
+ puts "Results: #{r.inspect}"
12
+
13
+ # This should take a little longer than 1 second, rather than longer than 3 seconds.
data/lib/forkify.rb ADDED
@@ -0,0 +1,87 @@
1
+ #require 'pp'
2
+
3
+ module Enumerable
4
+ def forkify procs = 5, &block
5
+ #puts "Class: #{self.class}"
6
+ if Array === self
7
+ items = self
8
+ else
9
+ begin
10
+ items = self.to_a
11
+ rescue NoMethodError => e
12
+ raise NoMethodError, "Unable to coerce #{self.inspect} to an Array type."
13
+ end
14
+ end
15
+
16
+ results = []
17
+ offset = 0
18
+
19
+ items_remaining = items.size
20
+
21
+ while (items_remaining > 0) do
22
+ num_procs = procs
23
+ num_procs = items_remaining if items_remaining < procs
24
+
25
+ pids = []
26
+ wpipes = []
27
+ rpipes = []
28
+
29
+ num_procs.times do |i|
30
+ #puts "Fork # #{i}"
31
+ r, w = IO.pipe
32
+ #pp "r, w: #{r} #{w}"
33
+ wpipes << w
34
+ rpipes << r
35
+ pid = fork
36
+ unless pid
37
+ r.close
38
+ result =
39
+ begin
40
+ block.call(items[i + offset])
41
+ rescue Object => e
42
+ e
43
+ end
44
+ w.write( Marshal.dump( result ))
45
+ w.close
46
+ exit
47
+ end
48
+
49
+ pids << pid
50
+
51
+ end
52
+
53
+ offset += num_procs
54
+
55
+ #pp "Waiting for pids: #{pids}"
56
+ pids.each { |p| Process.waitpid(p) }
57
+
58
+ datawaiting_pipes = Kernel.select(rpipes, wpipes, nil, 2)
59
+ readwaiting_pipes = datawaiting_pipes[0]
60
+ writewaiting_pipes = datawaiting_pipes[1]
61
+ #pp "data: #{datawaiting_pipes}"
62
+ #pp "read: #{readwaiting_pipes}"
63
+ #pp "write: #{writewaiting_pipes}"
64
+ unless readwaiting_pipes.size != writewaiting_pipes.size
65
+ readwaiting_pipes.size.times do |i|
66
+ r = readwaiting_pipes[i]
67
+ w = writewaiting_pipes[i]
68
+ w.close
69
+ data = ''
70
+ while ( buf = r.read(8192) )
71
+ data << buf
72
+ end
73
+ result = Marshal.load( data )
74
+ r.close
75
+ results << result
76
+ end
77
+ end
78
+
79
+ items_remaining -= num_procs
80
+ end
81
+
82
+ return results
83
+ end
84
+
85
+ end
86
+
87
+
@@ -0,0 +1,18 @@
1
+ require "test/unit"
2
+ require "forkify"
3
+
4
+ class TestForkify < Test::Unit::TestCase
5
+ def test_timings
6
+ time1 = Time.now
7
+ r = [1, 2, 3].forkify(3) { |n| sleep(1) }
8
+ time2 = Time.now
9
+ # Assert that it took less than 3 seconds
10
+ assert (time2 - time1) < 3
11
+ end
12
+
13
+ def test_array_results_returned_correctly
14
+ r = [1, 2, 3].forkify { |n| n * 2 }
15
+ assert r == [2, 4, 6]
16
+ end
17
+
18
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: forkify
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Lee Hinman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-23 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.0.0
24
+ version:
25
+ description: |-
26
+ forkify.rb makes it easy to process a bunch of data using 'n'
27
+ worker processes. It is based off of forkoff and threadify by Ara Howard.
28
+ It aims to be safe to use on Ruby 1.8.6+ and Ruby 1.9.1+
29
+ email:
30
+ - lee@writequit.org
31
+ executables: []
32
+
33
+ extensions: []
34
+
35
+ extra_rdoc_files:
36
+ - History.txt
37
+ - Manifest.txt
38
+ - README.txt
39
+ files:
40
+ - History.txt
41
+ - Manifest.txt
42
+ - README.txt
43
+ - Rakefile
44
+ - lib/forkify.rb
45
+ - test/test_forkify.rb
46
+ - examples/a.rb
47
+ - examples/b.rb
48
+ has_rdoc: true
49
+ homepage: http://github.com/dakrone/forkify
50
+ licenses: []
51
+
52
+ post_install_message:
53
+ rdoc_options:
54
+ - --main
55
+ - README.txt
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ version:
70
+ requirements: []
71
+
72
+ rubyforge_project: hinmanm
73
+ rubygems_version: 1.3.4
74
+ signing_key:
75
+ specification_version: 3
76
+ summary: forkify.rb makes it easy to process a bunch of data using 'n' worker processes
77
+ test_files:
78
+ - test/test_forkify.rb