Class: Socket

Inherits:
BasicSocket show all
Defined in:
lib/polyphony/extensions/socket.rb

Overview

Socket extensions # TODO: rewrite in C

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from BasicSocket

#__read_method__, #__write_method__

Methods inherited from IO

#close, copy_stream, deflate, double_splice, #double_splice, gunzip, gzip, http1_splice_chunked, inflate, orig_readlines, readlines, splice, #splice_from, tee, #tee_from, #wait_readable, #wait_writable

Class Method Details

.getaddrinfo(*args) ⇒ AddrInfo

Resolves the given addr using a worker thread from the default thread pool.

Returns:

  • (AddrInfo)


216
217
218
# File 'lib/polyphony/extensions/socket.rb', line 216

def getaddrinfo(*args)
  Polyphony::ThreadPool.process { orig_getaddrinfo(*args) }
end

Instance Method Details

#<<(msg) ⇒ Object

:nop-doc:



20
21
22
23
# File 'ext/polyphony/socket_extensions.c', line 20

VALUE Socket_double_chevron(VALUE self, VALUE msg) {
  Backend_send(BACKEND(), self, msg, INT2FIX(0));
  return self;
}

#acceptTCPSocket

Accepts an incoming connection.

Returns:



32
33
34
# File 'lib/polyphony/extensions/socket.rb', line 32

def accept
  Polyphony.backend_accept(self, TCPSocket)
end

#accept_loop {|Socket| ... } ⇒ nil

Accepts incoming connections in an infinite loop.

Yields:

  • (Socket)

    accepted socket

Returns:

  • (nil)


40
41
42
# File 'lib/polyphony/extensions/socket.rb', line 40

def accept_loop(&block)
  Polyphony.backend_accept_loop(self, TCPSocket, &block)
end

#connect(addr) ⇒ ::Socket

Connects to the given address

Parameters:

  • addr (AddrInfo, String)

    address to connect to

Returns:



51
52
53
54
55
# File 'lib/polyphony/extensions/socket.rb', line 51

def connect(addr)
  addr = Addrinfo.new(addr) if addr.is_a?(String)
  Polyphony.backend_connect(self, addr.ip_address, addr.ip_port)
  self
end

#dont_linger::Socket

Sets the linger option to 0.

Returns:



179
180
181
182
# File 'lib/polyphony/extensions/socket.rb', line 179

def dont_linger
  setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, Socket::ZERO_LINGER)
  self
end

#feed_loop(receiver, method = :call, &block) ⇒ Socket

Receives data from the socket in an infinite loop, passing the data to the given receiver using the given method. If a block is given, the result of the method call to the receiver is passed to the block.

This method can be used to feed data into parser objects. The following example shows how to feed data from a socket directly into a MessagePack unpacker:

unpacker = MessagePack::Unpacker.new conn.feed_loop(unpacker, :feed_each) { |msg| handle_msg(msg) }

Parameters:

  • receiver (any)

    receiver object

  • method (Symbol) (defaults to: :call)

    method to call

Returns:



128
129
130
# File 'lib/polyphony/extensions/socket.rb', line 128

def feed_loop(receiver, method = :call, &block)
  Polyphony.backend_recv_feed_loop(self, receiver, method, &block)
end

#no_delay::Socket

Sets the NODELAY option.

Returns:



187
188
189
190
# File 'lib/polyphony/extensions/socket.rb', line 187

def no_delay
  setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
  self
end

#read(len = nil, buf = nil, buffer_pos = 0) ⇒ String

Reads from the socket. If maxlen is given, reads up to maxlen bytes from the socket, otherwise reads to EOF. If buf is given, it is used as the buffer to read into, otherwise a new string is allocated. If buffer_pos is given, reads into the given offset (in bytes) in the given buffer. If the given buffer offset is negative, it is calculated from the current end of the buffer (-1 means the read data will be appended to the end of the buffer).

If no bytes are available and EOF is not hit, this method will block until the socket is ready to read from.

Parameters:

  • len (Integer, nil) (defaults to: nil)

    maximum bytes to read from socket

  • buf (String, nil) (defaults to: nil)

    buffer to read into

  • buffer_pos (Number) (defaults to: 0)

    buffer position to read into

Returns:

  • (String)

    buffer used for reading



75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/polyphony/extensions/socket.rb', line 75

def read(len = nil, buf = nil, buffer_pos = 0)
  return '' if len == 0
  return Polyphony.backend_read(self, buf, len, true, buffer_pos) if buf

  @read_buffer ||= +''
  result = Polyphony.backend_read(self, @read_buffer, len, true, -1)
  return nil unless result

  already_read = @read_buffer
  @read_buffer = +''
  already_read
