Class: Fraggle::Client

Inherits:
Object
  • Object
show all
Includes:
Request::Verb
Defined in:
lib/fraggle/client.rb

Defined Under Namespace

Classes: NoMoreAddrs

Constant Summary collapse

DefaultLog =
Logger.new(STDERR)

Constants included from Request::Verb

Request::Verb::DEL, Request::Verb::GET, Request::Verb::GETDIR, Request::Verb::NOP, Request::Verb::REV, Request::Verb::SET, Request::Verb::STAT, Request::Verb::WAIT, Request::Verb::WALK

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cn, addrs, log = DefaultLog) ⇒ Client

Returns a new instance of Client.



17
18
19
# File 'lib/fraggle/client.rb', line 17

def initialize(cn, addrs, log=DefaultLog)
  @cn, @addrs, @log = cn, addrs, log
end

Instance Attribute Details

#addrsObject (readonly)

Returns the value of attribute addrs.



15
16
17
# File 'lib/fraggle/client.rb', line 15

def addrs
  @addrs
end

#cnObject (readonly)

Returns the value of attribute cn.



15
16
17
# File 'lib/fraggle/client.rb', line 15

def cn
  @cn
end

#logObject (readonly)

Returns the value of attribute log.



15
16
17
# File 'lib/fraggle/client.rb', line 15

def log
  @log
end

Instance Method Details

#addrObject



21
22
23
# File 'lib/fraggle/client.rb', line 21

def addr
  cn.addr
end

#del(path, rev, &blk) ⇒ Object



44
45
46
47
48
49
50
51
# File 'lib/fraggle/client.rb', line 44

def del(path, rev, &blk)
  req = Request.new
  req.verb = DEL
  req.rev  = rev
  req.path = path

  idemp(req, &blk)
end

#get(path, rev = nil, &blk) ⇒ Object



35
36
37
38
39
40
41
42
# File 'lib/fraggle/client.rb', line 35

def get(path, rev=nil, &blk)
  req = Request.new
  req.verb = GET
  req.rev  = rev
  req.path = path

  resend(req, &blk)
end

#getdir(path, rev = nil, offset = nil, &blk) ⇒ Object



53
54
55
56
57
58
59
60
61
# File 'lib/fraggle/client.rb', line 53

def getdir(path, rev=nil, offset=nil, &blk)
  req = Request.new
  req.verb   = GETDIR
  req.rev    = rev
  req.path   = path
  req.offset = offset

  resend(req, &blk)
end

#idemp(req, &blk) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/fraggle/client.rb', line 134

def idemp(req, &blk)
  cb = Proc.new do |e|
    if e.disconnected? && req.rev > 0
      # If we're trying to update a value that isn't missing or that we're
      # not trying to clobber, it's safe to retry.  We can't idempotently
      # update missing values because there may be a race with another
      # client that sets and/or deletes the key during the time between your
      # read and write.
      req.tag = nil
      idemp(req, &blk)
      next
    end

    blk.call(e)
  end

  send(req, &cb)
end

#reconnect(addr) ⇒ Object



161
162
163
164
165
# File 'lib/fraggle/client.rb', line 161

def reconnect(addr)
  log.warn("reconnecting to #{addr}")
  host, port = addr.split(":")
  @cn = EM.connect(host, port, Fraggle::Connection, addr)
end

#reconnect!Object



153
154
155
156
157
158
159
# File 'lib/fraggle/client.rb', line 153

def reconnect!
  if addr = @addrs.shift
    reconnect(addr)
  else
    raise NoMoreAddrs
  end
end

#resend(req, &blk) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/fraggle/client.rb', line 120

def resend(req, &blk)
  cb = Proc.new do |e|
    if e.disconnected?
      req.tag = nil
      log.debug("resending: #{req.inspect}")
      resend(req, &blk)
    else
      blk.call(e)
    end
  end

  send(req, &cb)
end

#rev(&blk) ⇒ Object



82
83
84
85
86
87
# File 'lib/fraggle/client.rb', line 82

def rev(&blk)
  req = Request.new
  req.verb = REV

  resend(req, &blk)
end

#send(req, &blk) ⇒ Object

Sends a request to the server. Returns the request with a new tag assigned.



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/fraggle/client.rb', line 100

def send(req, &blk)
  cb = Proc.new do |e|
    log.debug("response: #{e.inspect} for #{req.inspect}")

    case true
    when e.disconnected?
      # If we haven't already reconnected, do so.
      if cn.err?
        log.error("conn err: #{req.inspect}")
        reconnect!
      end
    end

    blk.call(e)
  end

  log.debug("sending: #{req.inspect}")
  cn.send_request(req, cb)
end

#set(path, value, rev, &blk) ⇒ Object



25
26
27
28
29
30
31
32
33
# File 'lib/fraggle/client.rb', line 25

def set(path, value, rev, &blk)
  req = Request.new
  req.verb  = SET
  req.rev   = rev
  req.path  = path
  req.value = value

  idemp(req, &blk)
end

#stat(path, rev = nil, &blk) ⇒ Object



89
90
91
92
93
94
95
96
# File 'lib/fraggle/client.rb', line 89

def stat(path, rev=nil, &blk)
  req = Request.new
  req.rev  = rev
  req.verb = STAT
  req.path = path

  resend(req, &blk)
end

#wait(path, rev = nil, &blk) ⇒ Object



73
74
75
76
77
78
79
80
# File 'lib/fraggle/client.rb', line 73

def wait(path, rev=nil, &blk)
  req = Request.new
  req.verb = WAIT
  req.rev  = rev
  req.path = path

  resend(req, &blk)
end

#walk(path, rev = nil, offset = nil, &blk) ⇒ Object



63
64
65
66
67
68
69
70
71
# File 'lib/fraggle/client.rb', line 63

def walk(path, rev=nil, offset=nil, &blk)
  req = Request.new
  req.verb   = WALK
  req.rev    = rev
  req.path   = path
  req.offset = offset

  resend(req, &blk)
end