rainbows.git  about / heads / tags
Unicorn for sleepy apps and slow clients
blob 31b8dec1038acdefb870a47bc514ffb5b216e7ed 1299 bytes (raw)
$ git show HEAD:lib/rainbows/revactor/client/tee_socket.rb	# shows this blob on the CLI

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 
# -*- encoding: binary -*-
# :enddoc:
#
# Revactor Sockets do not implement readpartial, so we emulate just
# enough to avoid mucking with TeeInput internals.  Fortunately
# this code is not heavily used so we can usually avoid the overhead
# of adding a userspace buffer.
class Rainbows::Revactor::Client::TeeSocket
  def initialize(socket)
    # IO::Buffer is used internally by Rev which Revactor is based on
    # so we'll always have it available
    @socket, @rbuf = socket, IO::Buffer.new
  end

  def leftover
    @rbuf.read
  end

  # Revactor socket reads always return an unspecified amount,
  # sometimes too much
  def kgio_read(length, dst = "")
    return dst.replace("") if length == 0

    # always check and return from the userspace buffer first
    @rbuf.size > 0 and return dst.replace(@rbuf.read(length))

    # read off the socket since there was nothing in rbuf
    tmp = @socket.read

    # we didn't read too much, good, just return it straight back
    # to avoid needlessly wasting memory bandwidth
    tmp.size <= length and return dst.replace(tmp)

    # ugh, read returned too much
    @rbuf << tmp[length, tmp.size]
    dst.replace(tmp[0, length])
  rescue EOFError
  end

  # just proxy any remaining methods TeeInput may use
  def close
    @socket.close
  end
end

git clone https://yhbt.net/rainbows.git