abundance 1.2.4 → 1.2.5

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/lib/abundance.rb CHANGED
@@ -9,7 +9,7 @@
9
9
  #
10
10
  # And not:
11
11
  # * a replacement for Thread.new invocations
12
- # * a replacement for Thread friendly programming languages like Erlang
12
+ # * a replacement for concurrent programming languages like Erlang
13
13
  #
14
14
  # Its initial implementation uses:
15
15
  # * pure ruby
@@ -71,8 +71,8 @@ class Abundance
71
71
  # id1 = gardener.seed('command1')
72
72
  # id2 = gardener.seed('command2')
73
73
  #
74
- # result1 = gardener.harvest(id1)
75
- # result2 = gardener.harvest(id2)
74
+ # result1 = gardener.harvest(:one,id1)
75
+ # result2 = gardener.harvest(:one,id2)
76
76
  #
77
77
  # # with many more seeds over here
78
78
  #
data/lib/garden.rb CHANGED
@@ -15,7 +15,7 @@
15
15
  # :title:Garden
16
16
 
17
17
  class Garden
18
- require 'garden_rows'
18
+ require 'rows'
19
19
  require 'garden_cycles'
20
20
  include Cycles
21
21
  require 'toolshed'
@@ -52,12 +52,6 @@ class Garden
52
52
  report_growth(message_block)
53
53
  when :harvest
54
54
  harvest_some(message_block)
55
- when :init
56
- ask_for_init_status(message_block)
57
- when :init_crop
58
- answer_init_status(message_block)
59
- when :seed_all_crop
60
- special_crop_seed_all(message_block)
61
55
  when :close
62
56
  close_all(message_block)
63
57
  else
data/lib/garden_cycles.rb CHANGED
@@ -1,43 +1,43 @@
1
1
  class Garden
2
+ # The Cycles module is a set of method used by the Garden's fork.
3
+ # You will not need to use these methods unless you plan on refactoring the Garden.
4
+ #
2
5
  # Author:: lp (mailto:lp@spiralix.org)
3
6
  # Copyright:: 2008 Louis-Philippe Perron - Released under the terms of the MIT license
4
7
  # :title:Cycles
5
8
  module Cycles
6
9
 
7
10
  def set_my_containers
8
- @quit = false; @full_crop = false; @do_init = nil; @seed_all_message_block = nil; @init_all_crop = []
9
- @harvest = []; @rows_socket_paths = []; @init_done = []; @seed_all_done = []; @seed_all_crop = []
10
- @seeds = []; @sprouts = []; @crops = []; @id = 0
11
+ @close_message_block = nil; @full_crop_message_block = nil
12
+ @init_message_block = nil; @seed_all_message_block = nil
13
+ @harvest_queue = []; @waiting_rows = []; @id = 0
14
+ @seeds = []; @sprouts = []; @crops = []
11
15
  end
12
16
 
13
17
  def seed_if_row_available
14
18
  catch :fill_rows do
15
19
  loop do
16
- if ! @seed_all_message_block.nil? && ! @rows_socket_paths.empty? && @seed_all_done.size != @seed_all_message_block[1]
17
- row_socket_path = @rows_socket_paths.shift
18
- unless @seed_all_done.include?( row_socket_path )
20
+ if @seed_all_message_block && ! @waiting_rows.empty? && @seed_all_message_block[4][:row_done].size != @seed_all_message_block[1]
21
+ row_socket_path = @waiting_rows.shift
22
+ unless @seed_all_message_block[4][:row_done].include?( row_socket_path )
19
23
  socket_send([:seed,:all,@seed_all_message_block[2],row_socket_path])
20
- @seed_all_done << row_socket_path
24
+ @seed_all_message_block[4][:row_done] << row_socket_path
21
25
  else
22
- @rows_socket_paths << row_socket_path
26
+ @waiting_rows << row_socket_path
23
27
  end
