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 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
  ![Barney Picture](http://ompldr.org/vNnUwNA)
2
2
 
3
3
  Barney tries to make the sharing of data between processes as easy and **natural** as possible.
4
- Barney is developed against Ruby 1.9.1 or later. I'm not knowingly supporting earlier versions of Ruby.
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
- ## Sharable objects
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
- ## Thread safety
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
- Barney is thread-safe as long as one instance of Barney::Share is used per-thread.
15
- There is a mutex lock in place, but it only concerns Barney::Share#synchronize, where data is shared
16
- among all instances of Barney::Share.
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, :$times
31
+ obj.share :message
32
+ message = 'Hello, '
33
+
32
34
  pid = obj.fork do
33
- message.sub! 'f', 'b'
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 * $times # output is 'boobooboo'.
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
- [1,2,3].each do |e|
72
- pids << obj.fork do
73
- results.merge!(e => e)
74
- end
75
- end
44
+ ## Install
76
45
 
77
- pids.each { |pid| Process.wait pid }
78
- obj.sync
46
+ RubyGems.org
47
+ gem install barney
79
48
 
80
- obj.history.each_value do |history|
81
- results.merge! history[:results]
82
- end
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
- puts results.inspect # => { 1 => 1, 2 => 2, 3 => 3 }
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 :seq, :in, :out
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
- # Serves as a temporary holder for the latest value read from the child process.
17
+ # Returns the latest value read from a spawned child process.
15
18
  # @api private
16
- # @return [Object] Returns Object or subclass of.
19
+ # @return [Object]
17
20
  attr_accessor :value
18
21
 
19
- # Serves as a lock when {Barney::Share.value Barney::Share.value} is being accessed by {Barney::Share#synchronize}
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 :shared
28
- def shared; @shared.keys; end
29
-
30
- # Serves as a method that tells you the Process ID of the last forked child process.
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
- # Serves as a method to provide a history of changes made in multiple forks for a single instance of {Barney::Share}.
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
- # @return [Barney::Share] Returns an instance of Barney::Share.
39
+ # @yieldparam [Barney::Share] self Yields an instance of {Barney::Share}.
40
+ # @return [Barney::Share]
39
41
  def initialize
40
- @shared = {}
41
- @history = {}
42
- @context = nil
43
- @seq = 0
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).each do |variable|
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 do |variable|
64
- @shared.delete variable
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
- share *@shared.keys if @pid
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, array|
86
- stream = array[-1]
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, array|
103
- array.each do |stream|
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
- object = eval "#{variable} = Barney::Share.value", @context
108
- @history[stream.seq] = (@history[stream.seq] || {}).merge!({ variable => object })
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,6 +1,6 @@
1
1
  require 'barney/share'
2
2
 
3
3
  module Barney
4
- VERSION = '0.7.0'
4
+ VERSION = '0.8.0'
5
5
  end
6
6
 
@@ -1,19 +1,21 @@
1
1
  describe Barney::Share do
2
2
  describe '#history' do
3
3
 
4
- it 'should confirm #history provides the correct history' do
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 :hash
6
+ object.share :shared
7
+ shared = ""
9
8
 
10
- [1,2,3].each do |e|
11
- pid = object.fork { hash.merge! e => e }
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
- assert_equal expected, object.history
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
@@ -2,7 +2,9 @@ describe Barney::Share do
2
2
  describe '#initialize' do
3
3
 
4
4
  it 'should take a block' do
5
- Barney::Share.new { |obj| }
5
+ actual = false
6
+ Barney::Share.new { |obj| actual = true }
7
+ assert_equal true, actual
6
8
  end
7
9
 
8
10
  end
@@ -51,22 +51,31 @@ describe Barney::Share do
51
51
  end
52
52
 
53
53
  it 'should fix Github Issue #2' do
54
- a,b = 4,5
55
- @object.share :a
54
+ x = 4
55
+ y = 5
56
+
57
+ @object.share :x
56
58
  @object.fork { }
57
59
  Process.wait @object.pid
58
- @object.share :b
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
- a,b = 4,5
65
- @object.share :a, :b
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
- assert_equal({ 0 => { :a => 4, :b => 5 } }, @object.history)
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 #shared.' do
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.shared.empty?
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.7.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-03-14 00:00:00 +00:00
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
@@ -1,11 +0,0 @@
1
- describe Barney::Share do
2
- describe '#shared' do
3
-
4
- it 'should return a list of shared variables' do
5
- obj = Barney::Share.new
6
- obj.share :a, :b, :c
7
- assert_equal true, [:a, :b, :c].all? { |variable| obj.shared.include? variable }
8
- end
9
-
10
- end
11
- end