end

#readpartial(maxlen, buf = +'',, buffer_pos = 0, raise_on_eof = true) ⇒ String?

Reads up to maxlen from the socket. If buf is given, it is used as the buffer to read into, otherwise a new string is allocated. If buffer_pos is given, reads into the given offset (in bytes) in the given buffer. If the given buffer offset is negative, it is calculated from the current end of the buffer (-1 means the read data will be appended to the end of the buffer). If raise_on_eof is true (the default,) an EOFError will be raised on EOF, otherwise nil will be returned.

If no bytes are available and EOF is not hit, this method will block until the socket is ready to read from.

Parameters:

  • maxlen (Integer, nil)

    maximum bytes to read from socket

  • buf (String, nil) (defaults to: +'',)

    buffer to read into

  • buffer_pos (Number) (defaults to: 0)

    buffer position to read into

  • raise_on_eof (bool) (defaults to: true)

    whether to raise an exception on EOF

Returns:

  • (String, nil)

    buffer used for reading or nil on EOF

Raises:

  • (EOFError)


166
167
168
169
170
171
# File 'lib/polyphony/extensions/socket.rb', line 166

def readpartial(maxlen, buf = +'', buffer_pos = 0, raise_on_eof = true)
  result = Polyphony.backend_recv(self, buf, maxlen, buffer_pos)
  raise EOFError if !result && raise_on_eof

  result
end

#recv(maxlen, flags = 0, outbuf = nil) ⇒ String

Receives up to maxlen bytes from the socket. If outbuf is given, it is used as the buffer to receive into, otherwise a new string is allocated and used as buffer.

If no bytes are available, this method will block until the socket is ready to receive from.

Parameters:

  • maxlen (Integer)

    maximum bytes to receive

  • flags (Integer) (defaults to: 0)

    receive flags

  • outbuf (String, nil) (defaults to: nil)

    buffer for reading or nil to allocate new string

Returns:

  • (String)

    receive buffer



99
100
101
# File 'lib/polyphony/extensions/socket.rb', line 99

def recv(maxlen, flags = 0, outbuf = nil)
  Polyphony.backend_recv(self, outbuf || +'', maxlen, 0)
end

#recv_loop(maxlen = 8192) {|String| ... } ⇒ Socket Also known as: read_loop

Receives up to maxlen bytes at a time in an infinite loop. Read buffers will be passed to the given block.

Parameters:

  • maxlen (Integer) (defaults to: 8192)

    maximum bytes to receive

Yields:

  • (String)

    received data

Returns:



109
110
111
# File 'lib/polyphony/extensions/socket.rb', line 109

def recv_loop(maxlen = 8192, &block)
  Polyphony.backend_recv_loop(self, maxlen, &block)
end

#recvfrom(maxlen, flags = 0) ⇒ String

Reimplements #recvfrom.

Parameters:

  • maxlen (Integer)

    maximum bytes to receive

  • flags (Integer) (defaults to: 0)

    optional flags

Returns:

  • (String)

    received data



137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/polyphony/extensions/socket.rb', line 137

def recvfrom(maxlen, flags = 0)
  buf = +''
  while true
    result = recvfrom_nonblock(maxlen, flags, buf, **NO_EXCEPTION)
    case result
    when nil then raise IOError
    when :wait_readable then Polyphony.backend_wait_io(self, false)
    else
      return result
    end
  end
end

#reuse_addr::Socket

Sets the REUSEADDR option.

Returns:



195
196
197
198
# File 'lib/polyphony/extensions/socket.rb', line 195

def reuse_addr
  setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
  self
end

#reuse_port::Socket

Sets the REUSEPORT option.

Returns:



203
204
205
206
# File 'lib/polyphony/extensions/socket.rb', line 203

def reuse_port
  setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_REUSEPORT, 1)
  self
end

#send(msg, flags) ⇒ Object

:nop-doc:



5
6
7
# File 'ext/polyphony/socket_extensions.c', line 5

VALUE Socket_send(VALUE self, VALUE msg, VALUE flags) {
  return Backend_send(BACKEND(), self, msg, flags);
}

#write(*args) ⇒ Object

:nop-doc:



11
12
13
14
15
16
# File 'ext/polyphony/socket_extensions.c', line 11

VALUE Socket_write(int argc, VALUE *argv, VALUE self) {
  VALUE ary = rb_ary_new_from_values(argc, argv);
  VALUE result = Backend_sendv(BACKEND(), self, ary, INT2FIX(0));
  RB_GC_GUARD(ary);
  return result;
}