comp_tree 0.5.2 → 0.7.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.
Files changed (56) hide show
  1. data/CHANGES +24 -0
  2. data/README +19 -52
  3. data/Rakefile +1 -138
  4. data/comp_tree.gemspec +33 -30
  5. data/install.rb +3 -3
  6. data/lib/comp_tree/algorithm.rb +117 -156
  7. data/lib/comp_tree/driver.rb +39 -154
  8. data/lib/comp_tree/error.rb +18 -23
  9. data/lib/comp_tree/node.rb +46 -50
  10. data/lib/comp_tree.rb +56 -0
  11. data/rakelib/jumpstart/ruby.rb +51 -0
  12. data/{contrib/quix/lib/quix → rakelib/jumpstart}/simple_installer.rb +11 -13
  13. data/test/common.rb +29 -0
  14. data/test/test_basic.rb +189 -0
  15. data/test/test_circular.rb +34 -31
  16. data/test/test_drain.rb +38 -0
  17. data/test/test_exception.rb +37 -86
  18. data/test/test_flood.rb +14 -0
  19. data/test/test_grind.rb +77 -0
  20. data/test/test_sequential.rb +21 -0
  21. metadata +45 -58
  22. data/contrib/quix/Rakefile +0 -16
  23. data/contrib/quix/install.rb +0 -3
  24. data/contrib/quix/lib/quix/builtin/dir/casefold_brackets.rb +0 -7
  25. data/contrib/quix/lib/quix/builtin/kernel/tap.rb +0 -9
  26. data/contrib/quix/lib/quix/builtin/module/include.rb +0 -21
  27. data/contrib/quix/lib/quix/builtin/module/private.rb +0 -41
  28. data/contrib/quix/lib/quix/config.rb +0 -37
  29. data/contrib/quix/lib/quix/cygwin.rb +0 -60
  30. data/contrib/quix/lib/quix/diagnostic.rb +0 -44
  31. data/contrib/quix/lib/quix/enumerable.rb +0 -33
  32. data/contrib/quix/lib/quix/fileutils.rb +0 -37
  33. data/contrib/quix/lib/quix/hash_struct.rb +0 -27
  34. data/contrib/quix/lib/quix/kernel.rb +0 -61
  35. data/contrib/quix/lib/quix/lazy_struct.rb +0 -55
  36. data/contrib/quix/lib/quix/string.rb +0 -38
  37. data/contrib/quix/lib/quix/subpackager.rb +0 -52
  38. data/contrib/quix/lib/quix/thread_local.rb +0 -32
  39. data/contrib/quix/lib/quix/vars.rb +0 -138
  40. data/contrib/quix/lib/quix.rb +0 -32
  41. data/contrib/quix/test/all.rb +0 -12
  42. data/contrib/quix/test/test_deps.rb +0 -25
  43. data/contrib/quix/test/test_include.rb +0 -47
  44. data/contrib/quix/test/test_private.rb +0 -86
  45. data/contrib/quix/test/test_root.rb +0 -19
  46. data/contrib/quix/test/test_struct.rb +0 -48
  47. data/contrib/quix/test/test_vars.rb +0 -187
  48. data/lib/comp_tree/bucket_ipc.rb +0 -151
  49. data/lib/comp_tree/diagnostic.rb +0 -44
  50. data/lib/comp_tree/misc.rb +0 -61
  51. data/lib/comp_tree/retriable_fork.rb +0 -42
  52. data/lib/comp_tree/tap.rb +0 -9
  53. data/lib/comp_tree/task_node.rb +0 -22
  54. data/test/all.rb +0 -12
  55. data/test/test_bucketipc.rb +0 -72
  56. data/test/test_comp_tree.rb +0 -364
