finagle-thrift 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+
3
+ require 'thrift'
4
+
5
+ require 'finagle-thrift/thrift/tracing_types'
6
+ # require 'finagle-thrift/thrift/tracing_constants'
7
+
8
+ require 'finagle-thrift/client'
9
+ require 'finagle-thrift/thrift_client'
10
+ require 'finagle-thrift/trace'
11
+ require 'finagle-thrift/tracer'
12
+
13
+ module FinagleThrift
14
+ extend self
15
+ def enable_tracing!(service, client_id = nil, service_name = nil)
16
+ raise ArgumentError, "client_id must be nil or of type FinagleThrift::ClientId" if client_id && !client_id.is_a?(FinagleThrift::ClientId)
17
+ class << service
18
+ include ::FinagleThrift::ThriftClient
19
+ end
20
+
21
+ client_class = service.client_class
22
+ client_class.class_eval do
23
+ include ::FinagleThrift::Client
24
+ end
25
+ client_class.send(:define_method, :client_id) { client_id }
26
+ client_class.send(:define_method, :trace_service_name) { service_name }
27
+ end
28
+ end
@@ -0,0 +1,85 @@
1
+ module FinagleThrift
2
+ module Client
3
+ CanTraceMethodName = "__can__finagle__trace__v3__"
4
+
5
+ include ::Thrift::Client
6
+
7
+ alias_method :_orig_send_message, :send_message
8
+ alias_method :_orig_receive_message, :receive_message
9
+
10
+ def initialize(iprot, oprot=nil)
11
+ super
12
+ @upgraded = false
13
+ @client_port = 0
14
+ attempt_upgrade!
15
+ end
16
+
17
+ def send_message(name, args_class, args = {})
18
+ if @upgraded
19
+ header = ::FinagleThrift::RequestHeader.new
20
+ header.trace_id = Trace.id.trace_id.to_i
21
+ header.parent_span_id = Trace.id.parent_id.to_i
22
+ header.span_id = Trace.id.span_id.to_i
23
+ header.sampled = Trace.id.sampled?
24
+ header.debug = false
25
+
26
+ header.client_id = client_id if client_id
27
+
28
+ header.write(@oprot)
29
+ end
30
+ Trace.record(Trace::Annotation.new(Trace::Annotation::CLIENT_SEND, self.endpoint))
31
+
32
+ _orig_send_message(name, args_class, args)
33
+ end
34
+
35
+ def receive_message(klass)
36
+ if @upgraded
37
+ response = ::FinagleThrift::ResponseHeader.new
38
+ response.read(@iprot)
39
+ end
40
+ result = _orig_receive_message(klass)
41
+ Trace.record(Trace::Annotation.new(Trace::Annotation::CLIENT_RECV, self.endpoint))
42
+ result
43
+ end
44
+
45
+ protected
46
+ def client_id
47
+ nil
48
+ end
49
+
50
+ def trace_service_name
51
+ nil
52
+ end
53
+
54
+ def endpoint
55
+ @endpoint ||= Trace.default_endpoint.with_port(@client_port).with_service_name(trace_service_name)
56
+ end
57
+
58
+ private
59
+ def attempt_upgrade!
60
+ _orig_send_message(CanTraceMethodName, ::FinagleThrift::ConnectionOptions)
61
+ begin
62
+ extract_client_port
63
+ _orig_receive_message(::FinagleThrift::UpgradeReply)
64
+ @upgraded = true
65
+ rescue ::Thrift::ApplicationException
66
+ @upgraded = false
67
+ end
68
+ rescue
69
+ @upgraded = false
70
+ raise
71
+ end
72
+
73
+ def extract_client_port
74
+ @client_port = begin
75
+ # im sorry
76
+ trans = @oprot.instance_variable_get("@trans")
77
+ transport = trans.instance_variable_get("@transport")
78
+ handle = transport.instance_variable_get("@handle")
79
+ Socket.unpack_sockaddr_in(handle.getsockname).first
80
+ rescue
81
+ 0
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,18 @@
1
+ #
2
+ # Autogenerated by Thrift
3
+ #
4
+ # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5
+ #
6
+
7
+ require 'tracing_types'
8
+
9
+ module FinagleThrift
10
+ CLIENT_SEND = %q"cs"
11
+
12
+ CLIENT_RECV = %q"cr"
13
+
14
+ SERVER_SEND = %q"ss"
15
+
16
+ SERVER_RECV = %q"sr"
17
+
18
+ end
@@ -0,0 +1,210 @@
1
+ #
2
+ # Autogenerated by Thrift
3
+ #
4
+ # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
5
+ #
6
+
7
+
8
+ module FinagleThrift
9
+ module AnnotationType
10
+ BOOL = 0
11
+ BYTES = 1
12
+ I16 = 2
13
+ I32 = 3
14
+ I64 = 4
15
+ DOUBLE = 5
16
+ STRING = 6
17
+ VALUE_MAP = {0 => "BOOL", 1 => "BYTES", 2 => "I16", 3 => "I32", 4 => "I64", 5 => "DOUBLE", 6 => "STRING"}
18
+ VALID_VALUES = Set.new([BOOL, BYTES, I16, I32, I64, DOUBLE, STRING]).freeze
19
+ end
20
+
21
+ class Endpoint
22
+ include ::Thrift::Struct, ::Thrift::Struct_Union
23
+ IPV4 = 1
24
+ PORT = 2
25
+ SERVICE_NAME = 3
26
+
27
+ FIELDS = {
28
+ IPV4 => {:type => ::Thrift::Types::I32, :name => 'ipv4'},
29
+ PORT => {:type => ::Thrift::Types::I16, :name => 'port'},
30
+ SERVICE_NAME => {:type => ::Thrift::Types::STRING, :name => 'service_name'}
31
+ }
32
+
33
+ def struct_fields; FIELDS; end
34
+
35
+ def validate
36
+ end
37
+
38
+ ::Thrift::Struct.generate_accessors self
39
+ end
40
+
41
+ class Annotation
42
+ include ::Thrift::Struct, ::Thrift::Struct_Union
43
+ TIMESTAMP = 1
44
+ VALUE = 2
45
+ HOST = 3
46
+
47
+ FIELDS = {
48
+ TIMESTAMP => {:type => ::Thrift::Types::I64, :name => 'timestamp'},
49
+ VALUE => {:type => ::Thrift::Types::STRING, :name => 'value'},
50
+ HOST => {:type => ::Thrift::Types::STRUCT, :name => 'host', :class => FinagleThrift::Endpoint, :optional => true}
51
+ }
52
+
53
+ def struct_fields; FIELDS; end
54
+
55
+ def validate
56
+ end
57
+
58
+ ::Thrift::Struct.generate_accessors self
59
+ end
60
+
61
+ class BinaryAnnotation
62
+ include ::Thrift::Struct, ::Thrift::Struct_Union
63
+ KEY = 1
64
+ VALUE = 2
65
+ ANNOTATION_TYPE = 3
66
+ HOST = 4
67
+
68
+ FIELDS = {
69
+ KEY => {:type => ::Thrift::Types::STRING, :name => 'key'},
70
+ VALUE => {:type => ::Thrift::Types::STRING, :name => 'value', :binary => true},
71
+ ANNOTATION_TYPE => {:type => ::Thrift::Types::I32, :name => 'annotation_type', :enum_class => FinagleThrift::AnnotationType},
72
+ HOST => {:type => ::Thrift::Types::STRUCT, :name => 'host', :class => FinagleThrift::Endpoint, :optional => true}
73
+ }
74
+
75
+ def struct_fields; FIELDS; end
76
+
77
+ def validate
78
+ unless @annotation_type.nil? || FinagleThrift::AnnotationType::VALID_VALUES.include?(@annotation_type)
79
+ raise ::Thrift::ProtocolException.new(::Thrift::ProtocolException::UNKNOWN, 'Invalid value of field annotation_type!')
80
+ end
81
+ end
82
+
83
+ ::Thrift::Struct.generate_accessors self
84
+ end
85
+
86
+ class Span
87
+ include ::Thrift::Struct, ::Thrift::Struct_Union
88
+ TRACE_ID = 1
89
+ NAME = 3
90
+ ID = 4
91
+ PARENT_ID = 5
92
+ ANNOTATIONS = 6
93
+ BINARY_ANNOTATIONS = 8
94
+
95
+ FIELDS = {
96
+ TRACE_ID => {:type => ::Thrift::Types::I64, :name => 'trace_id'},
97
+ NAME => {:type => ::Thrift::Types::STRING, :name => 'name'},
98
+ ID => {:type => ::Thrift::Types::I64, :name => 'id'},
99
+ PARENT_ID => {:type => ::Thrift::Types::I64, :name => 'parent_id', :optional => true},
100
+ ANNOTATIONS => {:type => ::Thrift::Types::LIST, :name => 'annotations', :element => {:type => ::Thrift::Types::STRUCT, :class => FinagleThrift::Annotation}},
101
+ BINARY_ANNOTATIONS => {:type => ::Thrift::Types::LIST, :name => 'binary_annotations', :element => {:type => ::Thrift::Types::STRUCT, :class => FinagleThrift::BinaryAnnotation}}
102
+ }
103
+
104
+ def struct_fields; FIELDS; end
105
+
106
+ def validate
107
+ end
108
+
109
+ ::Thrift::Struct.generate_accessors self
110
+ end
111
+
112
+ # At connection time, we can let the server know who we are so
113
+ # they can book keep and optionally reject unknown clients.
114
+ class ClientId
115
+ include ::Thrift::Struct, ::Thrift::Struct_Union
116
+ NAME = 1
117
+
118
+ FIELDS = {
119
+ NAME => {:type => ::Thrift::Types::STRING, :name => 'name'}
120
+ }
121
+
122
+ def struct_fields; FIELDS; end
123
+
124
+ def validate
125
+ end
126
+
127
+ ::Thrift::Struct.generate_accessors self
128
+ end
129
+
130
+ # RequestHeader defines headers for the request. These carry the span data, and
131
+ # a flag indicating whether the request is to be debugged.
132
+ class RequestHeader
133
+ include ::Thrift::Struct, ::Thrift::Struct_Union
134
+ TRACE_ID = 1
135
+ SPAN_ID = 2
136
+ PARENT_SPAN_ID = 3
137
+ DEBUG = 4
138
+ SAMPLED = 5
139
+ CLIENT_ID = 6
140
+
141
+ FIELDS = {
142
+ TRACE_ID => {:type => ::Thrift::Types::I64, :name => 'trace_id'},
143
+ SPAN_ID => {:type => ::Thrift::Types::I64, :name => 'span_id'},
144
+ PARENT_SPAN_ID => {:type => ::Thrift::Types::I64, :name => 'parent_span_id', :optional => true},
145
+ DEBUG => {:type => ::Thrift::Types::BOOL, :name => 'debug'},
146
+ SAMPLED => {:type => ::Thrift::Types::BOOL, :name => 'sampled', :optional => true},
147
+ CLIENT_ID => {:type => ::Thrift::Types::STRUCT, :name => 'client_id', :class => FinagleThrift::ClientId, :optional => true}
148
+ }
149
+
150
+ def struct_fields; FIELDS; end
151
+
152
+ def validate
153
+ end
154
+
155
+ ::Thrift::Struct.generate_accessors self
156
+ end
157
+
158
+ # The Response carries a reply header for tracing. These are
159
+ # empty unless the request is being debugged, in which case a
160
+ # transcript is copied.
161
+ class ResponseHeader
162
+ include ::Thrift::Struct, ::Thrift::Struct_Union
163
+ SPANS = 1
164
+
165
+ FIELDS = {
166
+ SPANS => {:type => ::Thrift::Types::LIST, :name => 'spans', :element => {:type => ::Thrift::Types::STRUCT, :class => FinagleThrift::Span}}
167
+ }
168
+
169
+ def struct_fields; FIELDS; end
170
+
171
+ def validate
172
+ end
173
+
174
+ ::Thrift::Struct.generate_accessors self
175
+ end
176
+
177
+ # These are connection-level options negotiated during protocol
178
+ # upgrade.
179
+ class ConnectionOptions
180
+ include ::Thrift::Struct, ::Thrift::Struct_Union
181
+
182
+ FIELDS = {
183
+
184
+ }
185
+
186
+ def struct_fields; FIELDS; end
187
+
188
+ def validate
189
+ end
190
+
191
+ ::Thrift::Struct.generate_accessors self
192
+ end
193
+
194
+ # This is the struct that a successful upgrade will reply with.
195
+ class UpgradeReply
196
+ include ::Thrift::Struct, ::Thrift::Struct_Union
197
+
198
+ FIELDS = {
199
+
200
+ }
201
+
202
+ def struct_fields; FIELDS; end
203
+
204
+ def validate
205
+ end
206
+
207
+ ::Thrift::Struct.generate_accessors self
208
+ end
209
+
210
+ end
@@ -0,0 +1,10 @@
1
+ module FinagleThrift
2
+ module ThriftClient
3
+ def handled_proxy(method_name, *args)
4
+ Trace.push(Trace.id.next_id) do
5
+ Trace.set_rpc_name(method_name)
6
+ super(method_name, *args)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,135 @@
1
+ module Trace
2
+ extend self
3
+ DEFAULT_SAMPLE_RATE = 0.001
4
+ TRACE_ID_UPPER_BOUND = 2 ** 64
5
+
6
+ def id
7
+ if stack.empty?
8
+ span_id = generate_id
9
+ trace_id = TraceId.new(span_id, nil, span_id, should_sample?)
10
+ stack.push(trace_id)
11
+ end
12
+ stack.last
13
+ end
14
+
15
+ def push(trace_id)
16
+ stack.push(trace_id)
17
+ if block_given?
18
+ begin
19
+ yield
20
+ ensure
21
+ pop
22
+ end
23
+ end
24
+ end
25
+
26
+ def pop
27
+ stack.pop
28
+ end
29
+
30
+ def unwind
31
+ if block_given?
32
+ begin
33
+ saved_stack = stack.dup
34
+ yield
35
+ ensure
36
+ @stack = saved
37
+ end
38
+ end
39
+ end
40
+
41
+ def record(annotation)
42
+ tracer.record(id, annotation) unless stack.empty?
43
+ end
44
+
45
+ def set_rpc_name(name)
46
+ tracer.set_rpc_name(id, name) unless stack.empty?
47
+ end
48
+
49
+ def sample_rate=(sample_rate)
50
+ if sample_rate > 1 || sample_rate < 0
51
+ raise ArgumentError.new("sample rate must be [0,1]")
52
+ end
53
+ @sample_rate = sample_rate
54
+ end
55
+
56
+ def tracer=(tracer)
57
+ @tracer = tracer
58
+ end
59
+
60
+ class TraceId
61
+ attr_reader :trace_id, :parent_id, :span_id, :sampled
62
+ alias :sampled? :sampled
63
+ def initialize(trace_id, parent_id, span_id, sampled)
64
+ @trace_id = SpanId.from_value(trace_id)
65
+ @parent_id = parent_id.nil? ? nil : SpanId.from_value(parent_id)
66
+ @span_id = SpanId.from_value(span_id)
67
+ @sampled = !!sampled
68
+ end
69
+
70
+ def next_id
71
+ TraceId.new(@trace_id, @span_id, Trace.generate_id, @sampled)
72
+ end
73
+
74
+ def to_s
75
+ "TraceId(trace_id = #{@trace_id.to_s}, parent_id = #{@parent_id.to_s}, span_id = #{@span_id.to_s}, sampled = #{@sampled.to_s})"
76
+ end
77
+ end
78
+
79
+ class SpanId
80
+ HEX_REGEX = /^[a-f0-9]{16}$/i
81
+ MAX_SIGNED_I64 = 9223372036854775807
82
+ MASK = (2 ** 64) - 1
83
+
84
+ def self.from_value(v)
85
+ if v.is_a?(String) && v =~ HEX_REGEX
86
+ new(v.hex)
87
+ elsif v.is_a?(Numeric)
88
+ new(v)
89
+ elsif v.is_a?(SpanId)
90
+ v
91
+ end
92
+ end
93
+
94
+ def initialize(value)
95
+ @value = value
96
+ @i64 = if @value > MAX_SIGNED_I64
97
+ -1 * ((@value ^ MASK) + 1)
98
+ else
99
+ @value
100
+ end
101
+ end
102
+
103
+ def to_s; "%016x" % @value; end
104
+ def to_i; @i64; end
105
+ end
106
+
107
+ def generate_id
108
+ rand(TRACE_ID_UPPER_BOUND)
109
+ end
110
+
111
+ def should_sample?
112
+ rand < (@sample_rate || DEFAULT_SAMPLE_RATE)
113
+ end
114
+
115
+ def default_endpoint=(endpoint)
116
+ @default_endpoint = endpoint
117
+ end
118
+
119
+ def default_endpoint
120
+ @default_endpoint ||= begin
121
+ Endpoint.new(Endpoint.host_to_i32(Socket.gethostname), 0, "finagle-ruby")
122
+ end
123
+ end
124
+
125
+ private
126
+
127
+ def stack
128
+ @stack ||= []
129
+ end
130
+
131
+ def tracer
132
+ @tracer ||= NullTracer.new
133
+ end
134
+
135
+ end
@@ -0,0 +1,245 @@
1
+ module Trace
2
+ class Tracer
3
+ def record(id, annotation)
4
+ raise "not implemented"
5
+ end
6
+
7
+ def set_rpc_name(id, name)
8
+ raise "not implemented"
9
+ end
10
+ end
11
+
12
+ class NullTracer < Tracer
13
+ def record(id, annotation)
14
+ end
15
+
16
+ def set_rpc_name(id, name)
17
+ end
18
+ end
19
+
20
+ class FanoutTracer < Tracer
21
+ def initialize(tracers)
22
+ @tracers = tracers
23
+ end
24
+
25
+ def record(id, annotation)
26
+ @tracers.each { |tracer| tracer.record(id, annotation) }
27
+ end
28
+
29
+ def set_rpc_name(id, name)
30
+ @tracers.each { |tracer| tracer.set_rpc_name(id, name) }
31
+ end
32
+ end
33
+
34
+ class FileTracer < Tracer
35
+ def initialize
36
+ @last_trace_id = nil
37
+ @file = nil
38
+ end
39
+
40
+ def record(id, annotation)
41
+ return unless id.sampled?
42
+ file = get_file_for_id(id)
43
+ file.puts("#{id.to_s}: #{annotation.to_s}")
44
+ file.flush if (annotation.is_a?(Annotation) && annotation.value == Annotation::SERVER_SEND)
45
+ end
46
+
47
+ def set_rpc_name(id, name)
48
+ return unless id.sampled?
49
+ get_file_for_id(id).puts("#{id.to_s}: name = #{name}")
50
+ end
51
+
52
+ private
53
+ def get_file_for_id(id)
54
+ id = id.trace_id.to_i
55
+ if @last_trace_id != id
56
+ @last_trace_id = id
57
+ @file.close if @file
58
+ @file = File.open("/tmp/traces/#{id}.log", "a")
59
+ end
60
+ @file
61
+ end
62
+ end
63
+
64
+ class ZipkinTracer < Tracer
65
+ TRACER_CATEGORY = "zipkin"
66
+ def initialize(scribe, max_buffer)
67
+ @scribe = scribe
68
+ @max_buffer = max_buffer
69
+ reset
70
+ end
71
+
72
+ def record(id, annotation)
73
+ return unless id.sampled?
74
+ span = get_span_for_id(id)
75
+
76
+ case annotation
77
+ when BinaryAnnotation
78
+ span.binary_annotations << annotation
79
+ when Annotation
80
+ span.annotations << annotation
81
+ end
82
+
83
+ @count += 1
84
+ if @count >= @max_buffer || (annotation.is_a?(Annotation) && annotation.value == Annotation::SERVER_SEND)
85
+ flush!
86
+ end
87
+ end
88
+
89
+ def set_rpc_name(id, name)
90
+ return unless id.sampled?
91
+ span = get_span_for_id(id)
92
+ span.name = name.to_s
93
+ end
94
+
95
+ private
96
+ def get_span_for_id(id)
97
+ key = id.span_id.to_s
98
+ @spans[key] ||= begin
99
+ Span.new("", id)
100
+ end
101
+ end
102
+
103
+ def reset
104
+ @count = 0
105
+ @spans = {}
106
+ end
107
+
108
+ def flush!
109
+ @scribe.batch do
110
+ messages = @spans.values.map do |span|
111
+ buf = ''
112
+ trans = Thrift::MemoryBufferTransport.new(buf)
113
+ oprot = Thrift::BinaryProtocol.new(trans)
114
+ span.to_thrift.write(oprot)
115
+ binary = Base64.encode64(buf).gsub("\n", "")
116
+ @scribe.log(binary, TRACER_CATEGORY)
117
+ end
118
+ end
119
+ reset
120
+ end
121
+ end
122
+
123
+ class Span
124
+ attr_accessor :name, :annotations, :binary_annotations
125
+ def initialize(name, span_id)
126
+ @name = name
127
+ @span_id = span_id
128
+ @annotations = []
129
+ @binary_annotations = []
130
+ end
131
+
132
+ def to_thrift
133
+ FinagleThrift::Span.new(
134
+ :name => @name,
135
+ :trace_id => @span_id.trace_id.to_i,
136
+ :id => @span_id.span_id.to_i,
137
+ :parent_id => @span_id.parent_id.nil? ? nil : @span_id.parent_id.to_i,
138
+ :annotations => @annotations.map { |a| a.to_thrift },
139
+ :binary_annotations => @binary_annotations.map { |a| a.to_thrift }
140
+ )
141
+ end
142
+ end
143
+
144
+ class Annotation
145
+ CLIENT_SEND = "cs"
146
+ CLIENT_RECV = "cr"
147
+ SERVER_SEND = "ss"
148
+ SERVER_RECV = "sr"
149
+
150
+ attr_reader :value, :host, :timestamp
151
+ def initialize(value, host)
152
+ @timestamp = (Time.now.to_f * 1000 * 1000).to_i # micros
153
+ @value = value
154
+ @host = host
155
+ end
156
+
157
+ def to_thrift
158
+ thrift_host = host ? host.to_thrift : nil
159
+ FinagleThrift::Annotation.new(
160
+ :value => @value,
161
+ :host => thrift_host,
162
+ :timestamp => @timestamp
163
+ )
164
+ end
165
+
166
+ def to_s
167
+ "#{@value} at #{@timestamp} for (#{@host.to_s})"
168
+ end
169
+ end
170
+
171
+ class BinaryAnnotation
172
+ module Type
173
+ BOOL = "BOOL"
174
+ BYTES = "BYTES"
175
+ I16 = "I16"
176
+ I32 = "I32"
177
+ I64 = "I64"
178
+ DOUBLE = "DOUBLE"
179
+ STRING = "STRING"
180
+
181
+ def self.to_thrift(v)
182
+ FinagleThrift::AnnotationType::VALUE_MAP.index(v)
183
+ end
184
+ end
185
+
186
+ attr_reader :key, :value, :host
187
+ def initialize(key, value, annotation_type, host)
188
+ @key = key
189
+ @value = value
190
+ @annotation_type = annotation_type
191
+ @host = host
192
+ end
193
+
194
+ def to_thrift
195
+ thrift_host = host ? host.to_thrift : nil
196
+ FinagleThrift::BinaryAnnotation.new(
197
+ :key => @key,
198
+ :value => @value,
199
+ :annotation_type => Type.to_thrift(@annotation_type),
200
+ :host => thrift_host
201
+ )
202
+ end
203
+
204
+ end
205
+
206
+ class Endpoint < Struct.new(:ipv4, :port, :service_name)
207
+ MAX_I32 = ((2 ** 31) - 1)
208
+ MASK = (2 ** 32) - 1
209
+
210
+ def self.host_to_i32(host)
211
+ unsigned_i32 = Socket.getaddrinfo(host, nil)[0][3].split(".").map do |i|
212
+ i.to_i
213
+ end.inject(0) { |a,e| (a << 8) + e }
214
+
215
+ signed_i32 = if unsigned_i32 > MAX_I32
216
+ -1 * ((unsigned_i32 ^ MASK) + 1)
217
+ else
218
+ unsigned_i32
219
+ end
220
+
221
+ signed_i32
222
+ end
223
+
224
+ def with_port(port)
225
+ Endpoint.new(self.ipv4, port, self.service_name)
226
+ end
227
+
228
+ def with_service_name(service_name)
229
+ Endpoint.new(self.ipv4, self.port, service_name)
230
+ end
231
+
232
+ def to_thrift
233
+ FinagleThrift::Endpoint.new(
234
+ :ipv4 => self.ipv4,
235
+ :port => self.port,
236
+ :service_name => self.service_name
237
+ )
238
+ end
239
+
240
+ def to_s
241
+ "#{service_name}@#{ipv4}:#{port}"
242
+ end
243
+ end
244
+
245
+ end
@@ -0,0 +1,3 @@
1
+ module FinagleThrift
2
+ VERSION = "1.2.0"
3
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: finagle-thrift
3
+ version: !ruby/object:Gem::Version
4
+ hash: 31
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 2
9
+ - 0
10
+ version: 1.2.0
11
+ platform: ruby
12
+ authors:
13
+ - Arya Asemanfar
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-05-25 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description: A Ruby client library for integrating into finagle's thrift tracing protocol
22
+ email:
23
+ - arya@twitter.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - lib/finagle-thrift/client.rb
32
+ - lib/finagle-thrift/thrift/tracing_constants.rb
33
+ - lib/finagle-thrift/thrift/tracing_types.rb
34
+ - lib/finagle-thrift/thrift_client.rb
35
+ - lib/finagle-thrift/trace.rb
36
+ - lib/finagle-thrift/tracer.rb
37
+ - lib/finagle-thrift/version.rb
38
+ - lib/finagle-thrift.rb
39
+ homepage:
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ hash: 3
53
+ segments:
54
+ - 0
55
+ version: "0"
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 17
62
+ segments:
63
+ - 1
64
+ - 3
65
+ - 5
66
+ version: 1.3.5
67
+ requirements: []
68
+
69
+ rubyforge_project:
70
+ rubygems_version: 1.8.15
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: ""
74
+ test_files: []
75
+