dakrone-forkify 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ === 0.0.1 / 2009-06-23
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
@@ -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
@@ -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.
@@ -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
10
+ version = FORKIFY_VERSION
11
+ developer('Lee Hinman', 'lee@writequit.org')
12
+ self.rubyforge_name = 'hinmanm'
13
+ end
14
+
15
+ # vim: syntax=Ruby
@@ -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.
@@ -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.
@@ -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 "testy"
2
+ require "forkify"
3
+
4
+ Testy.testing 'forkify' do
5
+ test 'timings' do |t|
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
+ less_than_3 = ((time2 - time1) < 3)
11
+ t.check :timing, :expect => true, :actual => less_than_3
12
+ end
13
+
14
+ test 'array results' do |t|
15
+ r = [1, 2, 3].forkify { |n| n * 2 }
16
+ t.check :array_results, :expect => [2, 4, 6], :actual => r
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dakrone-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 -07: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: forkify.rb makes it easy to process a bunch of data using 'n' worker processes. It is based off of forkoff and threadify by Ara Howard. It aims to be safe to use on Ruby 1.8.6+ and Ruby 1.9.1+
26
+ email:
27
+ - lee@writequit.org
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - History.txt
34
+ - Manifest.txt
35
+ - README.txt
36
+ files:
37
+ - History.txt
38
+ - Manifest.txt
39
+ - README.txt
40
+ - Rakefile
41
+ - lib/forkify.rb
42
+ - test/test_forkify.rb
43
+ - examples/a.rb
44
+ - examples/b.rb
45
+ has_rdoc: false
46
+ homepage: http://github.com/dakrone/forkify
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --main
50
+ - README.txt
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ requirements: []
66
+
67
+ rubyforge_project: writequit
68
+ rubygems_version: 1.2.0
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: forkify.rb makes it easy to process a bunch of data using 'n' worker processes
72
+ test_files:
73
+ - test/test_forkify.rb