24
- elsif ! @do_init.nil? && ! @rows_socket_paths.empty? && @init_done.size != @do_init
25
- row_socket_path = @rows_socket_paths.shift
26
- unless @init_done.include?( row_socket_path )
28
+ elsif @init_message_block && ! @waiting_rows.empty? && @init_message_block[4][:row_done].size != @init_message_block[2]
29
+ row_socket_path = @waiting_rows.shift
30
+ unless @init_message_block[4][:row_done].include?( row_socket_path )
27
31
  socket_send([:seed,:init,'init_status',row_socket_path])
28
- @init_done << row_socket_path
32
+ @init_message_block[4][:row_done] << row_socket_path
29
33
  else
30
- @rows_socket_paths << row_socket_path
34
+ @waiting_rows << row_socket_path
31
35
  end
32
- elsif ! @seeds.empty? && ! @rows_socket_paths.empty?
33
- seed = @seeds.shift
34
- @sprouts[seed[:id]] = seed
35
- row_socket_path = @rows_socket_paths.shift
36
- socket_send([:seed,:sprout,seed,row_socket_path])
37
- elsif @quit && ! @rows_socket_paths.empty?
38
- seed = nil
39
- row_socket_path = @rows_socket_paths.shift
40
- socket_send([:seed,:quit,seed,row_socket_path])
36
+ elsif ! @seeds.empty? && ! @waiting_rows.empty?
37
+ seed = @seeds.shift; @sprouts[seed[:id]] = seed
38
+ socket_send([:seed,:sprout,seed,@waiting_rows.shift])
39
+ elsif @close_message_block && ! @waiting_rows.empty?
40
+ socket_send([:seed,:quit,nil,@waiting_rows.shift])
41
41
  else
42
42
  throw :fill_rows
43
43
  end
@@ -49,23 +49,24 @@ class Garden
49
49
  case message_block[1]
50
50
  when :one
51
51
  @id += 1; @seeds << {:id => @id , :seed => message_block[2]}
52
- socket_send([message_block[0],:garden,@id,message_block[3]])
52
+ message_block[2] = @id; socket_send(message_block)
53
53
  else
54
54
  @seed_all_message_block = Array.new(message_block)
55
+ @seed_all_message_block[4] = {:row_done => [], :crops => []}
55
56
  end
56
57
  end
57
58
 
58
59
  def this_row_is_available(message_block)
59
- if @quit
60
+ if @close_message_block
60
61
  message_block = [:row, :quit, nil, message_block[3]]
61
- elsif ! @seed_all_message_block.nil? && @seed_all_done.size != @seed_all_message_block[1] && ! @seed_all_done.include?( message_block[3] )
62
+ elsif @seed_all_message_block && @seed_all_message_block[4][:row_done].size != @seed_all_message_block[1] && ! @seed_all_message_block[4][:row_done].include?( message_block[3] )
62
63
  message_block = [:row, :all, @seed_all_message_block[2], message_block[3]]
63
- @seed_all_done << message_block[3]
64
- elsif ! @do_init.nil? && @init_done.size != @do_init && ! @init_done.include?( message_block[3] )
64
+ @seed_all_message_block[4][:row_done] << message_block[3]
65
+ elsif @init_message_block && @init_message_block[4][:row_done].size != @init_message_block[2] && ! @init_message_block[4][:row_done].include?( message_block[3] )
65
66
  message_block = [:row, :init, 'init_status', message_block[3]]
66
- @init_done << message_block[3]
67
+ @init_message_block[4][:row_done] << message_block[3]
67
68
  elsif @seeds.empty?
68
- @rows_socket_paths << message_block[2]
69
+ @waiting_rows << message_block[2]
69
70
  message_block = [:row, :wait, nil, message_block[3]]
70
71
  else
71
72
  seed = @seeds.shift; @sprouts[seed[:id]] = seed
@@ -75,97 +76,95 @@ class Garden
75
76
  end
76
77
 
77
78
  def save_crop_for(message_block)
