class GremlinClient::Connection

represents the connection to our gremlin server

Constants

STATUS

Attributes

pool[RW]

a centralized place for you to store a connection pool of those objects recommendeded one is: github.com/mperham/connection_pool

connection_timeout[R]
gremlin_script_path[R]
timeout[R]

Public Class Methods

new( host: 'localhost', port: 8182, path: '/', connection_timeout: 1, timeout: 10, gremlin_script_path: '.', autoconnect: true ) click to toggle source

initialize a new connection using:

host    => hostname/ip where to connect
port    => listen port of the server
timeout => how long the client might wait for response from the server
# File lib/gremlin_client/connection.rb, line 33
def initialize(
  host: 'localhost',
  port: 8182,
  path: '/',
  connection_timeout: 1,
  timeout: 10,
  gremlin_script_path: '.',
  autoconnect: true
)
  @host = host
  @port = port
  @path = path
  @connection_timeout = connection_timeout
  @timeout = timeout
  @gremlin_script_path = gremlin_script_path
  @gremlin_script_path = Pathname.new(@gremlin_script_path) unless @gremlin_script_path.is_a?(Pathname)
  @autoconnect = autoconnect
  connect if @autoconnect
end

Public Instance Methods

close() click to toggle source
# File lib/gremlin_client/connection.rb, line 93
def close
  @ws.close
end
connect() click to toggle source

creates a new connection object

# File lib/gremlin_client/connection.rb, line 54
def connect
  gremlin = self
  WebSocket::Client::Simple.connect("ws://#{@host}:#{@port}#{@path}") do |ws|
    @ws = ws

    @ws.on :message do |msg|
      gremlin.receive_message(msg)
    end

    @ws.on :error do |e|
      receive_error(e)
    end
  end
end
open?() click to toggle source
# File lib/gremlin_client/connection.rb, line 86
def open?
  @ws.open?
rescue ::NoMethodError
  # #2 => it appears to happen in some situations when the situation is dropped
  return false
end
receive_error(e) click to toggle source
# File lib/gremlin_client/connection.rb, line 113
def receive_error(e)
  @error = e
end
receive_message(msg) click to toggle source

this has to be public so the websocket client thread sees it

# File lib/gremlin_client/connection.rb, line 99
def receive_message(msg)
  response = Oj.load(msg.data)
  # this check is important in case a request timeout and we make new ones after
  if response['requestId'] == @request_id
    if @response.nil?
      @response = response
    else
      @response['result']['data'].concat response['result']['data']
      @response['result']['meta'].merge! response['result']['meta']
      @response['status'] = response['status']
    end
  end
end
reconnect() click to toggle source
# File lib/gremlin_client/connection.rb, line 69
def reconnect
  @ws.close unless @ws.nil?
  connect
end
send_file(filename, bindings={}) click to toggle source
# File lib/gremlin_client/connection.rb, line 82
def send_file(filename, bindings={})
  send_query(IO.read(resolve_path(filename)), bindings)
end
send_query(command, bindings={}) click to toggle source
# File lib/gremlin_client/connection.rb, line 74
def send_query(command, bindings={})
  wait_connection
  reset_request
  @ws.send(build_message(command, bindings), { type: 'text' })
  wait_response
  return treat_response
end

Protected Instance Methods

build_message(command, bindings) click to toggle source
# File lib/gremlin_client/connection.rb, line 169
def build_message(command, bindings)
  message = {
    requestId: @request_id,
    op: 'eval',
    processor: '',
    args: {
      gremlin: command,
      bindings: bindings,
      language: 'gremlin-groovy'
    }
  }
  Oj.dump(message, mode: :compat)
end
is_finished?() click to toggle source
# File lib/gremlin_client/connection.rb, line 141
def is_finished?
  return true unless @error.nil?
  return false if @response.nil?
  return false if @response['status'].nil?
  return @response['status']['code'] != STATUS[:partial_content]
end
reset_request() click to toggle source
# File lib/gremlin_client/connection.rb, line 134
def reset_request
  @request_id= SecureRandom.uuid
  @started_at = Time.now.to_i
  @error = nil
  @response = nil
end
resolve_path(filename) click to toggle source
# File lib/gremlin_client/connection.rb, line 183
def resolve_path(filename)
  return filename if filename.is_a?(String) && filename[0,1] == '/'
  @gremlin_script_path.join(filename).to_s
end
treat_response() click to toggle source

we validate our response here to make sure it is going to be raising exceptions in the right thread

# File lib/gremlin_client/connection.rb, line 159
def treat_response
  # note that the partial_content status should be processed differently.
  # look at http://tinkerpop.apache.org/docs/3.0.1-incubating/ for more info
  ok_status = [:success, :no_content, :partial_content].map { |st| STATUS[st] }
  unless ok_status.include?(@response['status']['code'])
    fail ::GremlinClient::ServerError.new(@response['status']['code'], @response['status']['message'])
  end
  @response['result']
end
wait_connection(skip_reconnect = false) click to toggle source
# File lib/gremlin_client/connection.rb, line 119
def wait_connection(skip_reconnect = false)
  w_from = Time.now.to_i
  while !open? && Time.now.to_i - @connection_timeout < w_from
    sleep 0.001
  end
  unless open?
    # reconnection code
    if @autoconnect && !skip_reconnect
      reconnect
      return wait_connection(true)
    end
    fail ::GremlinClient::ConnectionTimeoutError.new(@connection_timeout)
  end
end
wait_response() click to toggle source
# File lib/gremlin_client/connection.rb, line 148
def wait_response
  while !is_finished? && (Time.now.to_i - @started_at < @timeout)
    sleep 0.001
  end

  fail ::GremlinClient::ServerError.new(nil, @error) unless @error.nil?
  fail ::GremlinClient::ExecutionTimeoutError.new(@timeout) if @response.nil?
end