Class: Garden
Overview
These classes provides the garden part of the Gardener,Garden,Seed natural design patern
The Garden is where the thread concurency is implemented, offering itself as a thread queue manager, dispatching seeds from the Gardener to its Rows child class and back again. Since Ruby doesn’t implement Native Threads, and only Native Threads scales to multi-core execution, the way to implement concurent execution is through splitting the task at hand between multiple single threaded parallel executions. The Rows system does exactly that, using the Ruby fork function, then connecting the isolated running processes to the Garden, through a simple socket system provided by the Toolshed Module.
- Author
-
lp ([email protected])
- Copyright
-
2008 Louis-Philippe Perron - Released under the terms of the MIT license
:title:Garden
Defined Under Namespace
Classes: Rows
Constant Summary
Constants included from Toolshed
Instance Attribute Summary collapse
-
#pid ⇒ Object
readonly
Returns the value of attribute pid.
Instance Method Summary collapse
-
#initialize ⇒ Garden
constructor
The
new
class method initializes the Garden. -
#rows(rows, init_timeout, grow_block) ⇒ Object
The
rows
method for the Garden instance allow instantiation of its child Rows.
Methods included from Toolshed
available_port, block_size, block_size=, garden_port, garden_port=, socket_client_perm, #socket_client_perm_duplex, #socket_client_perm_send, socket_client_temp, #socket_client_temp, socket_server, #socket_server_recv, #socket_server_send
Constructor Details
#initialize ⇒ Garden
The new
class method initializes the Garden. As part of the Abundance lib, Garden is not initialized directly, but rather as a side effect of the Gardener’s initialization. Its instance resides in the @garden Gardener’s instance variable. Its real muscles are inaccessibles from instance method intervention, because of its nature as a forked Ruby process.
Example
garden = Garden.new
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/garden.rb', line 31 def initialize @pid = fork do @quit = false @harvest = [] @rows_port = [] @seeds = []; @sprouts = []; @crops = []; @id = 0 @socket_server = Toolshed.socket_server(Toolshed::garden_port) @socket_client_temp = Toolshed.socket_client_temp loop do catch :fill_rows do loop do if ! @seeds.empty? && ! @rows_port.empty? seed = @seeds.shift @sprouts[seed[:id]] = seed row_port = @rows_port.shift socket_client_temp(:sprout,seed,row_port) elsif @quit && ! @rows_port.empty? seed = nil row_port = @rows_port.shift socket_client_temp(:quit,seed,row_port) else throw :fill_rows end end end command, data, clientport, clientname, clientaddr = socket_server_recv case command when :seed @id += 1; @seeds << {:id => @id , :seed => data} socket_server_send(command,@id,clientaddr,clientport) when :row if @quit command = :quit seed = nil elsif @seeds.empty? seed = nil @rows_port << data else seed = @seeds.shift @sprouts[seed[:id]] = seed end socket_server_send(command,seed,clientaddr,clientport) when :crop @sprouts[data[:id]] = nil @crops[data[:id]] = data; socket_server_send(command,true,clientaddr,clientport) socket_server_send(command,data, @harvest[data[:id]][:clientaddr], @harvest[data[:id]][:clientport]) if @harvest[data[:id]] when :growth case data when :progress progress = sprintf( "%.2f", @crops.size.to_f / (@crops.size + @sprouts.compact.size + @seeds.size)) socket_server_send(command,progress,clientaddr,clientport) when :seed socket_server_send(command,@seeds.size,clientaddr,clientport) when :sprout socket_server_send(command,@sprouts.compact.size,clientaddr,clientport) when :crop socket_server_send(command,@crops.size,clientaddr,clientport) else socket_server_send(command,false,clientaddr,clientport) end when :harvest case data when :all socket_server_send(command,{:seeds => @seeds, :sprouts => @sprouts.compact, :crops => @crops},clientaddr,clientport) when :seed socket_server_send(command,@seeds,clientaddr,clientport) when :sprout socket_server_send(command,@sprouts.compact,clientaddr,clientport) when :crop socket_server_send(command,@crops,clientaddr,clientport) else if data.is_a? Integer if @crops[data] socket_server_send(command,@crops[data],clientaddr,clientport) else @harvest[data] = {:clientaddr => clientaddr, :clientport => clientport} end else socket_server_send(command,false,clientaddr,clientport) end end when :close if data[:level] == :garden @seeds_pid = data[:pid] @quit = true @mem_addr = clientaddr; @mem_port = clientport else @seeds_pid.delete(data[:pid].to_i) if @seeds_pid.empty? socket_server_send(:close,{:seeds => @seeds, :sprouts => @sprouts.compact, :crops => @crops}, @mem_addr, @mem_port) exit end end else socket_server_send(command,false,clientaddr,clientport) end end end return pid end |
Instance Attribute Details
#pid ⇒ Object (readonly)
Returns the value of attribute pid.
20 21 22 |
# File 'lib/garden.rb', line 20 def pid @pid end |
Instance Method Details
#rows(rows, init_timeout, grow_block) ⇒ Object
The rows
method for the Garden instance allow instantiation of its child Rows. As part of the Abundance lib, Garden.rows is not invoked directly, but rather as a side effect of the Gardener’s initialization. Its in reality an indirect initializer for the Rows class.
Parameter
-
rows = garden rows number, the number of concurent threads
-
init_timeout = allow to pause execution to allow for larger garden rows to initialize
Example
rows = garden.rows(4,2) { grow_block }
143 144 145 |
# File 'lib/garden.rb', line 143 def rows(rows,init_timeout,grow_block) Rows.new(rows,init_timeout,grow_block) end |