Class: Ione::Io::BaseConnection

Inherits:
Object
  • Object
show all
Defined in:
lib/ione/io/base_connection.rb

Overview

Since:

  • v1.0.0

Direct Known Subclasses

Connection, ServerConnection

Constant Summary collapse

CONNECTING_STATE =

Since:

  • v1.0.0

0
CONNECTED_STATE =

Since:

  • v1.0.0

1
DRAINING_STATE =

Since:

  • v1.0.0

2
CLOSED_STATE =

Since:

  • v1.0.0

3

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#hostObject (readonly)

Since:

  • v1.0.0



12
13
14
# File 'lib/ione/io/base_connection.rb', line 12

def host
  @host
end

#portObject (readonly)

Since:

  • v1.0.0



12
13
14
# File 'lib/ione/io/base_connection.rb', line 12

def port
  @port
end

Instance Method Details

#close(cause = nil) ⇒ true, false

Closes the connection

Returns:

  • (true, false)

    returns false if the connection was already closed

Since:

  • v1.0.0



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/ione/io/base_connection.rb', line 31

def close(cause=nil)
  @lock.synchronize do
    return false if @state == CLOSED_STATE
    @state = CLOSED_STATE
    @writable = false
  end
  if @io
    begin
      @io.close
      @io = nil
    rescue SystemCallError, IOError
      # nothing to do, the socket was most likely already closed
    end
  end
  if cause && !cause.is_a?(IoError)
    cause = ConnectionClosedError.new(cause.message)
  end
  if cause
    @closed_promise.fail(cause)
  else
    @closed_promise.fulfill(self)
  end
  true
end

#closed?Boolean

Returns true if the connection is closed

Returns:

  • (Boolean)

Since:

  • v1.0.0



96
97
98
# File 'lib/ione/io/base_connection.rb', line 96

def closed?
  @state == CLOSED_STATE
end

#connected?Boolean

Returns true if the connection is connected

Returns:

  • (Boolean)

Since:

  • v1.0.0



91
92
93
# File 'lib/ione/io/base_connection.rb', line 91

def connected?
  @state == CONNECTED_STATE
end

#drainIone::Future

Wait for the connection's buffers to empty and then close it.

This method is almost always preferable to #close.

Returns:

  • (Ione::Future)

    a future that resolves to the connection when it has closed

Since:

  • v1.1.0



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/ione/io/base_connection.rb', line 63

def drain
  @lock.lock
  begin
    return if @state == DRAINING_STATE || @state == CLOSED_STATE
    @state = DRAINING_STATE
  ensure
    @lock.unlock
  end
  if writable?
    if @io.respond_to?(:close_read)
      begin
        @io.close_read
      rescue SystemCallError, IOError
        # nothing to do, the socket was most likely already closed
      end
    end
  else
    close
  end
  @closed_promise.future
end

#on_closed {|error, nil| ... } ⇒ Object

Register to receive a notification when the socket is closed, both for expected and unexpected reasons.

Errors raised by the callback will be ignored.

Yields:

  • (error, nil)

    the error that caused the socket to close, or nil if the socket closed with #close

Since:

  • v1.0.0



134
135
136
137
# File 'lib/ione/io/base_connection.rb', line 134

def on_closed(&listener)
  @closed_promise.future.on_value { listener.call(nil) }
  @closed_promise.future.on_failure { |e| listener.call(e) }
end

#on_data {|String| ... } ⇒ Object

Register to receive notifications when new data is read from the socket.

You should only call this method in your protocol handler constructor.

Only one callback can be registered, if you register multiple times only the last one will receive notifications. This is not meant as a general event system, it's just for protocol handlers to receive data from their connection. If you want multiple listeners you need to implement that yourself in your protocol handler.

It is very important that you don't do any heavy lifting in the callback since it is called from the IO reactor thread, and as long as the callback is working the reactor can't handle any IO and no other callbacks can be called.

Errors raised by the callback will be ignored.

Yields:

  • (String)

    the new data

Since:

  • v1.0.0



123
124
125
# File 'lib/ione/io/base_connection.rb', line 123

def on_data(&listener)
  @data_listener = listener
end

#to_sObject

Since:

  • v1.0.0



211
212
213
214
215
216
217
# File 'lib/ione/io/base_connection.rb', line 211

def to_s
  state_constant_name = self.class.constants.find do |name|
    name.to_s.end_with?('_STATE') && self.class.const_get(name) == @state
  end
  state = state_constant_name.to_s.rpartition('_').first
  %(#<#{self.class.name} #{state} #{@host}:#{@port}>)
end

#write(bytes = nil) {|buffer| ... } ⇒ Object

Write bytes to the socket.

You can either pass in bytes (as a string or as a ByteBuffer), or you can use the block form of this method to get access to the connection's internal buffer.

Parameters:

  • bytes (String, Ione::ByteBuffer) (defaults to: nil)

    the data to write to the socket

Yield Parameters:

Since:

  • v1.0.0



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/ione/io/base_connection.rb', line 147

def write(bytes=nil)
  if @state == CONNECTED_STATE || @state == CONNECTING_STATE
    @lock.lock
    begin
      if block_given?
        yield @write_buffer
      elsif bytes
        @write_buffer.append(bytes)
      end
      @writable = !@write_buffer.empty?
    ensure
      @lock.unlock
    end
    @unblocker.unblock
  end
end