78
- @sprouts[message_block[2][:id]] = nil
79
- @crops[message_block[2][:id]] = message_block[2]
80
- if @harvest[message_block[2][:id]]
81
- socket_send([message_block[0],:garden,message_block[2], @harvest[message_block[2][:id]][:client_socket_path]])
82
- @crops[message_block[2][:id]] = @harvest[message_block[2][:id]] = nil
83
- elsif @full_crop && @seeds.compact.empty? && @sprouts.compact.empty?
84
- socket_send([message_block[0],:garden,@crops.compact,@mem_client_socket_path])
85
- @crops.clear; @full_crop = false
79
+ case message_block[1]
80
+ when :harvest
81
+ @sprouts[message_block[2][:id]] = nil
82
+ @crops[message_block[2][:id]] = message_block[2]
83
+ if @harvest_queue[message_block[2][:id]]
84
+ socket_send(message_block[0..2]+[@harvest_queue[message_block[2][:id]]])
85
+ @crops[message_block[2][:id]] = @harvest_queue[message_block[2][:id]] = nil
86
+ elsif @full_crop_message_block && @seeds.compact.empty? && @sprouts.compact.empty?
87
+ socket_send(message_block[0..1]+[@crops.compact,@full_crop_message_block[3]])
88
+ @crops.clear; @full_crop_message_block = nil
89
+ end
90
+ when :seed_all
91
+ @seed_all_message_block[4][:crops] << message_block[2]
92
+ if @seed_all_message_block[4][:crops].size == @seed_all_message_block[1]
93
+ @seed_all_message_block[2] = @seed_all_message_block[4][:crops]; @seed_all_message_block[4] = nil
94
+ socket_send(@seed_all_message_block.compact); @seed_all_message_block = nil
95
+ end
96
+ when :init
97
+ @init_message_block[4][:crops] << message_block[2]
98
+ if @init_message_block[4][:crops].size == @init_message_block[2]
99
+ @init_message_block[2] = @init_message_block[4][:crops]; @init_message_block[4] = nil
100
+ socket_send(@init_message_block.compact); @init_message_block = nil
101
+ end
86
102
  end
87
103
  end
88
104
 
89
105
  def report_growth(message_block)
90
- case message_block[2]
106
+ case message_block[1]
91
107
  when :progress
92
108
  value = @crops.size.to_f / (@crops.size + @sprouts.compact.size + @seeds.size)
93
109
  value = 1 if value.nan?; progress = sprintf( "%.2f", value)
94
- socket_send([message_block[0],:garden,progress,message_block[3]])
110
+ message_block[2] = progress
95
111
  when :seed
96
- socket_send([message_block[0],:garden,@seeds.size,message_block[3]])
112
+ message_block[2] = @seeds.size
97
113
  when :sprout
98
- socket_send([message_block[0],:garden,@sprouts.compact.size,message_block[3]])
114
+ message_block[2] = @sprouts.compact.size
99
115
  when :crop
100
- socket_send([message_block[0],:garden,@crops.size,message_block[3]])
116
+ message_block[2] = @crops.size
101
117
  else
102
- socket_send([message_block[0],:garden,false,message_block[3]])
118
+ message_block[2] = false
103
119
  end
120
+ socket_send(message_block)
104
121
  end
105
122
 
106
123
  def harvest_some(message_block)
107
- case message_block[2]
124
+ case message_block[1]
125
+ when :one
126
+ unless message_block[2].nil?
127
+ if @crops[message_block[2]]
128
+ socket_send(message_block[0..1]+[@crops[message_block[2]],message_block[3]])
129
+ @crops[message_block[2]] = nil
130
+ else
131
+ @harvest_queue[message_block[2]] = message_block[3]
132
+ end
133
+ else
134
+ message_block[2] = false; socket_send(message_block)
135
+ end
108
136
  when :all
109
- socket_send([message_block[0],:garden,{:seeds => @seeds, :sprouts => @sprouts.compact, :crops => @crops.compact},message_block[3]])
137
+ message_block[2] = {:seeds => @seeds, :sprouts => @sprouts.compact, :crops => @crops.compact}
138
+ socket_send(message_block)
110
139
  when :seed
111
- socket_send([message_block[0],:garden,@seeds,message_block[3]])
140
+ message_block[2] = @seeds; socket_send(message_block)
112
141
  when :sprout
113
- socket_send([message_block[0],:garden,@sprouts.compact,message_block[3]])
142
+ message_block[2] = @sprouts.compact; socket_send(message_block)
114
143
  when :crop
