Class: LightIO::Watchers::IO

Inherits:
Watcher
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/lightio/watchers/io.rb

Overview

LightIO::Watchers::IO provide a NIO::Monitor wrap to manage ‘raw’ socket / io

@Example:

#- wait_read for server socket
io_watcher = LightIO::Watchers::IO.new(server_socket, :r)
loop do
  io_watcher.wait_read
  client_socket = server_socket.accept
  # do something
end
io_watcher.close

Instance Attribute Summary

Attributes inherited from Watcher

#callback

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io, interests = :rw) ⇒ LightIO::Watchers::IO

Create a io watcher

Parameters:

  • io (Socket)

    An IO-able object

  • interests (Symbol) (defaults to: :rw)

    :r, :w, :rw - Is io readable? writeable? or both



20
21
22
23
24
25
26
27
28
# File 'lib/lightio/watchers/io.rb', line 20

def initialize(io, interests=:rw)
  @io = io
  @ioloop = LightIO::Core::IOloop.current
  @waiting = false
  ObjectSpace.define_finalizer(self, self.class.finalizer(@monitor))
  @error = nil
  # maintain socket status, see https://github.com/socketry/lightio/issues/1
  @readiness = nil
end

Class Method Details

.finalizer(monitor) ⇒ Object



38
39
40
# File 'lib/lightio/watchers/io.rb', line 38

def finalizer(monitor)
  proc {monitor.close if monitor && !monitor.close?}
end

Instance Method Details

#clear_statusObject



62
63
64
# File 'lib/lightio/watchers/io.rb', line 62

def clear_status
  @readiness = nil
end

#closeObject



92
93
94
95
96
97
# File 'lib/lightio/watchers/io.rb', line 92

def close
  return if closed?
  monitor.close
  @error = IOError.new('closed stream')
  callback_on_waiting
end

#monitor(interests = :rw) ⇒ Object

NIO::Monitor



31
32
33
34
35
# File 'lib/lightio/watchers/io.rb', line 31

def monitor(interests=:rw)
  @monitor ||= begin
    @ioloop.add_io_wait(@io, interests) {callback_on_waiting}
  end
end

#readable?Boolean

this method return previous IO.select status should avoid to directly use

Returns:

  • (Boolean)


48
49
50
51
# File 'lib/lightio/watchers/io.rb', line 48

def readable?
  check_monitor_read
  @readiness == :r || @readiness == :rw
end

#set_callback(&blk) ⇒ Object



105
106
107
# File 'lib/lightio/watchers/io.rb', line 105

def set_callback(&blk)
  @callback = blk
end

#start(ioloop) ⇒ Object

just implement IOloop#wait watcher interface



101
102
103
# File 'lib/lightio/watchers/io.rb', line 101

def start(ioloop)
  # do nothing
end

#wait(timeout = nil, mode = :read) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/lightio/watchers/io.rb', line 80

def wait(timeout=nil, mode=:read)
  LightIO::Timeout.timeout(timeout) do
    check_monitor(mode)
    in_waiting(mode) do
      wait_in_ioloop
    end
    self
  end
rescue Timeout::Error
  nil
end

#wait_readable(timeout = nil) ⇒ LightIO::Watchers::IO?

Blocking until io is readable

Parameters:

  • timeout (Numeric) (defaults to: nil)

    return nil after timeout seconds, otherwise return self

Returns:



69
70
71
# File 'lib/lightio/watchers/io.rb', line 69

def wait_readable(timeout=nil)
  wait timeout, :read
end

#wait_writable(timeout = nil) ⇒ LightIO::Watchers::IO?

Blocking until io is writable

Parameters:

  • timeout (Numeric) (defaults to: nil)

    return nil after timeout seconds, otherwise return self

Returns:



76
77
78
# File 'lib/lightio/watchers/io.rb', line 76

def wait_writable(timeout=nil)
  wait timeout, :write
end

#writable?Boolean Also known as: writeable?

this method return previous IO.select status should avoid to directly use

Returns:

  • (Boolean)


55
56
57
58
# File 'lib/lightio/watchers/io.rb', line 55

def writable?
  check_monitor_write
  @readiness == :w || @readiness == :rw
end