threadify 0.0.2

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.
data/README ADDED
@@ -0,0 +1,74 @@
1
+ NAME
2
+ threadify.rb
3
+
4
+
5
+ SYNOPSIS
6
+ enumerable = %w( a b c d )
7
+ enumerable.threadify(2){ 'process this block using two worker threads' }
8
+
9
+ DESCRIPTION
10
+ threadify.rb makes it stupid easy to process a bunch of data using 'n'
11
+ worker threads
12
+
13
+ INSTALL
14
+ gem install threadify
15
+
16
+ URI
17
+ http://rubyforge.org/projects/codeforpeople
18
+
19
+ SAMPLES
20
+
21
+ <========< sample/a.rb >========>
22
+
23
+ ~ > cat sample/a.rb
24
+
25
+ require 'open-uri'
26
+ require 'yaml'
27
+
28
+ require 'rubygems'
29
+ require 'threadify'
30
+
31
+
32
+ uris =
33
+ %w(
34
+ http://google.com
35
+ http://yahoo.com
36
+ http://rubyforge.org
37
+ http://ruby-lang.org
38
+ http://kcrw.org
39
+ http://drawohara.com
40
+ http://codeforpeople.com
41
+ )
42
+
43
+
44
+ time 'without threadify' do
45
+ uris.each do |uri|
46
+ body = open(uri){|pipe| pipe.read}
47
+ end
48
+ end
49
+
50
+
51
+ time 'with threadify' do
52
+ uris.threadify do |uri|
53
+ body = open(uri){|pipe| pipe.read}
54
+ end
55
+ end
56
+
57
+
58
+ BEGIN {
59
+ def time label
60
+ a = Time.now.to_f
61
+ yield
62
+ ensure
63
+ b = Time.now.to_f
64
+ y label => (b - a)
65
+ end
66
+ }
67
+
68
+ ~ > ruby sample/a.rb
69
+
70
+ ---
71
+ without threadify: 7.41900205612183
72
+ ---
73
+ with threadify: 3.69886112213135
74
+
@@ -0,0 +1,35 @@
1
+ lib, version = File::basename(File::dirname(File::expand_path(__FILE__))).split %r/-/, 2
2
+
3
+ require 'rubygems'
4
+
5
+ Gem::Specification::new do |spec|
6
+ $VERBOSE = nil
7
+
8
+ shiteless = lambda do |list|
9
+ list.delete_if do |file|
10
+ file =~ %r/\.svn/ or
11
+ file =~ %r/\.tmp/
12
+ end
13
+ end
14
+
15
+ spec.name = lib
16
+ spec.version = version
17
+ spec.platform = Gem::Platform::RUBY
18
+ spec.summary = lib
19
+
20
+ spec.files = shiteless[Dir::glob("**/**")]
21
+ spec.executables = shiteless[Dir::glob("bin/*")].map{|exe| File::basename exe}
22
+
23
+ spec.require_path = "lib"
24
+
25
+ spec.has_rdoc = File::exist? "doc"
26
+ spec.test_suite_file = "test/#{ lib }.rb" if File::directory? "test"
27
+ #spec.add_dependency 'lib', '>= version'
28
+
29
+ spec.extensions << "extconf.rb" if File::exists? "extconf.rb"
30
+
31
+ spec.rubyforge_project = 'codeforpeople'
32
+ spec.author = "Ara T. Howard"
33
+ spec.email = "ara.t.howard@gmail.com"
34
+ spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
35
+ end
@@ -0,0 +1,32 @@
1
+ require 'pathname'
2
+
3
+ $VERBOSE=nil
4
+
5
+ def indent s, n = 2
6
+ ws = ' ' * n
7
+ s.gsub %r/^/, ws
8
+ end
9
+
10
+ template = IO::read 'README.tmpl'
11
+
12
+ samples = ''
13
+ prompt = '~ > '
14
+
15
+ Dir['sample*/*'].sort.each do |sample|
16
+ samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
17
+
18
+ cmd = "cat #{ sample }"
19
+ samples << indent(prompt + cmd, 2) << "\n\n"
20
+ samples << indent(`#{ cmd }`, 4) << "\n"
21
+
22
+ cmd = "ruby #{ sample }"
23
+ samples << indent(prompt + cmd, 2) << "\n\n"
24
+
25
+ cmd = "ruby -Ilib #{ sample }"
26
+ samples << indent(`#{ cmd } 2>&1`, 4) << "\n"
27
+ end
28
+
29
+ #samples.gsub! %r/^/, ' '
30
+
31
+ readme = template.gsub %r/^\s*@samples\s*$/, samples
32
+ print readme
@@ -0,0 +1,214 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rbconfig'
3
+ require 'find'
4
+ require 'ftools'
5
+ require 'tempfile'
6
+ include Config
7
+
8
+ LIBDIR = "lib"
9
+ LIBDIR_MODE = 0644
10
+
11
+ BINDIR = "bin"
12
+ BINDIR_MODE = 0755
13
+
14
+
15
+ $srcdir = CONFIG["srcdir"]
16
+ $version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
17
+ $libdir = File.join(CONFIG["libdir"], "ruby", $version)
18
+ $archdir = File.join($libdir, CONFIG["arch"])
19
+ $site_libdir = $:.find {|x| x =~ /site_ruby$/}
20
+ $bindir = CONFIG["bindir"] || CONFIG['BINDIR']
21
+ $ruby_install_name = CONFIG['ruby_install_name'] || CONFIG['RUBY_INSTALL_NAME'] || 'ruby'
22
+ $ruby_ext = CONFIG['EXEEXT'] || ''
23
+ $ruby = File.join($bindir, ($ruby_install_name + $ruby_ext))
24
+
25
+ if !$site_libdir
26
+ $site_libdir = File.join($libdir, "site_ruby")
27
+ elsif $site_libdir !~ %r/#{Regexp.quote($version)}/
28
+ $site_libdir = File.join($site_libdir, $version)
29
+ end
30
+
31
+ def install_rb(srcdir=nil, destdir=nil, mode=nil, bin=nil)
32
+ #{{{
33
+ path = []
34
+ dir = []
35
+ Find.find(srcdir) do |f|
36
+ next unless FileTest.file?(f)
37
+ next if (f = f[srcdir.length+1..-1]) == nil
38
+ next if (/CVS$/ =~ File.dirname(f))
39
+ next if (/\.svn/ =~ File.dirname(f))
40
+ next if f =~ %r/\.lnk/
41
+ next if f =~ %r/\.svn/
42
+ next if f =~ %r/\.swp/
43
+ next if f =~ %r/\.svn/
44
+ path.push f
45
+ dir |= [File.dirname(f)]
46
+ end
47
+ for f in dir
48
+ next if f == "."
49
+ next if f == "CVS"
50
+ File::makedirs(File.join(destdir, f))
51
+ end
52
+ for f in path
53
+ next if (/\~$/ =~ f)
54
+ next if (/^\./ =~ File.basename(f))
55
+ unless bin
56
+ File::install(File.join(srcdir, f), File.join(destdir, f), mode, true)
57
+ else
58
+ from = File.join(srcdir, f)
59
+ to = File.join(destdir, f)
60
+ shebangify(from) do |sf|
61
+ $deferr.print from, " -> ", File::catname(from, to), "\n"
62
+ $deferr.printf "chmod %04o %s\n", mode, to
63
+ File::install(sf, to, mode, false)
64
+ end
65
+ end
66
+ end
67
+ #}}}
68
+ end
69
+ def shebangify f
70
+ #{{{
71
+ open(f) do |fd|
72
+ buf = fd.read 42
73
+ if buf =~ %r/^\s*#\s*!.*ruby/o
74
+ ftmp = Tempfile::new("#{ $$ }_#{ File::basename(f) }")
75
+ begin
76
+ fd.rewind
77
+ ftmp.puts "#!#{ $ruby }"
78
+ while((buf = fd.read(8192)))
79
+ ftmp.write buf
80
+ end
81
+ ftmp.close
82
+ yield ftmp.path
83
+ ensure
84
+ ftmp.close!
85
+ end
86
+ else
87
+ yield f
88
+ end
89
+ end
90
+ #}}}
91
+ end
92
+ def ARGV.switch
93
+ #{{{
94
+ return nil if self.empty?
95
+ arg = self.shift
96
+ return nil if arg == '--'
97
+ if arg =~ /^-(.)(.*)/
98
+ return arg if $1 == '-'
99
+ raise 'unknown switch "-"' if $2.index('-')
100
+ self.unshift "-#{$2}" if $2.size > 0
101
+ "-#{$1}"
102
+ else
103
+ self.unshift arg
104
+ nil
105
+ end
106
+ #}}}
107
+ end
108
+ def ARGV.req_arg
109
+ #{{{
110
+ self.shift || raise('missing argument')
111
+ #}}}
112
+ end
113
+ def linkify d, linked = []
114
+ #--{{{
115
+ if test ?d, d
116
+ versioned = Dir[ File::join(d, "*-[0-9].[0-9].[0-9].rb") ]
117
+ versioned.each do |v|
118
+ src, dst = v, v.gsub(%r/\-[\d\.]+\.rb$/, '.rb')
119
+ lnk = nil
120
+ begin
121
+ if test ?l, dst
122
+ lnk = "#{ dst }.lnk"
123
+ puts "#{ dst } -> #{ lnk }"
124
+ File::rename dst, lnk
125
+ end
126
+ unless test ?e, dst
127
+ puts "#{ src } -> #{ dst }"
128
+ File::copy src, dst
129
+ linked << dst
130
+ end
131
+ ensure
132
+ if lnk
133
+ at_exit do
134
+ puts "#{ lnk } -> #{ dst }"
135
+ File::rename lnk, dst
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
141
+ linked
142
+ #--}}}
143
+ end
144
+
145
+
146
+ #
147
+ # main program
148
+ #
149
+
150
+ libdir = $site_libdir
151
+ bindir = $bindir
152
+ no_linkify = false
153
+ linked = nil
154
+ help = false
155
+
156
+ usage = <<-usage
157
+ #{ File::basename $0 }
158
+ -d, --destdir <destdir>
159
+ -l, --libdir <libdir>
160
+ -b, --bindir <bindir>
161
+ -r, --ruby <ruby>
162
+ -n, --no_linkify
163
+ -s, --sudo
164
+ -h, --help
165
+ usage
166
+
167
+ begin
168
+ while switch = ARGV.switch
169
+ case switch
170
+ when '-d', '--destdir'
171
+ libdir = ARGV.req_arg
172
+ when '-l', '--libdir'
173
+ libdir = ARGV.req_arg
174
+ when '-b', '--bindir'
175
+ bindir = ARGV.req_arg
176
+ when '-r', '--ruby'
177
+ $ruby = ARGV.req_arg
178
+ when '-n', '--no_linkify'
179
+ no_linkify = true
180
+ when '-s', '--sudo'
181
+ sudo = 'sudo'
182
+ when '-h', '--help'
183
+ help = true
184
+ else
185
+ raise "unknown switch #{switch.dump}"
186
+ end
187
+ end
188
+ rescue
189
+ STDERR.puts $!.to_s
190
+ STDERR.puts usage
191
+ exit 1
192
+ end
193
+
194
+ if help
195
+ STDOUT.puts usage
196
+ exit
197
+ end
198
+
199
+ system "#{ sudo } #{ $ruby } pre-install.rb" if test(?s, 'pre-install.rb')
200
+
201
+ unless no_linkify
202
+ linked = linkify('lib') + linkify('bin')
203
+ end
204
+
205
+ system "#{ $ruby } extconf.rb && make && #{ sudo } make install" if test(?s, 'extconf.rb')
206
+
207
+ install_rb(LIBDIR, libdir, LIBDIR_MODE)
208
+ install_rb(BINDIR, bindir, BINDIR_MODE, bin=true)
209
+
210
+ if linked
211
+ linked.each{|path| File::rm_f path}
212
+ end
213
+
214
+ system "#{ sudo } #{ $ruby } post-install.rb" if test(?s, 'post-install.rb')
@@ -0,0 +1,94 @@
1
+ module Threadify
2
+ VERSION = '0.0.2'
3
+ def Threadify.version() Threadify::VERSION end
4
+
5
+ require 'thread'
6
+
7
+ @threads = 8
8
+ @abort_on_exception = true
9
+
10
+ class << self
11
+ attr_accessor :threads
12
+ attr_accessor :abort_on_exception
13
+ end
14
+ end
15
+
16
+ module Enumerable
17
+ def threadify opts = {}, &block
18
+ # setup
19
+ #
20
+ opts = {:threads => opts} if Numeric === opts
21
+ threads = Integer(opts[:threads] || opts['threads'] || Threadify.threads)
22
+ done = Object.new.freeze
23
+ jobs = Queue.new
24
+
25
+ # produce jobs
26
+ #
27
+ each_with_index{|elem, i| jobs.push [elem, i]}
28
+ threads.times{ jobs.push done} # mark the end
29
+
30
+ # fire off consumers
31
+ #
32
+ consumers = Array.new threads
33
+
34
+ threads.times do |i|
35
+ consumers[i] = Thread.new do
36
+ this = Thread.current
37
+ this.abort_on_exception = Threadify.abort_on_exception
38
+ loop{
39
+ job = jobs.pop
40
+ break if job == done
41
+ args = job.first
42
+ jobs << (job << block.call(*args))
43
+ }
44
+ end
45
+ end
46
+
47
+ # wait for consumers to finish
48
+ #
49
+ consumers.map{|t| t.join}
50
+
51
+ # collect the results and return them
52
+ #
53
+ jobs.push done
54
+ ret = []
55
+ while((job = jobs.pop) != done)
56
+ elem, i, value = job
57
+ ret[i] = value
58
+ end
59
+ ret
60
+ end
61
+ end
62
+
63
+ class Thread
64
+ def Thread.ify enumerable, *args, &block
65
+ enumerable.send :threadify, *args, &block
66
+ end
67
+ end
68
+
69
+
70
+ if __FILE__ == $0
71
+ require 'open-uri'
72
+ require 'yaml'
73
+
74
+ uris = %w( http://google.com http://yahoo.com http://rubyforge.org/ http://ruby-lang.org)
75
+
76
+ Thread.ify uris, :threads => 3 do |uri|
77
+ body = open(uri){|pipe| pipe.read}
78
+ y uri => body.size
79
+ end
80
+ end
81
+
82
+
83
+ __END__
84
+
85
+ sample output
86
+
87
+ ---
88
+ http://yahoo.com: 9562
89
+ ---
90
+ http://google.com: 6290
91
+ ---
92
+ http://rubyforge.org/: 22352
93
+ ---
94
+ http://ruby-lang.org: 9984
@@ -0,0 +1,42 @@
1
+ require 'open-uri'
2
+ require 'yaml'
3
+
4
+ require 'rubygems'
5
+ require 'threadify'
6
+
7
+
8
+ uris =
9
+ %w(
10
+ http://google.com
11
+ http://yahoo.com
12
+ http://rubyforge.org
13
+ http://ruby-lang.org
14
+ http://kcrw.org
15
+ http://drawohara.com
16
+ http://codeforpeople.com
17
+ )
18
+
19
+
20
+ time 'without threadify' do
21
+ uris.each do |uri|
22
+ body = open(uri){|pipe| pipe.read}
23
+ end
24
+ end
25
+
26
+
27
+ time 'with threadify' do
28
+ uris.threadify do |uri|
29
+ body = open(uri){|pipe| pipe.read}
30
+ end
31
+ end
32
+
33
+
34
+ BEGIN {
35
+ def time label
36
+ a = Time.now.to_f
37
+ yield
38
+ ensure
39
+ b = Time.now.to_f
40
+ y label => (b - a)
41
+ end
42
+ }
File without changes
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: threadify
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Ara T. Howard
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-07-01 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: ara.t.howard@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - gemspec.rb
26
+ - gen_readme.rb
27
+ - install.rb
28
+ - lib
29
+ - lib/threadify.rb
30
+ - README
31
+ - sample
32
+ - sample/a.rb
33
+ - threadify-0.0.2.gem
34
+ has_rdoc: false
35
+ homepage: http://codeforpeople.com/lib/ruby/threadify/
36
+ post_install_message:
37
+ rdoc_options: []
38
+
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ requirements: []
54
+
55
+ rubyforge_project: codeforpeople
56
+ rubygems_version: 1.0.1
57
+ signing_key:
58
+ specification_version: 2
59
+ summary: threadify
60
+ test_files: []
61
+