115
- socket_send([message_block[0],:garden,@crops.compact,message_block[3]])
116
- @crops.clear
144
+ message_block[2] = @crops.compact; socket_send(message_block); @crops.clear
117
145
  when :full_crop
118
146
  if @seeds.compact.empty? && @sprouts.compact.empty?
119
- socket_send([message_block[0],:garden,@crops.compact,message_block[3]])
120
- @crops.clear
147
+ message_block[2] = @crops.compact; socket_send(message_block); @crops.clear
121
148
  else
122
- @full_crop = true
123
- @mem_client_socket_path = message_block[3]
149
+ @full_crop_message_block = Array.new(message_block)
124
150
  end
151
+ when :init
152
+ @init_message_block = Array.new(message_block)
153
+ @init_message_block[4] = {:row_done => [], :crops => []}
125
154
  else
126
- if message_block[2].is_a? Integer
127
- if @crops[message_block[2]]
128
- socket_send([message_block[0],:garden,@crops[message_block[2]],message_block[3]])
129
- @crops[message_block[2]] = nil
130
- else
131
- @harvest[message_block[2]] = {:client_socket_path => message_block[3]}
132
- end
133
- else
134
- socket_send([message_block[0],:garden,false,message_block[3]])
135
- end
155
+ message_block[2] = false; socket_send(message_block)
136
156
  end
137
157
  end
138
-
139
- def ask_for_init_status(message_block)
140
- @do_init = message_block[2]
141
- @init_return = {:client_socket_path => message_block[3]}
142
- end
143
-
144
- def answer_init_status(message_block)
145
- @init_all_crop << message_block[2]
146
- if @init_all_crop.size == @do_init
147
- socket_send([message_block[0],:garden,@init_all_crop, @init_return[:client_socket_path]])
148
- @init_return = Hash.new; @init_done = Array.new; @do_init = nil; @init_all_crop = Array.new
149
- end
150
- end
151
-
152
- def special_crop_seed_all(message_block)
153
- @seed_all_crop << message_block[2]
154
- if @seed_all_crop.size == @seed_all_message_block[1]
155
- socket_send([message_block[0],:garden,@seed_all_crop, @seed_all_message_block[3]])
156
- @seed_all_message_block = nil; @seed_all_done = Array.new; @seed_all_crop = Array.new
157
- end
158
- end
159
-
158
+
160
159
  def close_all(message_block)
161
- if message_block[2][:level] == :garden
162
- @seeds_pid = message_block[2][:pid]
163
- @quit = true
164
- @mem_client_socket_path = message_block[3]
165
- else
166
- @seeds_pid.delete(message_block[2][:pid].to_i)
167
- if @seeds_pid.empty?
168
- socket_send([:close,:garden,{:seeds => @seeds, :sprouts => @sprouts.compact, :crops => @crops.compact}, @mem_client_socket_path])
160
+ case message_block[1]
161
+ when :garden
162
+ @close_message_block = Array.new(message_block)
163
+ when :row
164
+ @close_message_block[2].delete(message_block[2].to_i)
165
+ if @close_message_block[2].empty?
166
+ @close_message_block[2] = {:seeds => @seeds, :sprouts => @sprouts.compact, :crops => @crops.compact}
167
+ socket_send(@close_message_block)
169
168
  exit
170
169
  end
171
170
  end
data/lib/gardener.rb CHANGED
@@ -48,7 +48,7 @@ class Gardener
48
48
  # === Example
49
49
  # puts gardener.init_status.inspect # => [{:message=>"init ok", :success=>true, :pid=>4760}, {:message=>"init failed", :success=>false, :pid=>4761}]
50
50
  def init_status
51
- message_block = socket_duplex([:init,:gardener,@garden_rows.pids.size,@garden_path])
51
+ message_block = socket_duplex([:harvest,:init,@garden_rows.pids.size,@garden_path])
52
52
  message_block[2].map! do |row|
53
53
  {:success => row[:success], :message => row[:message], :pid => row[:id]}
54
54
  end
@@ -92,8 +92,8 @@ class Gardener
92
92
  # progress = gardener.growth(:progress)
