barney 0.7.0 → 0.8.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.
- data/ChangeLog +9 -0
- data/README.md +28 -61
- data/lib/barney/share.rb +42 -37
- data/lib/barney.rb +1 -1
- data/test/suite/lib/barney/share#history.rb +9 -7
- data/test/suite/lib/barney/share#initialize.rb +3 -1
- data/test/suite/lib/barney/share#synchronize.rb +15 -6
- data/test/suite/lib/barney/share#unshare.rb +2 -2
- metadata +2 -4
- data/test/suite/lib/barney/share#shared.rb +0 -11
data/ChangeLog
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
2011-04-19 Robert Gleeson <rob@flowof.info> v0.8.0
|
2
|
+
|
3
|
+
* Remove "seq" attribute from StreamPair.
|
4
|
+
* Banish @seq.
|
5
|
+
* Add HistoryItem (subclass of Struct).
|
6
|
+
* Share#history returns an Array of HistoryItem objects.
|
7
|
+
* Share#shared is deprecated. Use Shared#variables instead.
|
8
|
+
|
9
|
+
|
1
10
|
2011-03-14 Robert Gleeson <rob@flowof.info> v0.7.0
|
2
11
|
|
3
12
|
* Barney::Share#initialize yields a block.
|
data/README.md
CHANGED
@@ -1,87 +1,58 @@
|
|
1
1
|

