Module: THTP::Utils

Overview

Methods for interacting with generated Thrift files

Instance Method Summary collapse

Instance Method Details

#args_class(service, rpc) ⇒ Object

args class is named after RPC, e.g., #get_things => Get_things_args



41
42
43
# File 'lib/thtp/utils.rb', line 41

def args_class(service, rpc)
  service.const_get("#{rpc.capitalize}_args")
end

#canonical_name(klass) ⇒ Object

Used to turn classes to canonical strings for routing and logging, e.g.,

  • MyServices::Thing::ThingService -> MyService.Thing.ThingService

  • MyServices::Thing::ThingRequest -> MyService.Thing.ThingRequest

  • MyServices::Thing::BadException -> MyService.Thing.BadException

Parameters:

  • klass (Class)


93
94
95
# File 'lib/thtp/utils.rb', line 93

def canonical_name(klass)
  klass.name.gsub('::', '.')
end

#deserialize(transport, struct, protocol) ⇒ Object

Thrift deserialisation



52
53
54
55
56
57
# File 'lib/thtp/utils.rb', line 52

def deserialize(transport, struct, protocol)
  struct.read(protocol.new(transport)) # read off the stream into Thrift objects
  struct # return input object with all fields filled out
rescue Thrift::ProtocolException, EOFError => e
  raise DeserializationError, e
end

#deserialize_buffer(buffer, struct, protocol) ⇒ Object



59
60
61
# File 'lib/thtp/utils.rb', line 59

def deserialize_buffer(buffer, struct, protocol)
  deserialize(Thrift::MemoryBufferTransport.new(buffer), struct, protocol)
end

#deserialize_stream(in_stream, struct, protocol) ⇒ Object



63
64
65
# File 'lib/thtp/utils.rb', line 63

def deserialize_stream(in_stream, struct, protocol)
  deserialize(Thrift::IOStreamTransport.new(in_stream, nil), struct, protocol)
end

#elapsed_ms(start_time) ⇒ Object

useful for benchmarking. returns wall clock ms since start time



19
20
21
# File 'lib/thtp/utils.rb', line 19

def elapsed_ms(start_time)
  ((get_time - start_time) * 1000).round
end

#extract_rpcs(thrift_service) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
# File 'lib/thtp/utils.rb', line 28

def extract_rpcs(thrift_service)
  # it's really the Processor we want (the Client would work too)
  root = thrift_service < Thrift::Processor ? thrift_service : thrift_service::Processor
  # get all candidate classes that may contribute RPCs to this service
  root.ancestors.flat_map do |klass|
    next [] unless klass < Thrift::Processor
    klass.instance_methods(false).
      select { |method_name| method_name =~ /^process_/ }.
      map { |method_name| method_name.to_s.sub(/^process_/, '').to_sym }
  end
end

#get_timeObject

get the current time, for benchmarking purposes. monotonic time is better than Time.now for this purposes. note, only works on Ruby 2.1.8+



14
15
16
# File 'lib/thtp/utils.rb', line 14

def get_time
  Process.clock_gettime(Process::CLOCK_MONOTONIC)
end

#jsonify(obj) ⇒ Object

Recursive object serialiser compatible with anything likely to appear in Thrift, in case ActiveSupport’s #as_json monkeypatch is unavailable



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

def jsonify(obj)
  return obj.as_json if obj.respond_to?(:as_json) # ActiveSupport shortcut

  case obj
  when nil, false, true, Numeric # directly representable as JSON
    obj
  when Hash
    obj.each_with_object({}) { |(k, v), h| h[jsonify(k)] = jsonify(v) }
  when Enumerable
    obj.map { |v| jsonify(v) }
  else
    if obj.instance_variables.any?
      obj.instance_variables.each_with_object({}) do |iv, h|
        h[iv.to_s[1..-1].to_sym] = jsonify(obj.instance_variable_get(iv))
      end
    else
      obj.to_s # lowest common denominator serialisation
    end
  end
end

#result_class(service, rpc) ⇒ Object

result class is named after RPC, e.g., #do_stuff => Do_stuff_result



46
47
48
# File 'lib/thtp/utils.rb', line 46

def result_class(service, rpc)
  service.const_get("#{rpc.capitalize}_result")
end

#serialize(base_struct, transport, protocol) ⇒ Object

Thrift serialisation



69
70
71
72
73
74
# File 'lib/thtp/utils.rb', line 69

def serialize(base_struct, transport, protocol)
  base_struct.write(protocol.new(transport))
  transport.tap(&:flush)
rescue Thrift::ProtocolException, EOFError => e
  raise SerializationError, e
end

#serialize_buffer(base_struct, protocol) ⇒ Object



76
77
78
79
80
# File 'lib/thtp/utils.rb', line 76

def serialize_buffer(base_struct, protocol)
  transport = Thrift::MemoryBufferTransport.new
  serialize(base_struct, transport, protocol) # write to output transport, an in-memory buffer
  transport.read(transport.available) # return serialised thrift
end

#serialize_stream(base_struct, out_stream, protocol) ⇒ Object



82
83
84
# File 'lib/thtp/utils.rb', line 82

def serialize_stream(base_struct, out_stream, protocol)
  serialize(base_struct, Thrift::IOStreamTransport.new(nil, out_stream), protocol)
end