Class: Flare::Tools::Client

Inherits:
Object
  • Object
show all
Extended by:
Util::Logging
Includes:
Util::Constant, Util::Logging, Util::Result
Defined in:
lib/flare/tools/client.rb

Overview

Description

Direct Known Subclasses

Stats

Constant Summary collapse

@@processors =
{}
@@parsers =
{}

Constants included from Util::Result

Util::Result::ClientError, Util::Result::Deleted, Util::Result::End, Util::Result::Error, Util::Result::Exists, Util::Result::Found, Util::Result::None, Util::Result::NotFound, Util::Result::NotStored, Util::Result::Ok, Util::Result::ServerError, Util::Result::Stored

Constants included from Util::Constant

Util::Constant::DefalutBwlimit, Util::Constant::DefaultIndexServerName, Util::Constant::DefaultIndexServerPort, Util::Constant::DefaultNodePort, Util::Constant::DefaultTimeout, Util::Constant::STATUS_NG, Util::Constant::STATUS_OK

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Util::Logging

debug, error, fatal, info, logger, puts, set_logger, trace, warn

Methods included from Util::Result

result_of_string, string_of_result

Constructor Details

#initialize(host, port, tout = DefaultTimeout, uplink_limit = DefalutBwlimit, downlink_limit = DefalutBwlimit) ⇒ Client

Returns a new instance of Client.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/flare/tools/client.rb', line 37

def initialize(host, port, tout = DefaultTimeout, uplink_limit = DefalutBwlimit, downlink_limit = DefalutBwlimit)
  @tout = tout
  @conn = nil
  Timeout.timeout(1) do
    @conn = Flare::Net::Connection.new(host, port, uplink_limit, downlink_limit)
  end
  @server_name, @version = server_version
rescue Errno::ECONNREFUSED
  debug "Connection refused. server=[#{@conn}]"
  raise
rescue TimeoutError
  debug "Connection timeout. server=[#{@conn}]"
  raise
rescue SocketError
  debug "Connection error. server=[#{host}:#{port}]"
  raise
end

Class Method Details

.defcmd(method_symbol, command_template, &default_processor) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/flare/tools/client.rb', line 127

def self.defcmd(method_symbol, command_template, &default_processor)
  parser = lambda {|conn,processor|
    resp = ""
    answers = [Ok, End, Stored, Deleted, NotFound].map {|x| Flare::Util::Result.string_of_result(x)}
    fails = [Exists].map {|x| Flare::Util::Result.string_of_result(x)}
    errors = [Error, ServerError, ClientError].map {|x| Flare::Util::Result.string_of_result(x)}
    while x = conn.getline
      ans = x.chomp.split(' ', 2)
      ans = if ans.empty? then '' else ans[0] end
      case ans
      when *answers
        break
      when *fails
        resp = false
        break
      when *errors
        warn "Failed command. server=[#{self}] sent=[#{conn.last_sent}] result=[#{x.chomp}]"
        resp = false
        break
      else
        resp += x
      end
    end
    return processor.call(resp) if resp 
    return false
  }
  defcmd_generic(method_symbol, command_template, parser, true, &default_processor)
end

.defcmd_generic(method_symbol, command_template, parser, timeout, &default_processor) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/flare/tools/client.rb', line 113

