threadify 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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
+