Class: IO

Inherits:
Object show all
Includes:
CosmosIO
Defined in:
lib/cosmos/core_ext/io.rb

Constant Summary collapse

SELECT_BASE_TIMEOUT =

Initial timeout to call IO.select with. Timeouts are increased by doubling this value until the SELET_MAX_TIMEOUT value is reached.

0.0004
SELECT_MAX_TIMEOUT =

The maximum timeout at which point we call IO.select with whatever remaining timeout is left.

0.016

Class Method Summary collapse

Instance Method Summary collapse

Methods included from CosmosIO

#read_length_bytes

Class Method Details

.__select__Object

Alias the original IO.select method



35
# File 'lib/cosmos/core_ext/io.rb', line 35

alias_method :__select__, :select

.fast_read_select(read_sockets, timeout) ⇒ Object

Parameters:

  • read_sockets (Array<IO>)

    IO objects to wait to be ready to read

  • timeout (Numeric)

    Number of seconds to wait



115
116
117
# File 'lib/cosmos/core_ext/io.rb', line 115

def fast_read_select(read_sockets, timeout)
  return fast_select(read_sockets, nil, nil, timeout)
end

.fast_select(read_sockets = nil, write_sockets = nil, error_array = nil, timeout = nil) ⇒ Object

On Windows the IO.select function (when called with no timeout) takes a minimum of 10 msec to return, even if one of the IO objects is ready to read/write sooner than that.

This method is identical to IO.select but instead of calling IO.select with the full timeout, it calls IO.select with a small timeout and then doubles the timeout twice until eventually it calls IO.select with the remaining passed in timeout value.

Parameters:

  • read_sockets (Array<IO>) (defaults to: nil)

    IO objects to wait to be ready to read

  • write_sockets (Array<IO>) (defaults to: nil)

    IO objects to wait to be ready to write

  • error_array (Array<IO>) (defaults to: nil)

    IO objects to wait for exceptions

  • timeout (Numeric) (defaults to: nil)

    Number of seconds to wait



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/cosmos/core_ext/io.rb', line 50

def fast_select(read_sockets = nil, write_sockets = nil, error_array = nil, timeout = nil)
  # Always try a zero timeout first
  current_timeout = SELECT_BASE_TIMEOUT
  total_timeout = 0.0

  while true
    begin
      result = IO.__select__(read_sockets, write_sockets, error_array, current_timeout)
    # All OS errors are subclassed to SystemCallError as Errno::<Subclass>
    # See https://ruby-doc.org/core-3.1.0/Errno.html
    rescue SystemCallError
      return nil
    end
    return result if result or current_timeout.nil?
    return nil if timeout and total_timeout >= timeout

    if current_timeout <= 0.0001
      # Always try the base timeout next
      current_timeout = SELECT_BASE_TIMEOUT
      total_timeout = SELECT_BASE_TIMEOUT
    else
      # Then start doubling the timeout
      current_timeout = current_timeout * 2

      # Until it is bigger than our max timeout
      if current_timeout >= SELECT_MAX_TIMEOUT
        if timeout
          # Block for the remaining requested timeout
          current_timeout = timeout - total_timeout
          total_timeout = timeout
        else
          # Or block forever
          current_timeout = nil
        end
      else
        # Or it is bigger than the given timeout
        if timeout and current_timeout >= timeout
          # Block for the remaining requested timeout
          current_timeout = timeout - total_timeout
          total_timeout = timeout
        else
          # Up our total time in select
          total_timeout += current_timeout
        end
        if timeout and total_timeout > timeout
          # Block for the remaining requested timeout
          current_timeout = timeout - total_timeout
          total_timeout = timeout
        end
      end
      return nil if current_timeout and current_timeout < 0
    end
  end # while true
end

.fast_write_select(write_sockets, timeout) ⇒ Object

Parameters:

  • write_sockets (Array<IO>)

    IO objects to wait to be ready to write

  • timeout (Numeric)

    Number of seconds to wait



121
122
123
# File 'lib/cosmos/core_ext/io.rb', line 121

def fast_write_select(write_sockets, timeout)
  return fast_select(nil, write_sockets, nil, timeout)
end

Instance Method Details

#__close__Object

Alias the original close method



127
# File 'lib/cosmos/core_ext/io.rb', line 127

alias_method :__close__, :close

#closeObject

Patch the close method so that it won’t raise any exceptions



130
131
132
133
# File 'lib/cosmos/core_ext/io.rb', line 130

def close
  __close__
rescue
end

#select(read_sockets = nil, write_sockets = nil, error_array = nil, timeout = nil) ⇒ Object



108
109
110
# File 'lib/cosmos/core_ext/io.rb', line 108

def select(read_sockets = nil, write_sockets = nil, error_array = nil, timeout = nil)
  return fast_select(read_sockets, write_sockets, error_array, timeout)
end