doc: tag files containing internal implementation details
[ruby-mogilefs-client.git] / lib / mogilefs / socket / pure_ruby.rb
blob6b9efc0d52e3fe298ddf2a8a8fe1af8017c6b29f
1 # -*- encoding: binary -*-
2 # internal implementation details here, do not rely on them in your code
3 require "socket"
4 require "io/wait"
5 require "timeout"
7 class MogileFS::Socket < Socket
8   include MogileFS::SocketCommon
10   def self.start(host, port)
11     sock = new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
12     begin
13       sock.connect_nonblock(sockaddr_in(port, host))
14     rescue Errno::EINPROGRESS
15     end
16     sock.post_init(host, port)
17   end
19   def self.tcp(host, port, timeout = 5)
20     sock = start(host, port)
21     unless IO.select(nil, [ sock ], nil, timeout)
22       sock.close
23       raise MogileFS::Timeout, 'socket connect timeout'
24     end
25     sock
26   end
28   def timed_read(len, dst = "", timeout = 5)
29     begin
30       return read_nonblock(len, dst)
31     rescue Errno::EAGAIN
32       wait(timeout) or unreadable_socket!
33     rescue EOFError
34       return
35     end while true
36   end
38   def timed_peek(len, dst, timeout = 5)
39     begin
40       rc = recv_nonblock(len, Socket::MSG_PEEK)
41       return rc.empty? ? nil : dst.replace(rc)
42     rescue Errno::EAGAIN
43       wait(timeout) or unreadable_socket!
44     rescue EOFError
45       dst.replace("")
46       return
47     end while true
48   end
50   def timed_write(buf, timeout = 5)
51     written = 0
52     expect = buf.bytesize
53     begin
54       rc = write_nonblock(buf)
55       return if rc == buf.bytesize
56       written += rc
58       if buf.respond_to?(:byteslice)
59         buf = buf.byteslice(rc, buf.bytesize)
60       else
61         if buf.respond_to?(:encoding) && buf.encoding != Encoding::BINARY
62           buf = buf.dup.force_encoding(Encoding::BINARY)
63         end
64         buf = buf.slice(rc, buf.bytesize)
65       end
66     rescue Errno::EAGAIN
67       IO.select(nil, [self], nil, timeout) or
68         request_truncated!(written, expect)
69     end while true
70   end
71 end