Class: RedisHA::Connection

Inherits:
Socket
  • Object
show all
Defined in:
lib/redis_ha/connection.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(redis, pool) ⇒ Connection

Returns a new instance of Connection.



4
5
6
7
8
9
10
11
12
13
14
# File 'lib/redis_ha/connection.rb', line 4

def initialize(redis, pool)
  @write_buffer = ""
  @read_buffer = ""
  @response_offset = 0

  super(AF_INET, SOCK_STREAM, 0)

  @redis = redis
  @pool = pool
  setup(redis)
end

Instance Attribute Details

#addrObject

Returns the value of attribute addr.



2
3
4
# File 'lib/redis_ha/connection.rb', line 2

def addr
  @addr
end

#read_bufferObject

Returns the value of attribute read_buffer.



2
3
4
# File 'lib/redis_ha/connection.rb', line 2

def read_buffer
  @read_buffer
end

#statusObject

Returns the value of attribute status.



2
3
4
# File 'lib/redis_ha/connection.rb', line 2

def status
  @status
end

#write_bufferObject

Returns the value of attribute write_buffer.



2
3
4
# File 'lib/redis_ha/connection.rb', line 2

def write_buffer
  @write_buffer
end

Instance Method Details

#<<(buf) ⇒ Object



51
52
53
# File 'lib/redis_ha/connection.rb', line 51

def <<(buf)
  @write_buffer << buf
end

#checkObject



105
106
107
108
109
110
111
112
# File 'lib/redis_ha/connection.rb', line 105

def check
  if RedisHA::Protocol.peek?(@read_buffer)
    @ready = true
  end

  finish(:success) if @ready
  @ready
end

#execution_expiredObject



75
76
77
# File 'lib/redis_ha/connection.rb', line 75

def execution_expired
  finish(:fail)
end

#finish(stat) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
# File 'lib/redis_ha/connection.rb', line 93

def finish(stat)
  @ready = true

  if stat == :success
    @down_since = nil if @status != :up
    @status = :up
  else
    @status = :down
    @down_since = Time.now.to_f
  end
end

#nextObject



60
61
62
63
# File 'lib/redis_ha/connection.rb', line 60

def next
  @response_offset -= 1
  RedisHA::Protocol.parse(@read_buffer)
end

#ready?Boolean

Returns:

  • (Boolean)


79
80
81
82
83
84
85
# File 'lib/redis_ha/connection.rb', line 79

def ready?
  if @ready && @response_offset > 0
    self.next; @ready = false; check
  end

  !!@ready
end

#rewindObject



55
56
57
58
# File 'lib/redis_ha/connection.rb', line 55

def rewind
  @ready = false
  @response_offset -= 0
end

#setup(redis) ⇒ Object



87
88
89
90
91
# File 'lib/redis_ha/connection.rb', line 87

def setup(redis)
  addr = [redis.fetch(:port), redis.fetch(:host)]
  addr[1] = (TCPSocket.gethostbyname(addr[1]).last)
  @__addr = Socket.pack_sockaddr_in(*addr)
end

#up_or_retry?Boolean

Returns:

  • (Boolean)


114
115
116
117
118
119
120
121
# File 'lib/redis_ha/connection.rb', line 114

def up_or_retry?
  return true if @status == :up
  return true unless @down_since

  down_diff = Time.now.to_f - @down_since
  return true if down_diff > @pool.retry_timeout
  false
end

#wait_read?Boolean

Returns:

  • (Boolean)


65
66
67
68
# File 'lib/redis_ha/connection.rb', line 65

def wait_read?
  return false if @ready
  @write_buffer.size == 0
end

#wait_write?Boolean

Returns:

  • (Boolean)


70
71
72
73
# File 'lib/redis_ha/connection.rb', line 70

def wait_write?
  return false if @ready
  @write_buffer.size != 0
end

#yield_connectObject



16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/redis_ha/connection.rb', line 16

def yield_connect
  if @redis[:db] && !@db_selected
    @db_selected = true
    @response_offset += 1
    self << RedisHA::Protocol.request("select", @redis[:db])
  end

  connect_nonblock(@__addr)
rescue Errno::EINPROGRESS, Errno::ECONNABORTED, Errno::EINVAL
  nil
rescue Errno::ECONNREFUSED
  finish(:fail)
end

#yield_readObject



30
31
32
33
34
35
36
37
38
39
40
# File 'lib/redis_ha/connection.rb', line 30

def yield_read
  loop do
    @read_buffer << read_nonblock(1)[0]
  end
rescue Errno::EAGAIN
  check || raise(Errno::EAGAIN)
rescue Errno::ENOTCONN
  yield_connect
rescue Errno::ECONNREFUSED
  finish(:fail)
end

#yield_writeObject



42
43
44
45
46
47
48
49
# File 'lib/redis_ha/connection.rb', line 42

def yield_write
  len = write_nonblock(@write_buffer)
  @write_buffer = @write_buffer[len..-1] || ""
rescue Errno::EPIPE
  yield_connect
rescue Errno::ECONNREFUSED
  finish(:fail)
end