class Gibson::Client

Public Class Methods

new(opts = {}) click to toggle source

Create a new Gibson::Client instance, the options are passed to Gibson::Connection initialize method.

Examples:

Gibson::Client.new                         # will create a connection to the default /var/run/gibson.sock UNIX socket.
Gibson::Client.new :address => '127.0.0.1' # will connect to localhost:10128

Options:

  • :socket - The UNIX socket path, if this option is set a UNIX socket connection will be used. Default: /var/run/gibson.sock

  • :address - The ip address to connect to, if this option is set a TCP socket connection will be used. Default: nil

  • :port - The tcp port to connect to. Default: 10128

  • :timeout - The connection and I/O timeout in milliseconds. Default: 100

  • :keepalive - If a TCP connection will be used, set this to true to use the SO_KEEPALIVE flag on the socket. Default: false

# File lib/gibson/gibson.rb, line 32
def initialize(opts = {})
  @connection = nil
  @options = opts
end

Public Instance Methods

connect() click to toggle source

Create the connection.

# File lib/gibson/gibson.rb, line 38
def connect
  @connection = Connection.new( @options )
  @connection.connect
end
query( opcode, payload = '' ) click to toggle source

Send a query to the server given its opcode and arguments payload. Return the decoded data, or raise one of the RuntimeErrors defined inside Gibson::Protocol.

# File lib/gibson/gibson.rb, line 95
def query( opcode, payload = '' )
  connect if @connection == nil or not @connection.connected?

  psize  = payload.length
  packet = [ 2 + psize, opcode, payload ].pack( 'L<S<Z' + psize.to_s )

  wrote = @connection.write packet

  raise( Timeout::Error, "Couldn't complete writing ( wrote #{wrote} of #{packet.size} bytes )" ) unless packet.size == wrote 
  
  code, encoding, size = @connection.read(7).unpack('S<cL<' )
  data = @connection.read size
  
  raise( Timeout::Error, "Couldn't complete reading ( read #{data.size} of #{size} bytes )" ) unless data.size == size 

  decode code, encoding, size, StringIO.new(data)
end

Private Instance Methods

decode( code, encoding, size, io ) click to toggle source

Reply decoding wrapper.

# File lib/gibson/gibson.rb, line 74
def decode( code, encoding, size, io )
  if code == Protocol::REPLIES[:val]
    decode_val encoding, size, io

  elsif code == Protocol::REPLIES[:kval]
    decode_kval io, size

  elsif code == Protocol::REPLIES[:ok]
    true

  elsif Protocol.error? code
    raise Protocol::ERRORS[code]

  else
    io
  end
end
decode_kval( io, size ) click to toggle source

Decode a REPL_KVAL reply.

# File lib/gibson/gibson.rb, line 57
def decode_kval( io, size )
  count = io.read_unpacked 4, 'L<'
  obj   = {}

  count.times do |i|
    klen  = io.read_unpacked 4, 'L<' 
    key   = io.read_unpacked klen, 'a' + klen.to_s
    enc   = io.read_unpacked 1, 'c'
    vsize = io.read_unpacked 4, 'L<'

    obj[key] = decode Protocol::REPLIES[:val], enc, vsize, io
  end

  obj
end
decode_val( encoding, size, io ) click to toggle source

Decode a REPL_VAL reply.

# File lib/gibson/gibson.rb, line 44
def decode_val( encoding, size, io )
  # plain string
  if encoding == Protocol::ENCODINGS[:plain]
    io.read_unpacked size, 'a' + size.to_s
  # number
  elsif encoding == Protocol::ENCODINGS[:number]
    io.read_unpacked size, size == 4 ? 'l<' : 'q<'
  else
    raise 'Unknown data encoding.'
  end
end