Class: QuartzTorrent::IoFacade
- Inherits:
-
Object
- Object
- QuartzTorrent::IoFacade
- Defined in:
- lib/quartz_torrent/reactor.rb
Overview
This class provides a facade for an IO object. The read method on this object acts as a blocking read. Internally it reads nonblockingly and passes processing to other ready sockets if this socket would block.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#logger ⇒ Object
Returns the value of attribute logger.
Instance Method Summary collapse
-
#close ⇒ Object
Close the io.
-
#closed? ⇒ Boolean
Check if the io is closed.
-
#flush ⇒ Object
Flush data.
-
#initialize(ioInfo, logger = nil) ⇒ IoFacade
constructor
A new instance of IoFacade.
-
#read(length) ⇒ Object
Read ‘length` bytes.
- #readRateLimit=(rate) ⇒ Object
-
#removeFromIOHash(hash) ⇒ Object
Method needed for disposeIo to work without breaking encapsulation of WriteOnlyIoFacade.
-
#seek(amount, whence) ⇒ Object
Seek on the io.
-
#write(data) ⇒ Object
Write data to the IO.
- #writeRateLimit=(rate) ⇒ Object
Constructor Details
#initialize(ioInfo, logger = nil) ⇒ IoFacade
Returns a new instance of IoFacade.
215 216 217 218 219 |
# File 'lib/quartz_torrent/reactor.rb', line 215 def initialize(ioInfo, logger = nil) @ioInfo = ioInfo @io = ioInfo.io @logger = logger end |
Instance Attribute Details
#logger ⇒ Object
Returns the value of attribute logger.
221 222 223 |
# File 'lib/quartz_torrent/reactor.rb', line 221 def logger @logger end |
Instance Method Details
#close ⇒ Object
Close the io.
295 296 297 |
# File 'lib/quartz_torrent/reactor.rb', line 295 def close @io.close end |
#closed? ⇒ Boolean
Check if the io is closed.
300 301 302 |
# File 'lib/quartz_torrent/reactor.rb', line 300 def closed? @io.closed? end |
#flush ⇒ Object
Flush data.
290 291 292 |
# File 'lib/quartz_torrent/reactor.rb', line 290 def flush @io.flush end |
#read(length) ⇒ Object
Read ‘length` bytes.
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/quartz_torrent/reactor.rb', line 230 def read(length) data = '' while data.length < length begin toRead = length-data.length rateLimited = false if @ioInfo.readRateLimit avail = @ioInfo.readRateLimit.avail.to_i if avail < toRead toRead = avail rateLimited = true end @ioInfo.readRateLimit.withdraw toRead end @logger.debug "IoFacade: must read: #{length} have read: #{data.length}. Reading #{toRead} bytes now" if @logger data << @io.read_nonblock(toRead) if toRead > 0 # If we tried to read more than we are allowed to by rate limiting, yield. Fiber.yield if rateLimited rescue Errno::EWOULDBLOCK # Wait for more data. @logger.debug "IoFacade: read would block" if @logger Fiber.yield rescue Errno::EAGAIN, Errno::EINTR # Wait for more data. @logger.debug "IoFacade: read was interrupted" if @logger Fiber.yield rescue @logger.debug "IoFacade: read error: #{$!}" if @logger # Read failure occurred @ioInfo.lastReadError = $! if @ioInfo.useErrorhandler @ioInfo.state = :error Fiber.yield else raise $! end end end data end |
#readRateLimit=(rate) ⇒ Object
304 305 306 307 |
# File 'lib/quartz_torrent/reactor.rb', line 304 def readRateLimit=(rate) raise "The argument must be a RateLimit" if ! rate.nil? && ! rate.is_a?(RateLimit) @ioInfo.readRateLimit = rate end |
#removeFromIOHash(hash) ⇒ Object
Method needed for disposeIo to work without breaking encapsulation of WriteOnlyIoFacade.
225 226 227 |
# File 'lib/quartz_torrent/reactor.rb', line 225 def removeFromIOHash(hash) hash.delete @io end |
#seek(amount, whence) ⇒ Object
Seek on the io.
285 286 287 |
# File 'lib/quartz_torrent/reactor.rb', line 285 def seek(amount, whence) @io.seek amount, whence if @ioInfo.seekable? end |
#write(data) ⇒ Object
Write data to the IO.
272 273 274 275 276 277 278 279 280 |
# File 'lib/quartz_torrent/reactor.rb', line 272 def write(data) # Issue: what about write, read, read on files opened for read/write? Write should happen at offset X, but reads moved to offset N. Since writes # are buffered, write may happen after read which means write will happen at the wrong offset N. Can fix by always seeking (if needed) before writes to the # position where the write was queued, but this should only be done for files since other fds don't support seek. This is satisfactory for files opened # for write only since the file position will be where we expect so we won't need to seek. Same for read only. @ioInfo.outputBuffer.append data @logger.debug "wrote #{data.length} bytes to the output buffer of IO metainfo=#{@ioInfo.}" if @logger data.length end |
#writeRateLimit=(rate) ⇒ Object
309 310 311 312 |
# File 'lib/quartz_torrent/reactor.rb', line 309 def writeRateLimit=(rate) raise "The argument must be a RateLimit" if ! rate.nil? && !rate.is_a?(RateLimit) @ioInfo.writeRateLimit = rate end |