93
93
  # puts "progress is now #{progress}" # => progress is now 0.75
94
94
 
95
- def growth(data=:progress)
96
- message_block = socket_duplex([:growth,:gardener,data,@garden_path])
95
+ def growth(option=:progress)
96
+ message_block = socket_duplex([:growth,option,nil,@garden_path])
97
97
  return message_block[2]
98
98
  end
99
99
 
@@ -101,18 +101,20 @@ class Gardener
101
101
  # It has two different behaviour on queue data, one for ripe elements where it removes them from crop array ( on _seedID_ and :crop invocations ),
102
102
  # for all other methods of invocation it leaves the queue intact.
103
103
  # === Parameter
104
- # The parameter given as a symbol specifies the level of queue results you wish to get:
105
- # * seedID = return the result for a specific seed, if seed hasn't processed it wait until completed, _seedID_ is removed from crop array
104
+ # The option given as a symbol specifies the level of queue results you wish to get:
106
105
  # * :crop = return an array of seed for which process has completed, empties the crop array.
107
106
  # * :sprout = return an array of seed actually processing
108
107
  # * :seed = return an array of seed waiting to be processed
109
108
  # * :all = return a hash of respective arrays for crops, sprouts and seeds
110
109
  # * :full_crop = wait for all seeds to be done processing, then returns as in :crop.
110
+ # * :one = return the result for a specific seed, if seed hasn't processed it wait until completed, _seed_id_ is removed from crop array
111
+ # When specifying :one as option, a seed ID is also required:
112
+ # * _seedID_ = the id as returned by the +seed+ method
111
113
  # === Example
112
- # seed1_result = gardener.harvest(id_seed_1)
114
+ # seed1_result = gardener.harvest(:one,id_seed_1)
113
115
 
114
- def harvest(data)
115
- message_block = socket_duplex([:harvest,:gardener,data,@garden_path])
116
+ def harvest(option,seed_id=nil)
117
+ message_block = socket_duplex([:harvest,option,seed_id,@garden_path])
116
118
  return message_block[2]
117
119
  end
118
120
 
@@ -122,7 +124,7 @@ class Gardener
122
124
  # final_harvest = gardener.close
123
125
 
124
126
  def close
125
- message_block = socket_duplex([:close,:gardener,{:level => :garden, :pid => @garden_rows.pids},@garden_path])
127
+ message_block = socket_duplex([:close,:garden,@garden_rows.pids,@garden_path])
126
128
  return message_block[2]
127
129
  end
128
130
 
@@ -20,6 +20,8 @@ class Garden
20
20
  # :title:Rows
21
21
 
22
22
  class Rows
23
+ require 'rows_paths'
24
+ include Paths
23
25
  require 'toolshed'
24
26
  include Toolshed
25
27
  attr_reader :pids
@@ -42,7 +44,6 @@ class Garden
42
44
  @pids = []
43
45
  rows.times do
44
46
  @pids << fork do
45
- @seed_all = false
46
47
  set_my_socket_as_a(:row,garden_pid)
47
48
  t1 = Thread.new do
48
49
  gardener_block.call
@@ -54,42 +55,28 @@ class Garden
54
55
  message_block = socket_duplex([:row,:row,my_socket_path,@garden_path])
55
56
  case message_block[1]
56
57
  when :sprout
57
- $seed = message_block[2]
58
+ sprout(message_block)
58
59
  when :all
59
- @seed_all = true
60
- $seed = {:id => Process.pid, :seed => message_block[2]}
60
+ all(message_block)
61
61
  when :wait
62
62
  message_block = socket_recv
63
63
  case message_block[1]
64
64
  when :sprout
65
- $seed = message_block[2]
65
+ sprout(message_block)
66
66
  when :all
67
- @seed_all = true
68
- $seed = {:id => Process.pid, :seed => message_block[2]}
67
+ all(message_block)
69
68
  when :init
70
- $init = {:seed => 'init_status', :message => 'No Init Message', :id => Process.pid} if $init.nil?
71
- socket_send([:init_crop,:row,$init,@garden_path])
69
+ init
72
70
  when :quit
