abundance 1.2.0 → 1.2.1
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/toolshed.rb +47 -16
- data/test/tc_multi_gardener.rb +50 -0
- data/test/ts_abundance.rb +2 -1
- metadata +3 -2
data/lib/toolshed.rb
CHANGED
@@ -10,67 +10,93 @@
|
|
10
10
|
#
|
11
11
|
# :title:Toolshed
|
12
12
|
|
13
|
-
# TODO:
|
14
|
-
# -dedicated server on garden for 'ready!' rows where rows go write their PID
|
15
|
-
|
16
13
|
module Toolshed
|
17
14
|
require 'ftools'
|
18
15
|
require 'socket'
|
19
16
|
SOCKET_ROOT = '/tmp/abundance/'
|
20
17
|
Dir.mkdir(SOCKET_ROOT) unless File.exist?(SOCKET_ROOT)
|
21
18
|
|
22
|
-
# The Toolshed::block_size= method sets the
|
19
|
+
# The Toolshed::block_size= method sets the Socket block size for UNIXSocket operations.
|
20
|
+
# === Parameters
|
21
|
+
# * _block_size_ = the block size in bytes
|
23
22
|
def Toolshed::block_size=(block_size)
|
24
23
|
@@block_size = block_size
|
25
24
|
end
|
26
25
|
|
27
|
-
# The +
|
28
|
-
|
26
|
+
# The +set_my_socket_as_a+ method sets a UNIXServer socket as an instance variable for the calling object in a role based fashion.
|
27
|
+
# When the specified role is not a :garden, the Garden's socket path is also stored as an instance variable for the calling object.
|
28
|
+
# === Parameters
|
29
|
+
# * _role_ = the role for which you wish to establish the socket
|
30
|
+
# * _garden_pid_ = the garden pid that will become the basename for the garden socket. No need to specify this argument when _role_ is :garden.
|
29
31
|
def set_my_socket_as_a(role,garden_pid=Process.pid)
|
30
32
|
case role
|
31
33
|
when :garden
|
32
|
-
set_my_socket
|
34
|
+
set_my_socket(Process.pid.to_s)
|
35
|
+
when :gardener
|
36
|
+
set_garden_path(garden_pid)
|
37
|
+
set_my_socket(Process.pid.to_s + Time.now.to_i.to_s + rand(10000).to_s)
|
33
38
|
else
|
34
39
|
set_garden_path(garden_pid)
|
35
|
-
set_my_socket
|
40
|
+
set_my_socket(Process.pid.to_s)
|
36
41
|
end
|
37
42
|
end
|
38
43
|
|
44
|
+
# The +my_socket_path+ method act as an attribute reader for the @my_socket_path instance variable of the calling object.
|
39
45
|
def my_socket_path
|
40
46
|
@my_socket_path
|
41
47
|
end
|
42
48
|
|
43
|
-
#
|
44
|
-
|
49
|
+
# The +socket_send+ method open a UNIXSocket and send packets to a UNIXServer socket.
|
50
|
+
# When the _server_socket_path_ is not specified, it defaults sending to the Garden UNIXServer.
|
51
|
+
# === Parameters
|
52
|
+
# * _command_ = command part of the sent packet
|
53
|
+
# * _data_ = data part of the sent packet
|
54
|
+
# * _server_socket_path_ = a UNIXServer socket path for the packets to be sent to
|
45
55
|
def socket_send(command,data,server_socket_path=@garden_path)
|
46
56
|
send_block(command,data,server_socket_path)
|
47
57
|
end
|
48
58
|
|
59
|
+
# The +socket_duplex+ method open a UNIXSocket and send packets to a UNIXServer socket, then wait for loopback communication from destination and return results like +socket_recv+.
|
60
|
+
# === Parameters
|
61
|
+
# * _command_ = command part of the sent packet
|
62
|
+
# * _data_ = data part of the sent packet
|
63
|
+
# * _server_socket_path_ = a UNIXServer socket path for the packets to be sent to
|
49
64
|
def socket_duplex(command,data,server_socket_path=@garden_path)
|
50
65
|
send_block(command,data,server_socket_path)
|
51
66
|
Marshal.load(recv_whole_block)
|
52
67
|
end
|
53
|
-
|
68
|
+
|
69
|
+
# The +socket_recv+ method calls _accept_ on a UNIXServer socket, receives all the packets from a UNIXSocket sender, join the packets back as the original block message.
|
54
70
|
def socket_recv
|
55
71
|
Marshal.load(recv_whole_block)
|
56
72
|
end
|
57
73
|
|
58
74
|
private
|
59
75
|
|
60
|
-
|
61
|
-
|
76
|
+
# The +socket_path+ method takes a _socket_name_ as argument and returns the absolute path to this socket.
|
77
|
+
# === Parameters
|
78
|
+
# * _socket_name_ = the socket file name
|
79
|
+
def socket_path(socket_name)
|
80
|
+
File.catname(socket_name,SOCKET_ROOT)
|
62
81
|
end
|
63
82
|
|
64
|
-
|
65
|
-
|
83
|
+
# The +set_my_socket+ method stores a UNIXServer socket inside @my_socket instance variable and also stores this socket path inside @my_socket_path.
|
84
|
+
# === Parameters
|
85
|
+
# * _socket_name_ = the socket file name
|
86
|
+
def set_my_socket(socket_name)
|
87
|
+
@my_socket_path = socket_path(socket_name)
|
66
88
|
File.delete(@my_socket_path) if File.exist?(@my_socket_path)
|
67
89
|
@my_socket = UNIXServer.open(@my_socket_path)
|
68
90
|
end
|
69
91
|
|
92
|
+
# The +set_garden_path+ method stores the Garden's UNIXServer socket path inside @garden_path.
|
93
|
+
# === Parameters
|
94
|
+
# * _garden_pid_ = the Garden process pid
|
70
95
|
def set_garden_path(garden_pid)
|
71
|
-
@garden_path = socket_path(garden_pid)
|
96
|
+
@garden_path = socket_path(garden_pid.to_s)
|
72
97
|
end
|
73
98
|
|
99
|
+
# The +recv_whole_block+ method loops receiving a sent block as packets, rebuilding the whole block and joining it.
|
74
100
|
def recv_whole_block
|
75
101
|
begin
|
76
102
|
client = @my_socket.accept; block = []
|
@@ -90,6 +116,11 @@ module Toolshed
|
|
90
116
|
end
|
91
117
|
end
|
92
118
|
|
119
|
+
# The +send_block+ method sends a block to a server socket.
|
120
|
+
# === Parameters
|
121
|
+
# * _command_ = command part of the sent packet
|
122
|
+
# * _data_ = data part of the sent packet
|
123
|
+
# * _server_socket_path_ = the UNIXServer socket path to send to
|
93
124
|
def send_block(command,data,server_socket_path)
|
94
125
|
begin
|
95
126
|
client = UNIXSocket.open(server_socket_path)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
require 'test/unit'
|
3
|
+
require 'abundance'
|
4
|
+
|
5
|
+
class TestHighAPI < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test_two_gardeners
|
8
|
+
@rows = 2
|
9
|
+
set_gardener1
|
10
|
+
set_gardener2
|
11
|
+
check_both_gardener
|
12
|
+
end
|
13
|
+
|
14
|
+
def teardown
|
15
|
+
@g1.close
|
16
|
+
@g2.close
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def set_gardener1
|
22
|
+
@g1 = Abundance.gardener(:wheelbarrow => 128, :rows => @rows, :init_timeout => 3) do
|
23
|
+
Abundance.init_status(true,Process.pid)
|
24
|
+
Abundance.grow do |seed|
|
25
|
+
seed.crop(true, "gardener1: #{seed.sprout}")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def set_gardener2
|
31
|
+
@g2 = Abundance.gardener(:wheelbarrow => 128, :rows => @rows, :init_timeout => 3) do
|
32
|
+
Abundance.init_status(true,Process.pid)
|
33
|
+
Abundance.grow do |seed|
|
34
|
+
seed.crop(true, "gardener2: #{seed.sprout}")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def check_both_gardener
|
40
|
+
id1 = @g1.seed(Process.pid)
|
41
|
+
id2 = @g2.seed(Process.pid)
|
42
|
+
|
43
|
+
answer1 = @g1.harvest(id1)
|
44
|
+
answer2 = @g2.harvest(id2)
|
45
|
+
|
46
|
+
assert(answer1[:message] =~ /gardener1.*/)
|
47
|
+
assert(answer2[:message] =~ /gardener2.*/)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
data/test/ts_abundance.rb
CHANGED
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
|
+
version: 1.2.1
|
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-
|
12
|
+
date: 2009-01-12 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -28,6 +28,7 @@ files:
|
|
28
28
|
- lib/seed.rb
|
29
29
|
- lib/toolshed.rb
|
30
30
|
- test/tc_high_api.rb
|
31
|
+
- test/tc_multi_gardener.rb
|
31
32
|
- test/tc_robustness.rb
|
32
33
|
- test/ts_abundance.rb
|
33
34
|
has_rdoc: true
|