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



80
81
82
# File 'lib/ione/io/base_connection.rb', line 80

def closed?
  @state == CLOSED_STATE
end

#connected?Boolean

Returns true if the connection is connected

Returns:

  • (Boolean)

Since:

  • v1.0.0



75
76
77
# File 'lib/ione/io/base_connection.rb', line 75

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
# File 'lib/ione/io/base_connection.rb', line 63

def drain
  @state = DRAINING_STATE
  close unless @writable
  @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



118
119
120
121
# File 'lib/ione/io/base_connection.rb', line 118

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



107
108
109
# File 'lib/ione/io/base_connection.rb', line 107

def on_data(&listener)
  @data_listener = listener
end

#to_sObject

Since:

  • v1.0.0



184
185
186
187
188
189
190
# File 'lib/ione/io/base_connection.rb', line 184

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



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/ione/io/base_connection.rb', line 131

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