piper 0.0.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/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in piper.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem "rspec"
8
+ end
9
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,4 @@
1
+ class Piper
2
+ VERSION = "0.0.1"
3
+ end
4
+
data/lib/piper.rb ADDED
@@ -0,0 +1,119 @@
1
+
2
+ class Piper
3
+ DestinyNotYetChosenException = Class.new(Exception)
4
+ CannotWriteToReaderException = Class.new(Exception)
5
+ CannotReadFromWriterException = Class.new(Exception)
6
+
7
+ def initialize
8
+ @readpipe, @writepipe = IO.pipe
9
+ end
10
+
11
+ def destiny_chosen?
12
+ !(@writer.nil? && @reader.nil?)
13
+ end
14
+
15
+ def writer!
16
+ if !destiny_chosen?
17
+ @writer = true
18
+ @readpipe.close
19
+ end
20
+ end
21
+
22
+ def reader!
23
+ if !destiny_chosen?
24
+ @reader = true
25
+ @writepipe.close
26
+ end
27
+ end
28
+
29
+ def writer?
30
+ !!@writer
31
+ end
32
+
33
+ def reader?
34
+ !!@reader
35
+ end
36
+
37
+ def <<(obj)
38
+ raise CannotWriteToReader if reader?
39
+
40
+ # Force writer
41
+ writer!
42
+
43
+ dump wrap(obj)
44
+ end
45
+
46
+ def close
47
+ dump :close => true if writer?
48
+ end
49
+
50
+ def load
51
+ raise CannotReadFromWriterException if writer?
52
+
53
+ # Force reader
54
+ reader!
55
+
56
+ Marshal.load(@readpipe)
57
+ end
58
+
59
+ def raw
60
+ raise DestinyNotYetChosenException if !destiny_chosen?
61
+
62
+ reader? ? @readpipe : @writepipe
63
+ end
64
+
65
+ protected
66
+
67
+ def dump(obj)
68
+ Marshal.dump(obj, @writepipe)
69
+ end
70
+
71
+ def wrap(obj)
72
+ {:object => obj}
73
+ end
74
+
75
+ class << self
76
+ def receive(*pipes)
77
+ open_pipes = [*pipes]
78
+
79
+ # Force all pipes to be readers
80
+ open_pipes.each {|p| p.reader! }
81
+
82
+ pipes_by_raw_read_pipe = {}
83
+ open_pipes.each do |p|
84
+ pipes_by_raw_read_pipe[p.raw] = p
85
+ end
86
+
87
+ loop do
88
+ ready = IO.select(open_pipes.map {|p| p.raw }, nil, nil, nil)
89
+
90
+ # Should always be ready, but if not, somehow it
91
+ # timed out. Throw error
92
+ if !ready
93
+ raise Exception
94
+ else
95
+ ready_pipes = ready[0].select {|p|
96
+ !p.eof?
97
+ }.map {|raw_pipe|
98
+ pipes_by_raw_read_pipe[raw_pipe]
99
+ }
100
+
101
+ ready_pipes.each do |pipe|
102
+ wrapper = pipe.load
103
+
104
+ if wrapper[:close]
105
+ pipes_by_raw_read_pipe.delete(pipe.raw)
106
+
107
+ open_pipes.delete(pipe)
108
+ return if open_pipes.empty?
109
+ else
110
+ object = wrapper.delete :object
111
+ yield(object)
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+
data/piper.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "piper/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "piper"
7
+ s.version = Piper::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Justin Camerer"]
10
+ s.email = ["iamjwc@gmail.com"]
11
+ s.homepage = "http://github.com/iamjwc/piper"
12
+ s.summary = %q{Wrapper around IO.pipe to allow easier communication between multiple processes.}
13
+ s.description = %q{Check the summary.}
14
+
15
+ s.rubyforge_project = "piper"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
@@ -0,0 +1,32 @@
1
+ require File.expand_path("../../spec_helper", __FILE__)
2
+
3
+ describe Piper do
4
+ it "should be able to send a message between two processes" do
5
+ send_to_child("hi").should == "hi"
6
+ end
7
+
8
+ it "should be able to send all different types of objects" do
9
+ send_to_child(:hey).should == :hey
10
+ send_to_child(1).should == 1
11
+ send_to_child(1.3).should == 1.3
12
+ send_to_child([1,2,3]).should == [1,2,3]
13
+ end
14
+
15
+ it "should use a special message when sending" do
16
+ send_to_child(:close).should == :close
17
+ end
18
+
19
+ def send_to_child(message)
20
+ p = Piper.new
21
+
22
+ if fork
23
+ m = nil
24
+ Piper.receive(p) {|message| m = message }
25
+ m
26
+ else
27
+ p << message
28
+ p.close
29
+ exit!
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,5 @@
1
+ Bundler.setup(:test)
2
+ require 'rspec'
3
+
4
+ require File.expand_path(File.dirname(__FILE__)+'/../lib/piper')
5
+
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: piper
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Justin Camerer
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-05-12 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Check the summary.
23
+ email:
24
+ - iamjwc@gmail.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - .gitignore
33
+ - .rspec
34
+ - Gemfile
35
+ - Rakefile
36
+ - lib/piper.rb
37
+ - lib/piper/version.rb
38
+ - piper.gemspec
39
+ - spec/lib/piper_spec.rb
40
+ - spec/spec_helper.rb
41
+ has_rdoc: true
42
+ homepage: http://github.com/iamjwc/piper
43
+ licenses: []
44
+
45
+ post_install_message:
46
+ rdoc_options: []
47
+
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ hash: 3
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ hash: 3
65
+ segments:
66
+ - 0
67
+ version: "0"
68
+ requirements: []
69
+
70
+ rubyforge_project: piper
71
+ rubygems_version: 1.4.2
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: Wrapper around IO.pipe to allow easier communication between multiple processes.
75
+ test_files:
76
+ - spec/lib/piper_spec.rb
77
+ - spec/spec_helper.rb