upfluence-thrift 1.0.1

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.
Files changed (128) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +43 -0
  3. data/benchmark/Benchmark.thrift +24 -0
  4. data/benchmark/benchmark.rb +271 -0
  5. data/benchmark/client.rb +74 -0
  6. data/benchmark/gen-rb/benchmark_constants.rb +11 -0
  7. data/benchmark/gen-rb/benchmark_service.rb +80 -0
  8. data/benchmark/gen-rb/benchmark_types.rb +10 -0
  9. data/benchmark/server.rb +82 -0
  10. data/benchmark/thin_server.rb +44 -0
  11. data/ext/binary_protocol_accelerated.c +460 -0
  12. data/ext/binary_protocol_accelerated.h +20 -0
  13. data/ext/bytes.c +36 -0
  14. data/ext/bytes.h +31 -0
  15. data/ext/compact_protocol.c +637 -0
  16. data/ext/compact_protocol.h +20 -0
  17. data/ext/constants.h +99 -0
  18. data/ext/extconf.rb +34 -0
  19. data/ext/macros.h +41 -0
  20. data/ext/memory_buffer.c +134 -0
  21. data/ext/memory_buffer.h +20 -0
  22. data/ext/protocol.c +0 -0
  23. data/ext/protocol.h +0 -0
  24. data/ext/strlcpy.c +41 -0
  25. data/ext/strlcpy.h +34 -0
  26. data/ext/struct.c +707 -0
  27. data/ext/struct.h +25 -0
  28. data/ext/thrift_native.c +201 -0
  29. data/lib/thrift.rb +68 -0
  30. data/lib/thrift/bytes.rb +131 -0
  31. data/lib/thrift/client.rb +71 -0
  32. data/lib/thrift/core_ext.rb +23 -0
  33. data/lib/thrift/core_ext/fixnum.rb +29 -0
  34. data/lib/thrift/exceptions.rb +87 -0
  35. data/lib/thrift/multiplexed_processor.rb +76 -0
  36. data/lib/thrift/processor.rb +57 -0
  37. data/lib/thrift/protocol/base_protocol.rb +379 -0
  38. data/lib/thrift/protocol/binary_protocol.rb +237 -0
  39. data/lib/thrift/protocol/binary_protocol_accelerated.rb +39 -0
  40. data/lib/thrift/protocol/compact_protocol.rb +435 -0
  41. data/lib/thrift/protocol/json_protocol.rb +769 -0
  42. data/lib/thrift/protocol/multiplexed_protocol.rb +40 -0
  43. data/lib/thrift/protocol/protocol_decorator.rb +194 -0
  44. data/lib/thrift/serializer/deserializer.rb +33 -0
  45. data/lib/thrift/serializer/serializer.rb +34 -0
  46. data/lib/thrift/server/base_server.rb +31 -0
  47. data/lib/thrift/server/mongrel_http_server.rb +60 -0
  48. data/lib/thrift/server/nonblocking_server.rb +305 -0
  49. data/lib/thrift/server/rack_application.rb +61 -0
  50. data/lib/thrift/server/simple_server.rb +43 -0
  51. data/lib/thrift/server/thin_http_server.rb +51 -0
  52. data/lib/thrift/server/thread_pool_server.rb +75 -0
  53. data/lib/thrift/server/threaded_server.rb +47 -0
  54. data/lib/thrift/struct.rb +237 -0
  55. data/lib/thrift/struct_union.rb +192 -0
  56. data/lib/thrift/thrift_native.rb +24 -0
  57. data/lib/thrift/transport/base_server_transport.rb +37 -0
  58. data/lib/thrift/transport/base_transport.rb +109 -0
  59. data/lib/thrift/transport/buffered_transport.rb +114 -0
  60. data/lib/thrift/transport/framed_transport.rb +117 -0
  61. data/lib/thrift/transport/http_client_transport.rb +56 -0
  62. data/lib/thrift/transport/io_stream_transport.rb +39 -0
  63. data/lib/thrift/transport/memory_buffer_transport.rb +125 -0
  64. data/lib/thrift/transport/server_socket.rb +63 -0
  65. data/lib/thrift/transport/socket.rb +139 -0
  66. data/lib/thrift/transport/unix_server_socket.rb +60 -0
  67. data/lib/thrift/transport/unix_socket.rb +40 -0
  68. data/lib/thrift/types.rb +101 -0
  69. data/lib/thrift/union.rb +179 -0
  70. data/spec/BaseService.thrift +27 -0
  71. data/spec/ExtendedService.thrift +25 -0
  72. data/spec/Referenced.thrift +44 -0
  73. data/spec/ThriftNamespacedSpec.thrift +53 -0
  74. data/spec/ThriftSpec.thrift +183 -0
  75. data/spec/base_protocol_spec.rb +217 -0
  76. data/spec/base_transport_spec.rb +350 -0
  77. data/spec/binary_protocol_accelerated_spec.rb +42 -0
  78. data/spec/binary_protocol_spec.rb +66 -0
  79. data/spec/binary_protocol_spec_shared.rb +455 -0
  80. data/spec/bytes_spec.rb +160 -0
  81. data/spec/client_spec.rb +99 -0
  82. data/spec/compact_protocol_spec.rb +143 -0
  83. data/spec/exception_spec.rb +141 -0
  84. data/spec/flat_spec.rb +62 -0
  85. data/spec/gen-rb/base/base_service.rb +80 -0
  86. data/spec/gen-rb/base/base_service_constants.rb +11 -0
  87. data/spec/gen-rb/base/base_service_types.rb +26 -0
  88. data/spec/gen-rb/extended/extended_service.rb +78 -0
  89. data/spec/gen-rb/extended/extended_service_constants.rb +11 -0
  90. data/spec/gen-rb/extended/extended_service_types.rb +12 -0
  91. data/spec/gen-rb/flat/namespaced_nonblocking_service.rb +272 -0
  92. data/spec/gen-rb/flat/referenced_constants.rb +11 -0
  93. data/spec/gen-rb/flat/referenced_types.rb +17 -0
  94. data/spec/gen-rb/flat/thrift_namespaced_spec_constants.rb +11 -0
  95. data/spec/gen-rb/flat/thrift_namespaced_spec_types.rb +28 -0
  96. data/spec/gen-rb/namespaced_spec_namespace/namespaced_nonblocking_service.rb +272 -0
  97. data/spec/gen-rb/namespaced_spec_namespace/thrift_namespaced_spec_constants.rb +11 -0
  98. data/spec/gen-rb/namespaced_spec_namespace/thrift_namespaced_spec_types.rb +28 -0
  99. data/spec/gen-rb/nonblocking_service.rb +272 -0
  100. data/spec/gen-rb/other_namespace/referenced_constants.rb +11 -0
  101. data/spec/gen-rb/other_namespace/referenced_types.rb +17 -0
  102. data/spec/gen-rb/thrift_spec_constants.rb +11 -0
  103. data/spec/gen-rb/thrift_spec_types.rb +538 -0
  104. data/spec/http_client_spec.rb +120 -0
  105. data/spec/json_protocol_spec.rb +513 -0
  106. data/spec/namespaced_spec.rb +67 -0
  107. data/spec/nonblocking_server_spec.rb +263 -0
  108. data/spec/processor_spec.rb +80 -0
  109. data/spec/serializer_spec.rb +67 -0
  110. data/spec/server_socket_spec.rb +79 -0
  111. data/spec/server_spec.rb +147 -0
  112. data/spec/socket_spec.rb +61 -0
  113. data/spec/socket_spec_shared.rb +104 -0
  114. data/spec/spec_helper.rb +64 -0
  115. data/spec/struct_nested_containers_spec.rb +191 -0
  116. data/spec/struct_spec.rb +293 -0
  117. data/spec/thin_http_server_spec.rb +141 -0
  118. data/spec/types_spec.rb +115 -0
  119. data/spec/union_spec.rb +203 -0
  120. data/spec/unix_socket_spec.rb +107 -0
  121. data/test/debug_proto/gen-rb/debug_proto_test_constants.rb +274 -0
  122. data/test/debug_proto/gen-rb/debug_proto_test_types.rb +761 -0
  123. data/test/debug_proto/gen-rb/empty_service.rb +24 -0
  124. data/test/debug_proto/gen-rb/inherited.rb +79 -0
  125. data/test/debug_proto/gen-rb/reverse_order_service.rb +82 -0
  126. data/test/debug_proto/gen-rb/service_for_exception_with_a_map.rb +81 -0
  127. data/test/debug_proto/gen-rb/srv.rb +330 -0
  128. metadata +388 -0