@@ -1,151 +0,0 @@
1
-
2
- require 'drb'
3
- require 'thread'
4
-
5
- require 'comp_tree/retriable_fork'
6
- require 'comp_tree/diagnostic'
7
- require 'comp_tree/tap'
8
-
9
- module CompTree
10
- module BucketIPC
11
- class Bucket
12
- include Diagnostic
13
- include RetriableFork
14
-
15
- def initialize(address, timeout, wait_interval)
16
- trace "Making bucket with address #{address}"
17
-
18
- @remote_pid = fork {
19
- own_object = Class.new {
20
- attr_accessor(:contents)
21
- }.new
22
- server = DRb.start_service(address, own_object)
23
- debug {
24
- server.verbose = true
25
- }
26
- DRb.thread.join
27
- }
28
-
29
- @remote_object = DRbObject.new_with_uri(address)
30
- @address = address
31
- @timeout = timeout
32
- @wait_interval = wait_interval
33
- end
34
-
35
- attr_accessor(:timeout, :wait_interval)
36
- attr_reader(:address)
37
-
38
- def contents=(new_contents)
39
- connect {
40
- @remote_object.contents = new_contents
41
- }
42
- end
43
-
44
- def contents
45
- connect {
46
- @remote_object.contents
47
- }
48
- end
49
-
50
- def stop
51
- Process.kill("TERM", @remote_pid)
52
- end
53
-
54
- private
55
-
56
- def connect
57
- begin
58
- return yield
59
- rescue DRb::DRbConnError
60
- start = Time.now
61
- begin
62
- Kernel.sleep(@wait_interval)
63
- return yield
64
- rescue DRb::DRbConnError
65
- if Time.now - start > @timeout
66
- raise
67
- end
68
- retry
69
- end
70
- end
71
- end
72
- end
73
-
74
- class DriverBase
75
- def initialize(addresses, timeout, wait_interval)
76
- begin
77
- @buckets = addresses.map { |address|
78
- Bucket.new(address, timeout, wait_interval)
79
- }
80
- if block_given?
81
- yield @buckets
82
- end
83
- ensure
84
- if block_given?
85
- stop
86
- end
87
- end
88
- end
89
-
90
- def stop
91
- if defined?(@buckets)
92
- @buckets.each { |bucket|
93
- bucket.stop
94
- }
95
- end
96
- end
97
- end
98
-
99
- class Driver < DriverBase
100
- DEFAULTS = {
101
- :timeout => 0.5,
102
- :wait_interval => 0.05,
103
- :port_start => 18181,
104
- }
105
-
106
- module BucketCounter
107
- @mutex = Mutex.new
108
- @count = 0
109
- class << self
110
- def increment_count
111
- @mutex.synchronize {
112
- @count += 1
113
- }
114
- end
115
-
116
- def map_indexes(num_buckets)
117
- Array.new.tap { |result|
118
- num_buckets.times {
119
- result << yield(increment_count)
120
- }
121
- }
122
- end
123
- end
124
- end
125
-
126
- def initialize(num_buckets, opts_in = {})
127
- opts = DEFAULTS.merge(opts_in)
128
-
129
- addresses =
130
- if RetriableFork::HAVE_FORK
131
- #
132
- # Assume the existence of fork implies a unix machine.
133
- #
134
- require 'drb/unix'
135
- basename = "drbunix://#{Dir.tmpdir}/bucket.#{Process.pid}.#{rand}"
136
- BucketCounter.map_indexes(num_buckets) { |index|
137
- "#{basename}.#{index}"
138
- }
139
- else
140
- #
141
- # Fallback: use the default socket.
142
- #
143
- BucketCounter.map_indexes(num_buckets) { |index|
144
- "druby://localhost:#{opts[:port_start] + index}"
145
- }
146
- end
147
- super(addresses, opts[:timeout], opts[:wait_interval])
148
- end
149
- end
150
- end
151
- end
@@ -1,44 +0,0 @@
1
-
2
- require 'comp_tree/tap'
3
-
4
- module CompTree
5
- module Diagnostic
6
- def show(desc = nil, stream = STDOUT, &block)
7
- if desc
8
- stream.puts(desc)
9
- end
10
- if block
11
- expression = block.call
12
- eval(expression, block.binding).tap { |result|
13
- stream.printf("%-16s => %s\n", expression, result.inspect)
14
- }
15
- end
16
- end
17
-
18
- if $DEBUG
19
- def debug
20
- yield
21
- end
22
-
23
- def debugging?
24
- true
25
- end
26
-
27
- def trace(desc = nil, &block)
28
- if desc
29
- show("#{desc}.".sub(%r!\.\.+\Z!, ""), STDERR, &block)
30
- else
31
- show(nil, STDERR, &block)
32
- end
33
- end
34
- else
35
- # non-$DEBUG
36
- def debug ; end
37
- def debugging? ; end
38
- def trace(*args) ; end
39
- end
40
-
41
- extend self
42
- end
43
- end
44
-
@@ -1,61 +0,0 @@
1
-
2
- require 'thread'
3
-
4
- module CompTree
5
- module Misc
6
- def let
7
- yield self
8
- end
9
-
10
- def singleton_class
11
- class << self
12
- self
13
- end
14
- end
15
-
16
- module Gensym
17
- @mutex = Mutex.new
18
- @count = 0
19
-
20
- def gensym(prefix = nil)
21
- count = Gensym.module_eval {
22
- @mutex.synchronize {
23
- @count += 1
24
- }
25
- }
26
- "#{prefix || :G}_#{count}".to_sym
27
- end
28
- end
29
- include Gensym
30
-
31
- def call_private(method, *args, &block)
32
- instance_eval { send(method, *args, &block) }
33
- end
34
-
35
- def with_warnings(value = true)
36
- previous = $VERBOSE
37
- $VERBOSE = value
38
- begin
39
- yield
40
- ensure
41
- $VERBOSE = previous
42
- end
43
- end
44
-
45
- def no_warnings(&block)
46
- with_warnings(false, &block)
47
- end
48
-
49
- def abort_on_exception(value = true)
50
- previous = Thread.abort_on_exception
51
- Thread.abort_on_exception = value
52
- begin
53
- yield
54
- ensure
55
- Thread.abort_on_exception = previous
56
- end
57
- end
58
-
59
- extend self
60
- end
61
- end
@@ -1,42 +0,0 @@
1
-
2
- module CompTree
3
- module RetriableFork
4
- HAVE_FORK = lambda {
5
- begin
6
- process_id = fork { }
7
- Process.wait(process_id)
8
- rescue NotImplementedError
9
- return false
10
- end
11
- true
12
- }.call
13
-
14
- def fork(retry_wait = 10, retry_max = 10, &block)
15
- num_retries = 0
16
- begin
17
- Process.fork(&block)
18
- rescue Errno::EAGAIN
19
- num_retries += 1
20
- if num_retries == retry_max
21
- message = %Q{
22
- ****************************************************************
23
- Maximum number of EAGAIN signals reached (#{retry_max})
24
- ****************************************************************
25
-
26
- Either increase your process limit permission (consult your
27
- OS manual) or run this script as superuser.
28
-
29
- ****************************************************************
30
- }
31
- STDERR.puts(message.gsub(%r!^[ \t]+!, ""))
32
- raise
33
- end
34
- STDERR.puts "Caught EGAIN. Retrying in #{retry_wait} seconds."
35
- sleep(retry_wait)
36
- retry
37
- end
38
- end
39
- module_function :fork
40
- end
41
- end
42
-
data/lib/comp_tree/tap.rb DELETED
@@ -1,9 +0,0 @@
1
-
2
- unless respond_to? :tap
3
- module Kernel
4
- def tap
5
- yield self
6
- self
7
- end
8
- end
9
- end
@@ -1,22 +0,0 @@
1
-
2
- module CompTree
3
- #
4
- # TaskNode is a Node which discards its results
5
- #
6
- class TaskNode < Node
7
- def compute #:nodoc:
8
- @function.call
9
- true
10
- end
11
-
12
- class << self
13
- #
14
- # TaskNode always returns true.
15
- #
16
- def discard_result?
17
- true
18
- end
19
- end
20
- end
21
- end
22
-
data/test/all.rb DELETED
@@ -1,12 +0,0 @@
1
-
2
- require 'rbconfig'
3
-
4
- Dir["#{File.dirname(__FILE__)}/test_*.rb"].map { |file|
5
- File.expand_path(file)
6
- }.each { |file|
7
- # spawn separate processes to avoid EAGAIN signals on fork
8
- ruby = File.join(
9
- Config::CONFIG["bindir"],
10
- Config::CONFIG["RUBY_INSTALL_NAME"])
11
- system(ruby, file)
12
- }
@@ -1,72 +0,0 @@
1
-
2
- $LOAD_PATH.unshift(File.expand_path("#{File.dirname(__FILE__)}/../lib"))
3
-
4
- require 'test/unit'
5
- require 'comp_tree/bucket_ipc'
6
-
7
- Thread.abort_on_exception = true
8
-
9
- class BucketTest < Test::Unit::TestCase
10
- include CompTree::RetriableFork
11
-
12
- def each_bucket(num_buckets, &block)
13
- if HAVE_FORK
14
- CompTree::BucketIPC::Driver.new(num_buckets) { |buckets|
15
- buckets.each { |bucket|
16
- yield bucket
17
- }
18
- }
19
- end
20
- end
21
-
22
- def test_1_no_fork
23
- each_bucket(10) { |bucket|
24
- local = bucket.contents = :before
25
- bucket.contents = :after
26
- assert_equal(local, :before)
27
- assert_equal(bucket.contents, :after)
28
- }
29
- end
30
-
31
- def test_2_fork
32
- each_bucket(10) { |bucket|
33
- local = bucket.contents = :before
34
- process_id = fork {
35
- bucket.contents = :after
36
- }
37
- Process.wait(process_id)
38
- assert_equal(local, :before)
39
- assert_equal(bucket.contents, :after)
40
- }
41
- end
42
-
43
- def each_base_test
44
- [
45
- :test_1_no_fork,
46
- :test_2_fork,
47
- ].each { |method|
48
- yield method
49
- }
50
- end
51
-
52
- def test_3_thread
53
- each_base_test { |method|
54
- Thread.new {
55
- send(method)
56
- }.join
57
- }
58
- end
59
-
60
- def test_4_thread_flood
61
- each_base_test { |method|
62
- (0...10).map {
63
- Thread.new {
64
- send(method)
65
- }
66
- }.each { |thread|
67
- thread.join
68
- }
69
- }
70
- end
71
- end
72
-