def self.defcmd_generic(method_symbol, command_template, parser, timeout, &default_processor)
  @@parsers[method_symbol] = parser
  @@processors[method_symbol] = default_processor || proc { false }
  timeout_expr = if timeout then "@tout" else "nil" end
  self.class_eval %{
    def #{method_symbol.to_s}(*args, &processor)
      cmd = "#{command_template}"
      cmd = cmd % args if args.size > 0
      processor = @@processors[:#{method_symbol}] if processor.nil?
      request(cmd, @@parsers[:#{method_symbol}], processor, #{timeout_expr})
    end
  }
end

.defcmd_key(method_symbol, command_template, &default_processor) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/flare/tools/client.rb', line 171

def self.defcmd_key(method_symbol, command_template, &default_processor)
  parser = lambda {|conn,processor|
    rets = []
    while true
      line = conn.getline
      elems = line.split(' ')
      if elems[0] == "KEY"
        unless processor.nil?
          r = processor.call(elems[1])
          rets << r if r
        end
      elsif elems[0] == "END"
        return rets
      else
        info "key parser: error \"#{line.chomp}\""
        return false
      end
    end
  }
  defcmd_generic(method_symbol, command_template, parser, false, &default_processor)
end

.defcmd_listelement(method_symbol, command_template, &default_processor) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/flare/tools/client.rb', line 218

def self.defcmd_listelement(method_symbol, command_template, &default_processor)
  parser = lambda {|conn,processor|
    rets = []
    while true
      line = conn.getline
      elems = line.split(' ')
      if elems[0] == "LISTELEMENT"
        key, rel, abs = elems[1], elems[2].to_i, elems[3].to_i
        flag, len, version, expire = elems[4].to_i, elems[5].to_i, elems[6], elems[7]
        data = conn.read(len)
        unless processor.nil?
          r = processor.call(data, key, rel, abs, flag, len, version, expire)
          rets << r if r
        end
        conn.getline # skip
      elsif elems[0] == "END"
        return rets[0] if rets.size == 1
        return rets
      else
        info "error \"#{line.chomp}\""
        return false
      end
    end
  }
  defcmd_generic(method_symbol, command_template, parser, false, &default_processor)
end

.defcmd_noreply(method_symbol, command_template, &default_processor) ⇒ Object



156
157
158
159
160
161
# File 'lib/flare/tools/client.rb', line 156

def self.defcmd_noreply(method_symbol, command_template, &default_processor)
  parser = lambda {|conn,processor|
    return processor.call()
  }
  defcmd_generic(method_symbol, command_template, parser, true, &default_processor)
end

.defcmd_oneline(method_symbol, command_template, &default_processor) ⇒ Object



163
164
165
166
167
168
169
# File 'lib/flare/tools/client.rb', line 163

def self.defcmd_oneline(method_symbol, command_template, &default_processor)
  parser = lambda {|conn,processor|
    line = conn.getline
    processor.call(line)
  }
  defcmd_generic(method_symbol, command_template, parser, true, &default_processor)
end

.defcmd_value(method_symbol, command_template, &default_processor) ⇒ Object



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/flare/tools/client.rb', line 193

def self.defcmd_value(method_symbol, command_template, &default_processor)
  parser = lambda {|conn,processor|
    rets = []
    while true
      line = conn.getline
      elems = line.split(' ')
      if elems[0] == "VALUE"
        key, flag, len, version, expire = elems[1], elems[2].to_i, elems[3].to_i, elems[4].to_i, elems[5].to_i
        data = conn.read(len)
        unless processor.nil?
          r = processor.call(data, key, flag, len, version, expire)
          rets << r if r
        end
        conn.getline # skip
      elsif elems[0] == "END"
        return rets
      else
        info "value parser: error \"#{line.chomp}\""
        return false
      end
    end
  }
  defcmd_generic(method_symbol, command_template, parser, false, &default_processor)
end

.open(host, port, tout = DefaultTimeout, uplink_limit = DefalutBwlimit, downlink_limit = DefalutBwlimit, &block) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/flare/tools/client.rb', line 24

def self.open(host, port, tout = DefaultTimeout, uplink_limit = DefalutBwlimit, downlink_limit = DefalutBwlimit, &block)
  session = nil
  session = self.new(host, port, tout, uplink_limit, downlink_limit)
  return session if block.nil?
  return block.call(session)
ensure
  if session.nil?
    error "failed to open #{host}:#{port}."
  else
    session.close # this might raise IOError
  end
end

Instance Method Details

#closeObject



102
103
104
105
106
107
108
# File 'lib/flare/tools/client.rb', line 102

def close()
  begin
    Timeout.timeout(1) { quit }
  rescue Timeout::Error => e
  end
  @conn.close
end

#hostObject



64
65
66
# File 'lib/flare/tools/client.rb', line 64

def host
  @conn.host
end

#hostnameObject



68
69
70
# File 'lib/flare/tools/client.rb', line 68

def hostname
  @conn.host
end

#portObject



72
73
74
# File 'lib/flare/tools/client.rb', line 72

def port
  @conn.port
end

#received_sizeObject



98
99
100
# File 'lib/flare/tools/client.rb', line 98

def received_size
  @conn.received_size
end

#request(cmd, parser, processor, tout = @tout) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/flare/tools/client.rb', line 76

def request(cmd, parser, processor, tout = @tout)
  # info "request(#{cmd}, #{noreply})"
  @conn.reconnect if @conn.closed?
  debug "Enter the command server. server=[#{@conn}] command=[#{cmd}}]"
  response = nil
  cmd.chomp!
  cmd += "\r\n"
  Timeout.timeout(tout) do
    @conn.send(cmd)
    response = parser.call(@conn, processor)
  end
  response
rescue TimeoutError => e
  error "Connection timeout. server=[#{@conn}] command=[#{cmd}}]"
  @conn.close
  raise e
end

#required_version?(required_version, version = @version) ⇒ Boolean

Returns:

  • (Boolean)


55
56
57
58
59
60
61
62
# File 'lib/flare/tools/client.rb', line 55

def required_version?(required_version, version = @version)
  (0...required_version.size).each do |i|
    n = if i < version.size then version[i] else 0 end
    return true if n > required_version[i]
    return false if n < required_version[i]
  end
  true
end

#sent_sizeObject



94
95
96
# File 'lib/flare/tools/client.rb', line 94

def sent_size
  @conn.sent_size
end

#server_versionObject



245
246
247
248
249
250
251
# File 'lib/flare/tools/client.rb', line 245

def server_version
  verstrings = version.split('-')
  server = "flare"
  server = verstrings.shift if verstrings.size > 1
  version = verstrings[0].split('.').map {|v| v.to_i}
  [server, version]
end

#versionObject

we have two types of VERSION formats. VERSION flare-1.0.14 VERSION 1.0.9



256
257
258
# File 'lib/flare/tools/client.rb', line 256

def version
  version_
end