|
2
2
|
|
3
3
|
Barney tries to make the sharing of data between processes as easy and **natural** as possible.
|
4
|
-
Barney is developed
|
4
|
+
Barney is developed to run on Ruby 1.9.1 or later, but it may work on earlier versions of Ruby as well.
|
5
5
|
|
6
|
-
##
|
7
|
-
Behind the scenes, Barney is using Marshal to send data between processes.
|
8
|
-
Any object that can be dumped through Marshal.dump can be shared.
|
9
|
-
This excludes anonymous modules, anonymous classes, Proc objects, and possibly some other objects I
|
10
|
-
cannot think of.
|
6
|
+
## Limitations
|
11
7
|
|
12
|
-
|
8
|
+
* Sharable objects
|
9
|
+
Behind the scenes, Barney is using Marshal to send data between processes.
|
10
|
+
Any object that can be dumped through Marshal.dump can be shared.
|
11
|
+
This excludes anonymous modules, anonymous classes, Proc objects, and possibly some other objects I
|
12
|
+
cannot think of.
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
* Thread safety
|
15
|
+
Barney is thread-safe as long as one instance of Barney::Share is used per-thread.
|
16
|
+
There is a mutex lock in place, but it only concerns Barney::Share#synchronize, where data is shared
|
17
|
+
among all instances of Barney::Share.
|
17
18
|
|
18
19
|
## Examples
|
19
20
|
|
20
|
-
Okay, now that we've got that out of the way, let's see what using Barney is like
|
21
|
+
Okay, now that we've got that out of the way, let's see what using Barney is like:
|
22
|
+
(The [Samples](https://github.com/robgleeson/barney/tree/develop/samples) directory has more examples …)
|
21
23
|
|
22
24
|
**Basic**
|
23
25
|
|
24
26
|
#!/usr/bin/env ruby
|
25
27
|
require 'barney'
|
26
28
|
|
27
|
-
message = 'foo'
|
28
|
-
$times = 2
|
29
29
|
|
30
30
|
obj = Barney::Share.new
|
31
|
-
obj.share :message
|
31
|
+
obj.share :message
|
32
|
+
message = 'Hello, '
|
33
|
+
|
32
34
|
pid = obj.fork do
|
33
|
-
message
|
34
|
-
$times += 1
|
35
|
+
message << 'World!'
|
35
36
|
end
|
36
37
|
|
37
38
|
Process.wait pid
|
38
39
|
obj.sync
|
39
40
|
|
40
|
-
puts message
|
41
|
-
|
42
|
-
**Sequential Jobs**
|
43
|
-
|
44
|
-
#!/usr/bin/env ruby
|
45
|
-
require 'barney'
|
46
|
-
|
47
|
-
a = "12"
|
48
|
-
|
49
|
-
obj = Barney::Share.new
|
50
|
-
obj.share :a
|
51
|
-
|
52
|
-
3.upto(4).each do |i|
|
53
|
-
pid = obj.fork { a << i.to_s }
|
54
|
-
Process.wait pid
|
55
|
-
obj.sync
|
56
|
-
end
|
57
|
-
|
58
|
-
a # => "1234"
|
59
|
-
|
60
|
-
**Paralell Jobs**
|
61
|
-
|
62
|
-
#/usr/bin/env ruby
|
63
|
-
require 'barney'
|
64
|
-
|
65
|
-
results = {}
|
66
|
-
pids = []
|
41
|
+
puts message # 'Hello, World!'
|
67
42
|
|
68
|
-
obj = Barney::Share.new
|
69
|
-
obj.share :results
|
70
43
|
|
71
|
-
|
72
|
-
pids << obj.fork do
|
73
|
-
results.merge!(e => e)
|
74
|
-
end
|
75
|
-
end
|
44
|
+
## Install
|
76
45
|
|
77
|
-
|
78
|
-
|
46
|
+
RubyGems.org
|
47
|
+
gem install barney
|
79
48
|
|
80
|
-
|
81
|
-
|
82
|
-
|
49
|
+
Github
|
50
|
+
git clone git://github.com/robgleeson/barney.git
|
51
|
+
cd barney
|
52
|
+
gem build *.gemspec
|
53
|
+
gem install *.gem
|
83
54
|
|
84
|
-
|
55
|
+
I'm following the [Semantic Versioning](http://www.semver.org) policy.
|
85
56
|
|
86
57
|
## Documentation
|
87
58
|
|
@@ -95,13 +66,9 @@ Okay, now that we've got that out of the way, let's see what using Barney is lik
|
|
95
66
|
* [0.4.0](http://rubydoc.info/gems/barney/0.4.0)
|
96
67
|
* …
|
97
68
|
|
69
|
+
|
98
70
|
## License
|
99
71
|
|
100
72
|
Barney is released under the Lesser GPL(LGPL).
|
101
73
|
|
102
|
-
## Install
|
103
|
-
|
104
|
-
gem install barney
|
105
74
|
|
106
|
-
The repository has a gemspec you can build and install from, too.
|
107
|
-
I'm following the [Semantic Versioning](http://www.semver.org) policy.
|
data/lib/barney/share.rb
CHANGED
@@ -2,21 +2,24 @@ module Barney
|
|
2
2
|
|
3
3
|
class Share
|
4
4
|
|
5
|
-
# @attr [Fixnum] seq The associated sequence number.
|
6
5
|
# @attr [IO] in The pipe which is used to read data.
|
7
6
|
# @attr [IO] out The pipe which is used to write data.
|
8
7
|
# @api private
|
9
|
-
StreamPair = Struct.new :
|
8
|
+
StreamPair = Struct.new :in, :out
|
9
|
+
|
10
|
+
# @attr [Symbol] variable The variable name.
|
11
|
+
# @attr [Object] value The value of the variable.
|
12
|
+
HistoryItem = Struct.new :variable, :value
|
10
13
|
|
11
14
|
@mutex = Mutex.new
|
12
15
|
|
13
16
|
class << self
|
14
|
-
#
|
17
|
+
# Returns the latest value read from a spawned child process.
|
15
18
|
# @api private
|
16
|
-
# @return [Object]
|
19
|
+
# @return [Object]
|
17
20
|
attr_accessor :value
|
18
21
|
|
19
|
-
#
|
22
|
+
# Returns a Mutex that is used when {Barney::Share.value Barney::Share.value} is being accessed by {Barney::Share#synchronize}
|
20
23
|
# @api private
|
21
24
|
# @return [Mutex]
|
22
25
|
attr_reader :mutex
|
@@ -24,23 +27,22 @@ module Barney
|
|
24
27
|
|
25
28
|
# Returns a list of all variables or constants being shared for this instance of {Barney::Share Barney::Share}.
|
26
29
|
# @return [Array<Symbol>]
|
27
|
-
attr_reader :
|
28
|
-
|
29
|
-
|
30
|
-
#
|
31
|
-
# @return [Fixnum] Returns the Process ID as a Fixnum.
|
30
|
+
attr_reader :variables
|
31
|
+
|
32
|
+
# Returns the Process ID of the last forked process.
|
33
|
+
# @return [Fixnum]
|
32
34
|
attr_reader :pid
|
33
35
|
|
34
|
-
#
|
35
|
-
# @return [{ Fixnum => { Symbol => Object }}] Fixnum represents sequence, Symbol the variable, and Object its value.
|
36
|
+
# @return [Array<HistoryItem>]
|
36
37
|
attr_reader :history
|
37
38
|
|
38
|
-
# @
|
39
|
+
# @yieldparam [Barney::Share] self Yields an instance of {Barney::Share}.
|
40
|
+
# @return [Barney::Share]
|
39
41
|
def initialize
|
40
|
-
@shared
|
41
|
-
@
|
42
|
-
@
|
43
|
-
@
|
42
|
+
@shared = Hash.new { |h,k| h[k] = [] }
|
43
|
+
@variables = []
|
44
|
+
@history = []
|
45
|
+
@context = nil
|
44
46
|
yield self if block_given?
|
45
47
|
end
|
46
48
|
|
@@ -48,22 +50,15 @@ module Barney
|
|
48
50
|
# @param [Symbol] Variable Accepts a variable amount of Symbol objects.
|
49
51
|
# @return [Array<Symbol>] Returns a list of all variables that are being shared.
|
50
52
|
def share *variables
|
51
|
-
variables.map(&:to_sym)
|
52
|
-
if (@shared[variable].nil?) || (not @shared[variable].find { |struct| struct.seq == @seq })
|
53
|
-
@shared.store variable, (@shared[variable] || []) << StreamPair.new(@seq, *IO.pipe)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
@shared.keys
|
53
|
+
@variables.push *variables.map(&:to_sym)
|
57
54
|
end
|
58
55
|
|
59
56
|
# Serves as a method to remove a variable or constant from being shared between two processes.
|
60
57
|
# @param [Symbol] Variable Accepts a variable amount of Symbol objects.
|
61
58
|
# @return [Array<Symbol>] Returns a list of the variables that are still being shared.
|
62
59
|
def unshare *variables
|
63
|
-
variables.map(&:to_sym).each
|
64
|
-
|
65
|
-
end
|
66
|
-
@shared.keys
|
60
|
+
variables.map(&:to_sym).each { |variable| @variables.delete variable }
|
61
|
+
@variables
|
67
62
|
end
|
68
63
|
|
69
64
|
# Serves as a method to spawn a new child process.
|
@@ -77,20 +72,19 @@ module Barney
|
|
77
72
|
# @return [Fixnum] Returns the Process ID(PID) of the spawned child process.
|
78
73
|
def fork &blk
|
79
74
|
raise ArgumentError, "A block or Proc object is expected" unless block_given?
|
80
|
-
|
75
|
+
spawn_pipes
|
81
76
|
|
82
77
|
@context = blk.binding
|
83
78
|
@pid = Kernel.fork do
|
84
79
|
blk.call
|
85
|
-
@shared.each do |variable,
|
86
|
-
stream =
|
80
|
+
@shared.each do |variable, history|
|
81
|
+
stream = history[-1]
|
87
82
|
stream.in.close
|
88
83
|
stream.out.write Marshal.dump(eval("#{variable}", @context))
|
89
84
|
stream.out.close
|
90
85
|
end
|
91
86
|
end
|
92
|
-
|
93
|
-
@seq += 1
|
87
|
+
|
94
88
|
@pid
|
95
89
|
end
|
96
90
|
|
@@ -99,20 +93,31 @@ module Barney
|
|
99
93
|
# @return [void]
|
100
94
|
def synchronize
|
101
95
|
Barney::Share.mutex.synchronize do
|
102
|
-
@shared.each do |variable,
|
103
|
-
|
96
|
+
@shared.each do |variable, history|
|
97
|
+
history.each do |stream|
|
104
98
|
stream.out.close
|
105
99
|
Barney::Share.value = Marshal.load stream.in.read
|
106
100
|
stream.in.close
|
107
|
-
|
108
|
-
@history
|
101
|
+
value = eval "#{variable} = Barney::Share.value", @context
|
102
|
+
@history.push HistoryItem.new variable.to_sym, value
|
109
103
|
end
|
110
|
-
array.clear
|
111
104
|
end
|
112
105
|
end
|
113
106
|
end
|
114
107
|
alias_method :sync, :synchronize
|
115
108
|
|
109
|
+
private
|
110
|
+
|
111
|
+
def spawn_pipes
|
112
|
+
@shared.keep_if do |variable|
|
113
|
+
@variables.member? variable
|
114
|
+
end
|
115
|
+
|
116
|
+
@variables.each do |variable|
|
117
|
+
@shared[variable].push StreamPair.new *IO.pipe
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
116
121
|
end
|
117
122
|
|
118
123
|
end
|
data/lib/barney.rb
CHANGED
@@ -1,19 +1,21 @@
|
|
1
1
|
describe Barney::Share do
|
2
2
|
describe '#history' do
|
3
3
|
|
4
|
-
it 'should
|
5
|
-
hash = {}
|
6
|
-
expected = { 0 => { :hash => { 1 => 1 } }, 1 => { :hash => { 2 => 2 } }, 2 => { :hash => { 3 => 3 } } }
|
4
|
+
it 'should provide the correct history.' do
|
7
5
|
object = Barney::Share.new
|
8
|
-
object.share :
|
6
|
+
object.share :shared
|
7
|
+
shared = ""
|
9
8
|
|
10
|
-
|
11
|
-
pid = object.fork {
|
9
|
+
%w(a b c).each do |e|
|
10
|
+
pid = object.fork { shared << e }
|
12
11
|
Process.wait pid
|
13
12
|
end
|
14
13
|
|
15
14
|
object.sync
|
16
|
-
|
15
|
+
|
16
|
+
history = object.history
|
17
|
+
assert_equal true, history.all? { |item| item.variable == :shared }
|
18
|
+
assert_equal "abc", history.map { |item| item.value }.join
|
17
19
|
end
|
18
20
|
|
19
21
|
end
|
@@ -51,22 +51,31 @@ describe Barney::Share do
|
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'should fix Github Issue #2' do
|
54
|
-
|
55
|
-
|
54
|
+
x = 4
|
55
|
+
y = 5
|
56
|
+
|
57
|
+
@object.share :x
|
56
58
|
@object.fork { }
|
57
59
|
Process.wait @object.pid
|
58
|
-
|
60
|
+
|
61
|
+
@object.share :y
|
59
62
|
@object.fork { b = 6 }
|
63
|
+
Process.wait @object.pid
|
64
|
+
|
60
65
|
@object.sync # will raise NoMethodError if fails.
|
61
66
|
end
|
62
67
|
|
63
68
|
it 'should fix GitHub Issue #3' do
|
64
|
-
|
65
|
-
|
69
|
+
x = 4
|
70
|
+
y = 5
|
71
|
+
|
72
|
+
@object.share :x, :y
|
66
73
|
@object.fork { }
|
67
74
|
Process.wait @object.pid
|
68
75
|
@object.sync
|
69
|
-
|
76
|
+
|
77
|
+
assert_equal 4, @object.history[0].value
|
78
|
+
assert_equal 5, @object.history[1].value
|
70
79
|
end
|
71
80
|
|
72
81
|
end
|
@@ -16,10 +16,10 @@ describe Barney::Share do
|
|
16
16
|
assert_equal 5, @a
|
17
17
|
end
|
18
18
|
|
19
|
-
it 'should confirm a shared variable is removed from #
|
19
|
+
it 'should confirm a shared variable is removed from #variables.' do
|
20
20
|
@object.share :@a
|
21
21
|
@object.unshare :@a
|
22
|
-
assert_equal true, @object.
|
22
|
+
assert_equal true, @object.variables.empty?
|
23
23
|
end
|
24
24
|
|
25
25
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: barney
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.8.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Robert Gleeson
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-04-19 00:00:00 +01:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -55,7 +55,6 @@ files:
|
|
55
55
|
- test/suite/lib/barney/share#fork.rb
|
56
56
|
- test/suite/lib/barney/share#history.rb
|
57
57
|
- test/suite/lib/barney/share#initialize.rb
|
58
|
-
- test/suite/lib/barney/share#shared.rb
|
59
58
|
- test/suite/lib/barney/share#synchronize.rb
|
60
59
|
- test/suite/lib/barney/share#unshare.rb
|
61
60
|
has_rdoc: true
|
@@ -90,6 +89,5 @@ test_files:
|
|
90
89
|
- test/suite/lib/barney/share#fork.rb
|
91
90
|
- test/suite/lib/barney/share#history.rb
|
92
91
|
- test/suite/lib/barney/share#initialize.rb
|
93
|
-
- test/suite/lib/barney/share#shared.rb
|
94
92
|
- test/suite/lib/barney/share#synchronize.rb
|
95
93
|
- test/suite/lib/barney/share#unshare.rb
|