73
- pid = Process.pid
74
- socket_send([:close,:row,{:level => :seed, :pid => pid},@garden_path])
75
- exit
71
+ quit
76
72
  end
77
73
  when :init
78
- $init = {:seed => 'init_status', :message => 'No Init Message', :id => Process.pid} if $init.nil?
79
- socket_send([:init_crop,:row,$init,@garden_path])
74
+ init
80
75
  when :quit
81
- pid = Process.pid
82
- socket_send([:close,:row,{:level => :seed, :pid => pid},@garden_path])
83
- exit
76
+ quit
84
77
  end
85
- elsif ! $seed[:success].nil?
86
- if @seed_all
87
- socket_send([:seed_all_crop,:row,$seed,@garden_path])
88
- @seed_all = false
89
- else
90
- socket_send([:crop,:row,$seed,@garden_path])
91
- end
92
- $seed = nil;
78
+ elsif $seed[:success]
79
+ crop
93
80
  else
94
81
  t1.run
95
82
  end
data/lib/rows_paths.rb ADDED
@@ -0,0 +1,40 @@
1
+ class Garden
2
+ class Rows
3
+ # The Paths module is a set of method used by the Rows's forks.
4
+ # You will not need to use these methods unless you plan on refactoring the Rows.
5
+ #
6
+ # Author:: lp (mailto:lp@spiralix.org)
7
+ # Copyright:: 2008 Louis-Philippe Perron - Released under the terms of the MIT license
8
+ # :title:Rows
9
+ module Paths
10
+
11
+ def all(message_block)
12
+ $seed = {:id => Process.pid, :seed => message_block[2], :all => true}
13
+ end
14
+
15
+ def crop
16
+ if $seed[:all]
17
+ socket_send([:crop,:seed_all,$seed,@garden_path])
18
+ else
19
+ socket_send([:crop,:harvest,$seed,@garden_path])
20
+ end
21
+ $seed = nil
22
+ end
23
+
24
+ def init
25
+ $init = {:seed => 'init_status', :message => 'No Init Message', :id => Process.pid} if $init.nil?
26
+ socket_send([:crop,:init,$init,@garden_path])
27
+ end
28
+
29
+ def quit
30
+ socket_send([:close,:row,Process.pid,@garden_path])
31
+ exit
32
+ end
33
+
34
+ def sprout(message_block)
35
+ $seed = message_block[2]
36
+ end
37
+
38
+ end
39
+ end
40
+ end
data/test/tc_high_api.rb CHANGED
@@ -69,7 +69,7 @@ class TestHighAPI < Test::Unit::TestCase
69
69
  id = @g.seed(Process.pid)
70
70
  assert_kind_of(Integer,id)
71
71
 
72
- answer = @g.harvest(id)
72
+ answer = @g.harvest(:one,id)
73
73
  assert_kind_of(Hash,answer)
74
74
  assert_equal(Process.pid,answer[:seed])
75
75
  assert_equal(id,answer[:id])
@@ -40,8 +40,8 @@ class TestHighAPI < Test::Unit::TestCase
40
40
  id1 = @g1.seed(Process.pid)
41
41
  id2 = @g2.seed(Process.pid)
42
42
 
43
- answer1 = @g1.harvest(id1)
44
- answer2 = @g2.harvest(id2)
43
+ answer1 = @g1.harvest(:one,id1)
44
+ answer2 = @g2.harvest(:one,id2)
45
45
 
46
46
  assert(answer1[:message] != answer2[:message])
47
47
  assert(answer1[:message] =~ /gardener1.*/)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abundance
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 1.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Louis-Philippe Perron
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-16 00:00:00 -05:00
12
+ date: 2009-01-18 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -25,8 +25,9 @@ files:
25
25
  - lib/abundance.rb
26
26
  - lib/garden.rb
27
27
  - lib/garden_cycles.rb
28
- - lib/garden_rows.rb
29
28
  - lib/gardener.rb
29
+ - lib/rows.rb
30
+ - lib/rows_paths.rb
30
31
  - lib/seed.rb
31
32
  - lib/toolshed.rb
32
33
  - test/tc_burst.rb