Class: Cod::Pipe
Overview
A cod channel based on IO.pipe.
Note that if you embed Cod::Pipe channels into your messages, Cod will insert the object id of that channel into the byte stream that is transmitted. On receiving such an object id (a machine pointer), Cod will try to reconstruct the channel that was at the origin of the id. This can obviously only work if you have such an object in your address space. There are multiple ways to construct such a situation. Say you want to send a pipe channel to one of your (forked) childs: This will work if you create the channel before forking the child, since master and child will share all objects that were available before the fork.
Defined Under Namespace
Modules: SplitMethods
Instance Attribute Summary collapse
-
#pipe ⇒ Object
readonly
The underlying IOPair.
-
#serializer ⇒ Object
readonly
The serializer for this pipe.
Class Method Summary collapse
Instance Method Summary collapse
- #_dump(depth) ⇒ Object
-
#can_read? ⇒ Boolean
Returns true if you can read from this pipe.
-
#can_write? ⇒ Boolean
Returns true if you can write to this pipe.
-
#client(answers_to) ⇒ Cod::Service::Client
Produces a service client.
-
#close ⇒ void
Closes the pipe completely.
-
#get(opts = {}) ⇒ Object
Using #get on a pipe instance will close the other pipe end.
-
#initialize(serializer = nil, pipe_pair = nil) ⇒ Pipe
constructor
Creates a Pipe.
-
#initialize_copy(other) ⇒ Object
Creates a copy of this pipe channel.
-
#put(obj) ⇒ void
Using #put on a pipe instance will close the other pipe end.
-
#r ⇒ Object
Returns the read end of the pipe.
-
#readonly ⇒ Object
Makes this pipe readonly.
-
#select(timeout = nil) ⇒ Object
Returns if this pipe is ready for reading.
-
#service ⇒ Cod::Service
Produces a service using this pipe as service channel.
-
#split ⇒ Array<Cod::Channel>
Actively splits this pipe into two ends, a read end and a write end.
- #to_read_fds ⇒ Object
-
#w ⇒ Object
Returns the write end of the pipe.
-
#writeonly ⇒ Object
Makes this pipe writeonly.
Methods inherited from Channel
Constructor Details
#initialize(serializer = nil, pipe_pair = nil) ⇒ Pipe
Creates a Cod::Pipe.
36 37 38 39 40 |
# File 'lib/cod/pipe.rb', line 36 def initialize(serializer=nil, pipe_pair=nil) super() @serializer = serializer || SimpleSerializer.new @pipe = IOPair.new(*pipe_pair) end |
Instance Attribute Details
#pipe ⇒ Object (readonly)
The underlying IOPair.
18 19 20 |
# File 'lib/cod/pipe.rb', line 18 def pipe @pipe end |
#serializer ⇒ Object (readonly)
The serializer for this pipe.
21 22 23 |
# File 'lib/cod/pipe.rb', line 21 def serializer @serializer end |
Class Method Details
._load(string) ⇒ Object
210 211 212 |
# File 'lib/cod/pipe.rb', line 210 def self._load(string) # :nodoc: ObjectSpace._id2ref(Integer(string)) end |
Instance Method Details
#_dump(depth) ⇒ Object
205 206 207 |
# File 'lib/cod/pipe.rb', line 205 def _dump(depth) # :nodoc: object_id.to_s end |
#can_read? ⇒ Boolean
Returns true if you can read from this pipe.
153 154 155 |
# File 'lib/cod/pipe.rb', line 153 def can_read? not r.nil? end |
#can_write? ⇒ Boolean
Returns true if you can write to this pipe.
159 160 161 |
# File 'lib/cod/pipe.rb', line 159 def can_write? not pipe.w.nil? end |
#client(answers_to) ⇒ Cod::Service::Client
Produces a service client. Requests are sent to this channel, and answers are routed back to answers_to
.
198 199 200 |
# File 'lib/cod/pipe.rb', line 198 def client(answers_to) Service::Client.new(self, answers_to) end |
#close ⇒ void
This method returns an undefined value.
Closes the pipe completely. All active ends are closed. Note that you can call this function on a closed pipe without getting an error raised.
134 135 136 |
# File 'lib/cod/pipe.rb', line 134 def close pipe.close end |
#get(opts = {}) ⇒ Object
Using #get on a pipe instance will close the other pipe end. Subsequent #put will receive a Cod::InvalidOperation.
118 119 120 121 122 123 124 125 126 127 |
# File 'lib/cod/pipe.rb', line 118 def get(opts={}) raise Cod::WriteOnlyChannel unless can_read? pipe.close_w return deserialize_one rescue EOFError raise Cod::ConnectionLost, "All pipe ends seem to be closed. Reading from this pipe will not "+ "return any data." end |
#initialize_copy(other) ⇒ Object
Creates a copy of this pipe channel. This performs a shallow #dup except for the file descriptors stored in the pipe, so that a #close affects only one copy.
49 50 51 52 53 |
# File 'lib/cod/pipe.rb', line 49 def initialize_copy(other) super @serializer = other.serializer @pipe = other.pipe.dup end |
#put(obj) ⇒ void
This method returns an undefined value.
Using #put on a pipe instance will close the other pipe end. Subsequent #get will raise a Cod::InvalidOperation.
105 106 107 108 109 110 |
# File 'lib/cod/pipe.rb', line 105 def put(obj) raise Cod::ReadOnlyChannel unless can_write? pipe.write( serializer.en(obj)) end |
#r ⇒ Object
Returns the read end of the pipe
169 170 171 |
# File 'lib/cod/pipe.rb', line 169 def r pipe.r end |
#readonly ⇒ Object
Makes this pipe readonly. Calls to #put will error out. This closes the write end permanently and provokes end of file on the read end once all processes that posses a link to the write end do so.
Returns self so that you can write for example:
read_end = pipe.dup.readonly
64 65 66 67 |
# File 'lib/cod/pipe.rb', line 64 def readonly pipe.close_w self end |
#select(timeout = nil) ⇒ Object
Returns if this pipe is ready for reading.
140 141 142 143 |
# File 'lib/cod/pipe.rb', line 140 def select(timeout=nil) result = Cod.select(timeout, self) not result.nil? end |
#service ⇒ Cod::Service
Produces a service using this pipe as service channel.
188 189 190 |
# File 'lib/cod/pipe.rb', line 188 def service Service.new(self) end |
#split ⇒ Array<Cod::Channel>
88 89 90 91 92 93 94 |
# File 'lib/cod/pipe.rb', line 88 def split [self.dup.readonly, self.dup.writeonly].tap { |split| self.close split.extend(SplitMethods) } end |
#to_read_fds ⇒ Object
147 148 149 |
# File 'lib/cod/pipe.rb', line 147 def to_read_fds r end |
#w ⇒ Object
Returns the write end of the pipe
177 178 179 |
# File 'lib/cod/pipe.rb', line 177 def w pipe.w end |
#writeonly ⇒ Object
Makes this pipe writeonly. Calls to #get will error out. See #readonly.
Returns self so that you can write for example:
write_end = pipe.dup.writeonly
76 77 78 79 |
# File 'lib/cod/pipe.rb', line 76 def writeonly pipe.close_r self end |