@@ -0,0 +1,61 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one
3
+ # or more contributor license agreements. See the NOTICE file
4
+ # distributed with this work for additional information
5
+ # regarding copyright ownership. The ASF licenses this file
6
+ # to you under the Apache License, Version 2.0 (the
7
+ # "License"); you may not use this file except in compliance
8
+ # with the License. You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing,
13
+ # software distributed under the License is distributed on an
14
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ # KIND, either express or implied. See the License for the
16
+ # specific language governing permissions and limitations
17
+ # under the License.
18
+ #
19
+
20
+ require 'rack'
21
+
22
+ module Thrift
23
+ class RackApplication
24
+
25
+ THRIFT_HEADER = "application/x-thrift"
26
+
27
+ def self.for(path, processor, protocol_factory)
28
+ Rack::Builder.new do
29
+ use Rack::CommonLogger
30
+ use Rack::ShowExceptions
31
+ use Rack::Lint
32
+ map path do
33
+ run lambda { |env|
34
+ request = Rack::Request.new(env)
35
+ if RackApplication.valid_thrift_request?(request)
36
+ RackApplication.successful_request(request, processor, protocol_factory)
37
+ else
38
+ RackApplication.failed_request
39
+ end
40
+ }
41
+ end
42
+ end
43
+ end
44
+
45
+ def self.successful_request(rack_request, processor, protocol_factory)
46
+ response = Rack::Response.new([], 200, {'Content-Type' => THRIFT_HEADER})
47
+ transport = IOStreamTransport.new rack_request.body, response
48
+ protocol = protocol_factory.get_protocol transport
49
+ processor.process protocol, protocol
50
+ response
51
+ end
52
+
53
+ def self.failed_request
54
+ Rack::Response.new(['Not Found'], 404, {'Content-Type' => THRIFT_HEADER})
55
+ end
56
+
57
+ def self.valid_thrift_request?(rack_request)
58
+ rack_request.post? && rack_request.env["CONTENT_TYPE"] == THRIFT_HEADER
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,43 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one
3
+ # or more contributor license agreements. See the NOTICE file
4
+ # distributed with this work for additional information
5
+ # regarding copyright ownership. The ASF licenses this file
6
+ # to you under the Apache License, Version 2.0 (the
7
+ # "License"); you may not use this file except in compliance
8
+ # with the License. You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing,
13
+ # software distributed under the License is distributed on an
14
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ # KIND, either express or implied. See the License for the
16
+ # specific language governing permissions and limitations
17
+ # under the License.
18
+ #
19
+
20
+ module Thrift
21
+ class SimpleServer < BaseServer
22
+ def serve
23
+ begin
24
+ @server_transport.listen
25
+ loop do
26
+ client = @server_transport.accept
27
+ trans = @transport_factory.get_transport(client)
28
+ prot = @protocol_factory.get_protocol(trans)
29
+ begin
30
+ loop do
31
+ @processor.process(prot, prot)
32
+ end
33
+ rescue Thrift::TransportException, Thrift::ProtocolException
34
+ ensure
35
+ trans.close
36
+ end
37
+ end
38
+ ensure
39
+ @server_transport.close
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,51 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one
3
+ # or more contributor license agreements. See the NOTICE file
4
+ # distributed with this work for additional information
5
+ # regarding copyright ownership. The ASF licenses this file
6
+ # to you under the Apache License, Version 2.0 (the
7
+ # "License"); you may not use this file except in compliance
8
+ # with the License. You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing,
13
+ # software distributed under the License is distributed on an
14
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ # KIND, either express or implied. See the License for the
16
+ # specific language governing permissions and limitations
17
+ # under the License.
18
+ #
19
+
20
+ require 'rack'
21
+ require 'thin'
22
+ require 'thrift/server/rack_application'
23
+
24
+ ##
25
+ # Wraps the Thin web server to provide a Thrift server over HTTP.
26
+ module Thrift
27
+ class ThinHTTPServer < BaseServer
28
+
29
+ ##
30
+ # Accepts a Thrift::Processor
31
+ # Options include:
32
+ # * :port
33
+ # * :ip
34
+ # * :path
35
+ # * :protocol_factory
36
+ def initialize(processor, options={})
37
+ port = options[:port] || 80
38
+ ip = options[:ip] || "0.0.0.0"
39
+ path = options[:path] || "/"
40
+ protocol_factory = options[:protocol_factory] || BinaryProtocolFactory.new
41
+ app = RackApplication.for(path, processor, protocol_factory)
42
+ @server = Thin::Server.new(ip, port, app)
43
+ end
44
+
45
+ ##
46
+ # Starts the server
47
+ def serve
48
+ @server.start
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,75 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one
3
+ # or more contributor license agreements. See the NOTICE file
4
+ # distributed with this work for additional information
5
+ # regarding copyright ownership. The ASF licenses this file
6
+ # to you under the Apache License, Version 2.0 (the
7
+ # "License"); you may not use this file except in compliance
8
+ # with the License. You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing,
13
+ # software distributed under the License is distributed on an
14
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ # KIND, either express or implied. See the License for the
16
+ # specific language governing permissions and limitations
17
+ # under the License.
18
+ #
19
+
20
+ require 'thread'
21
+
22
+ module Thrift
23
+ class ThreadPoolServer < BaseServer
24
+ def initialize(processor, server_transport, transport_factory=nil, protocol_factory=nil, num=20)
25
+ super(processor, server_transport, transport_factory, protocol_factory)
26
+ @thread_q = SizedQueue.new(num)
27
+ @exception_q = Queue.new
28
+ @running = false
29
+ end
30
+
31
+ ## exceptions that happen in worker threads will be relayed here and
32
+ ## must be caught. 'retry' can be used to continue. (threads will
33
+ ## continue to run while the exception is being handled.)
34
+ def rescuable_serve
35
+ Thread.new { serve } unless @running
36
+ @running = true
37
+ raise @exception_q.pop
38
+ end
39
+
40
+ ## exceptions that happen in worker threads simply cause that thread
41
+ ## to die and another to be spawned in its place.
42
+ def serve
43
+ @server_transport.listen
44
+
45
+ begin
46
+ loop do
47
+ @thread_q.push(:token)
48
+ Thread.new do
49
+ begin
50
+ loop do
51
+ client = @server_transport.accept
52
+ trans = @transport_factory.get_transport(client)
53
+ prot = @protocol_factory.get_protocol(trans)
54
+ begin
55
+ loop do
56
+ @processor.process(prot, prot)
57
+ end
58
+ rescue Thrift::TransportException, Thrift::ProtocolException => e
59
+ ensure
60
+ trans.close
61
+ end
62
+ end
63
+ rescue => e
64
+ @exception_q.push(e)
65
+ ensure
66
+ @thread_q.pop # thread died!
67
+ end
68
+ end
69
+ end
70
+ ensure
71
+ @server_transport.close
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,47 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one
3
+ # or more contributor license agreements. See the NOTICE file
4
+ # distributed with this work for additional information
5
+ # regarding copyright ownership. The ASF licenses this file
6
+ # to you under the Apache License, Version 2.0 (the
7
+ # "License"); you may not use this file except in compliance
8
+ # with the License. You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing,
13
+ # software distributed under the License is distributed on an
14
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ # KIND, either express or implied. See the License for the
16
+ # specific language governing permissions and limitations
17
+ # under the License.
18
+ #
19
+
20
+ require 'thread'
21
+
22
+ module Thrift
23
+ class ThreadedServer < BaseServer
24
+ def serve
25
+ begin
26
+ @server_transport.listen
27
+ loop do
28
+ client = @server_transport.accept
29
+ trans = @transport_factory.get_transport(client)
30
+ prot = @protocol_factory.get_protocol(trans)
31
+ Thread.new(prot, trans) do |p, t|
32
+ begin
33
+ loop do
34
+ @processor.process(p, p)
35
+ end
36
+ rescue Thrift::TransportException, Thrift::ProtocolException
37
+ ensure
38
+ t.close
39
+ end
40
+ end
41
+ end
42
+ ensure
43
+ @server_transport.close
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,237 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one
3
+ # or more contributor license agreements. See the NOTICE file
4
+ # distributed with this work for additional information
5
+ # regarding copyright ownership. The ASF licenses this file
6
+ # to you under the Apache License, Version 2.0 (the
7
+ # "License"); you may not use this file except in compliance
8
+ # with the License. You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing,
13
+ # software distributed under the License is distributed on an
14
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ # KIND, either express or implied. See the License for the
16
+ # specific language governing permissions and limitations
17
+ # under the License.
18
+ #
19
+
20
+ require 'set'
21
+
22
+ module Thrift
23
+ module Struct
24
+ def initialize(d={}, &block)
25
+ # get a copy of the default values to work on, removing defaults in favor of arguments
26
+ fields_with_defaults = fields_with_default_values.dup
27
+
28
+ # check if the defaults is empty, or if there are no parameters for this
29
+ # instantiation, and if so, don't bother overriding defaults.
30
+ unless fields_with_defaults.empty? || d.empty?
31
+ d.each_key do |name|
32
+ fields_with_defaults.delete(name.to_s)
33
+ end
34
+ end
35
+
36
+ # assign all the user-specified arguments
37
+ unless d.empty?
38
+ d.each do |name, value|
39
+ unless name_to_id(name.to_s)
40
+ raise Exception, "Unknown key given to #{self.class}.new: #{name}"
41
+ end
42
+ Thrift.check_type(value, struct_fields[name_to_id(name.to_s)], name) if Thrift.type_checking
43
+ instance_variable_set("@#{name}", value)
44
+ end
45
+ end
46
+
47
+ # assign all the default values
48
+ unless fields_with_defaults.empty?
49
+ fields_with_defaults.each do |name, default_value|
50
+ instance_variable_set("@#{name}", (default_value.dup rescue default_value))
51
+ end
52
+ end
53
+
54
+ yield self if block_given?
55
+ end
56
+
57
+ def fields_with_default_values
58
+ fields_with_default_values = self.class.instance_variable_get(:@fields_with_default_values)
59
+ unless fields_with_default_values
60
+ fields_with_default_values = {}
61
+ struct_fields.each do |fid, field_def|
62
+ unless field_def[:default].nil?
63
+ fields_with_default_values[field_def[:name]] = field_def[:default]
64
+ end
65
+ end
66
+ self.class.instance_variable_set(:@fields_with_default_values, fields_with_default_values)
67
+ end
68
+ fields_with_default_values
69
+ end
70
+
71
+ def inspect(skip_optional_nulls = true)
72
+ fields = []
73
+ each_field do |fid, field_info|
74
+ name = field_info[:name]
75
+ value = instance_variable_get("@#{name}")
76
+ unless skip_optional_nulls && field_info[:optional] && value.nil?
77
+ fields << "#{name}:#{inspect_field(value, field_info)}"
78
+ end
79
+ end
80
+ "<#{self.class} #{fields.join(", ")}>"
81
+ end
82
+
83
+ def read(iprot)
84
+ iprot.read_struct_begin
85
+ loop do
86
+ fname, ftype, fid = iprot.read_field_begin
87
+ break if (ftype == Types::STOP)
88
+ handle_message(iprot, fid, ftype)
89
+ iprot.read_field_end
90
+ end
91
+ iprot.read_struct_end
92
+ validate
93
+ end
94
+
95
+ def write(oprot)
96
+ validate
97
+ oprot.write_struct_begin(self.class.name)
98
+ each_field do |fid, field_info|
99
+ name = field_info[:name]
100
+ type = field_info[:type]
101
+ value = instance_variable_get("@#{name}")
102
+ unless value.nil?
103
+ if is_container? type
104
+ oprot.write_field_begin(name, type, fid)
105
+ write_container(oprot, value, field_info)
106
+ oprot.write_field_end
107
+ else
108
+ oprot.write_field(field_info, fid, value)
109
+ end
110
+ end
111
+ end
112
+ oprot.write_field_stop
113
+ oprot.write_struct_end
114
+ end
115
+
116
+ def ==(other)
117
+ return false if other.nil?
118
+ each_field do |fid, field_info|
119
+ name = field_info[:name]
120
+ return false unless other.respond_to?(name) && self.send(name) == other.send(name)
121
+ end
122
+ true
123
+ end
124
+
125
+ def eql?(other)
126
+ self.class == other.class && self == other
127
+ end
128
+
129
+ # This implementation of hash() is inspired by Apache's Java HashCodeBuilder class.
130
+ def hash
131
+ total = 17
132
+ each_field do |fid, field_info|
133
+ name = field_info[:name]
134
+ value = self.send(name)
135
+ total = (total * 37 + value.hash) & 0xffffffff
136
+ end
137
+ total
138
+ end
139
+
140
+ def differences(other)
141
+ diffs = []
142
+ unless other.is_a?(self.class)
143
+ diffs << "Different class!"
144
+ else
145
+ each_field do |fid, field_info|
146
+ name = field_info[:name]
147
+ diffs << "#{name} differs!" unless self.instance_variable_get("@#{name}") == other.instance_variable_get("@#{name}")
148
+ end
149
+ end
150
+ diffs
151
+ end
152
+
153
+ def self.field_accessor(klass, field_info)
154
+ field_name_sym = field_info[:name].to_sym
155
+ klass.send :attr_reader, field_name_sym
156
+ klass.send :define_method, "#{field_info[:name]}=" do |value|
157
+ Thrift.check_type(value, field_info, field_info[:name]) if Thrift.type_checking
158
+ instance_variable_set("@#{field_name_sym}", value)
159
+ end
160
+ end
161
+
162
+ def self.generate_accessors(klass)
163
+ klass::FIELDS.values.each do |field_info|
164
+ field_accessor(klass, field_info)
165
+ qmark_isset_method(klass, field_info)
166
+ end
167
+ end
168
+
169
+ def self.qmark_isset_method(klass, field_info)
170
+ klass.send :define_method, "#{field_info[:name]}?" do
171
+ !self.send(field_info[:name].to_sym).nil?
172
+ end
173
+ end
174
+
175
+ def <=>(other)
176
+ if self.class == other.class
177
+ each_field do |fid, field_info|
178
+ v1 = self.send(field_info[:name])
179
+ v1_set = !v1.nil?
180
+ v2 = other.send(field_info[:name])
181
+ v2_set = !v2.nil?
182
+ if v1_set && !v2_set
183
+ return -1
184
+ elsif !v1_set && v2_set
185
+ return 1
186
+ elsif v1_set && v2_set
187
+ cmp = v1 <=> v2
188
+ if cmp != 0
189
+ return cmp
190
+ end
191
+ end
192
+ end
193
+ 0
194
+ else
195
+ self.class <=> other.class
196
+ end
197
+ end
198
+
199
+ protected
200
+
201
+ def self.append_features(mod)
202
+ if mod.ancestors.include? ::Exception
203
+ mod.send :class_variable_set, :'@@__thrift_struct_real_initialize', mod.instance_method(:initialize)
204
+ super
205
+ # set up our custom initializer so `raise Xception, 'message'` works
206
+ mod.send :define_method, :struct_initialize, mod.instance_method(:initialize)
207
+ mod.send :define_method, :initialize, mod.instance_method(:exception_initialize)
208
+ else
209
+ super
210
+ end
211
+ end
212
+
213
+ def exception_initialize(*args, &block)
214
+ if args.size == 1 and args.first.is_a? Hash
215
+ # looks like it's a regular Struct initialize
216
+ method(:struct_initialize).call(args.first)
217
+ else
218
+ # call the Struct initializer first with no args
219
+ # this will set our field default values
220
+ method(:struct_initialize).call()
221
+ # now give it to the exception
222
+ self.class.send(:class_variable_get, :'@@__thrift_struct_real_initialize').bind(self).call(*args, &block) if args.size > 0
223
+ # self.class.instance_method(:initialize).bind(self).call(*args, &block)
224
+ end
225
+ end
226
+
227
+ def handle_message(iprot, fid, ftype)
228
+ field = struct_fields[fid]
229
+ if field and field[:type] == ftype
230
+ value = read_field(iprot, field)
231
+ instance_variable_set("@#{field[:name]}", value)
232
+ else
233
+ iprot.skip(ftype)
234
+ end
235
+ end
236
+ end
237
+ end