log4ever 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.gitignore +2 -1
  2. data/Gemfile +2 -1
  3. data/Gemfile.lock +7 -1
  4. data/README.md +3 -1
  5. data/lib/log4r/evernote.rb +10 -24
  6. data/lib/log4r/outputter/evernoteoutputter.rb +3 -11
  7. data/log4ever.gemspec +2 -1
  8. data/spec/log4ever_spec.rb +24 -17
  9. metadata +40 -58
  10. data/.project +0 -11
  11. data/lib/log4r/evernote/lib/Evernote/EDAM/errors_constants.rb +0 -14
  12. data/lib/log4r/evernote/lib/Evernote/EDAM/errors_types.rb +0 -128
  13. data/lib/log4r/evernote/lib/Evernote/EDAM/limits_constants.rb +0 -240
  14. data/lib/log4r/evernote/lib/Evernote/EDAM/limits_types.rb +0 -13
  15. data/lib/log4r/evernote/lib/Evernote/EDAM/note_store.rb +0 -5487
  16. data/lib/log4r/evernote/lib/Evernote/EDAM/note_store_constants.rb +0 -14
  17. data/lib/log4r/evernote/lib/Evernote/EDAM/note_store_types.rb +0 -1012
  18. data/lib/log4r/evernote/lib/Evernote/EDAM/types_constants.rb +0 -20
  19. data/lib/log4r/evernote/lib/Evernote/EDAM/types_types.rb +0 -1792
  20. data/lib/log4r/evernote/lib/Evernote/EDAM/user_store.rb +0 -549
  21. data/lib/log4r/evernote/lib/Evernote/EDAM/user_store_constants.rb +0 -18
  22. data/lib/log4r/evernote/lib/Evernote/EDAM/user_store_types.rb +0 -415
  23. data/lib/log4r/evernote/lib/thrift/client.rb +0 -62
  24. data/lib/log4r/evernote/lib/thrift/core_ext/fixnum.rb +0 -29
  25. data/lib/log4r/evernote/lib/thrift/core_ext.rb +0 -23
  26. data/lib/log4r/evernote/lib/thrift/exceptions.rb +0 -84
  27. data/lib/log4r/evernote/lib/thrift/processor.rb +0 -57
  28. data/lib/log4r/evernote/lib/thrift/protocol/base_protocol.rb +0 -290
  29. data/lib/log4r/evernote/lib/thrift/protocol/binary_protocol.rb +0 -229
  30. data/lib/log4r/evernote/lib/thrift/protocol/binary_protocol_accelerated.rb +0 -39
  31. data/lib/log4r/evernote/lib/thrift/protocol/compact_protocol.rb +0 -426
  32. data/lib/log4r/evernote/lib/thrift/serializer/deserializer.rb +0 -33
  33. data/lib/log4r/evernote/lib/thrift/serializer/serializer.rb +0 -34
  34. data/lib/log4r/evernote/lib/thrift/server/base_server.rb +0 -31
  35. data/lib/log4r/evernote/lib/thrift/server/mongrel_http_server.rb +0 -58
  36. data/lib/log4r/evernote/lib/thrift/server/nonblocking_server.rb +0 -305
  37. data/lib/log4r/evernote/lib/thrift/server/simple_server.rb +0 -43
  38. data/lib/log4r/evernote/lib/thrift/server/thread_pool_server.rb +0 -75
  39. data/lib/log4r/evernote/lib/thrift/server/threaded_server.rb +0 -47
  40. data/lib/log4r/evernote/lib/thrift/struct.rb +0 -237
  41. data/lib/log4r/evernote/lib/thrift/struct_union.rb +0 -192
  42. data/lib/log4r/evernote/lib/thrift/thrift_native.rb +0 -24
  43. data/lib/log4r/evernote/lib/thrift/transport/base_server_transport.rb +0 -37
  44. data/lib/log4r/evernote/lib/thrift/transport/base_transport.rb +0 -107
  45. data/lib/log4r/evernote/lib/thrift/transport/buffered_transport.rb +0 -108
  46. data/lib/log4r/evernote/lib/thrift/transport/framed_transport.rb +0 -116
  47. data/lib/log4r/evernote/lib/thrift/transport/http_client_transport.rb +0 -53
  48. data/lib/log4r/evernote/lib/thrift/transport/io_stream_transport.rb +0 -39
  49. data/lib/log4r/evernote/lib/thrift/transport/memory_buffer_transport.rb +0 -125
  50. data/lib/log4r/evernote/lib/thrift/transport/server_socket.rb +0 -63
  51. data/lib/log4r/evernote/lib/thrift/transport/socket.rb +0 -137
  52. data/lib/log4r/evernote/lib/thrift/transport/unix_server_socket.rb +0 -60
  53. data/lib/log4r/evernote/lib/thrift/transport/unix_socket.rb +0 -40
  54. data/lib/log4r/evernote/lib/thrift/types.rb +0 -101
  55. data/lib/log4r/evernote/lib/thrift/union.rb +0 -179
  56. data/lib/log4r/evernote/lib/thrift.rb +0 -64
@@ -1,305 +0,0 @@
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 'logger'
21
- require 'thread'
22
-
23
- module Thrift
24
- # this class expects to always use a FramedTransport for reading messages
25
- class NonblockingServer < BaseServer
26
- def initialize(processor, server_transport, transport_factory=nil, protocol_factory=nil, num=20, logger=nil)
27
- super(processor, server_transport, transport_factory, protocol_factory)
28
- @num_threads = num
29
- if logger.nil?
30
- @logger = Logger.new(STDERR)
31
- @logger.level = Logger::WARN
32
- else
33
- @logger = logger
34
- end
35
- @shutdown_semaphore = Mutex.new
36
- @transport_semaphore = Mutex.new
37
- end
38
-
39
- def serve
40
- @logger.info "Starting #{self}"
41
- @server_transport.listen
42
- @io_manager = start_io_manager
43
-
44
- begin
45
- loop do
46
- break if @server_transport.closed?
47
- begin
48
- rd, = select([@server_transport], nil, nil, 0.1)
49
- rescue Errno::EBADF => e
50
- # In Ruby 1.9, calling @server_transport.close in shutdown paths causes the select() to raise an
51
- # Errno::EBADF. If this happens, ignore it and retry the loop.
52
- break
53
- end
54
- next if rd.nil?
55
- socket = @server_transport.accept
56
- @logger.debug "Accepted socket: #{socket.inspect}"
57
- @io_manager.add_connection socket
58
- end
59
- rescue IOError => e
60
- end
61
- # we must be shutting down
62
- @logger.info "#{self} is shutting down, goodbye"
63
- ensure
64
- @transport_semaphore.synchronize do
65
- @server_transport.close
66
- end
67
- @io_manager.ensure_closed unless @io_manager.nil?
68
- end
69
-
70
- def shutdown(timeout = 0, block = true)
71
- @shutdown_semaphore.synchronize do
72
- return if @is_shutdown
73
- @is_shutdown = true
74
- end
75
- # nonblocking is intended for calling from within a Handler
76
- # but we can't change the order of operations here, so lets thread
77
- shutdown_proc = lambda do
78
- @io_manager.shutdown(timeout)
79
- @transport_semaphore.synchronize do
80
- @server_transport.close # this will break the accept loop
81
- end
82
- end
83
- if block
84
- shutdown_proc.call
85
- else
86
- Thread.new &shutdown_proc
87
- end
88
- end
89
-
90
- private
91
-
92
- def start_io_manager
93
- iom = IOManager.new(@processor, @server_transport, @transport_factory, @protocol_factory, @num_threads, @logger)
94
- iom.spawn
95
- iom
96
- end
97
-
98
- class IOManager # :nodoc:
99
- DEFAULT_BUFFER = 2**20
100
-
101
- def initialize(processor, server_transport, transport_factory, protocol_factory, num, logger)
102
- @processor = processor
103
- @server_transport = server_transport
104
- @transport_factory = transport_factory
105
- @protocol_factory = protocol_factory
106
- @num_threads = num
107
- @logger = logger
108
- @connections = []
109
- @buffers = Hash.new { |h,k| h[k] = '' }
110
- @signal_queue = Queue.new
111
- @signal_pipes = IO.pipe
112
- @signal_pipes[1].sync = true
113
- @worker_queue = Queue.new
114
- @shutdown_queue = Queue.new
115
- end
116
-
117
- def add_connection(socket)
118
- signal [:connection, socket]
119
- end
120
-
121
- def spawn
122
- @iom_thread = Thread.new do
123
- @logger.debug "Starting #{self}"
124
- run
125
- end
126
- end
127
-
128
- def shutdown(timeout = 0)
129
- @logger.debug "#{self} is shutting down workers"
130
- @worker_queue.clear
131
- @num_threads.times { @worker_queue.push [:shutdown] }
132
- signal [:shutdown, timeout]
133
- @shutdown_queue.pop
134
- @signal_pipes[0].close
135
- @signal_pipes[1].close
136
- @logger.debug "#{self} is shutting down, goodbye"
137
- end
138
-
139
- def ensure_closed
140
- kill_worker_threads if @worker_threads
141
- @iom_thread.kill
142
- end
143
-
144
- private
145
-
146
- def run
147
- spin_worker_threads
148
-
149
- loop do
150
- rd, = select([@signal_pipes[0], *@connections])
151
- if rd.delete @signal_pipes[0]
152
- break if read_signals == :shutdown
153
- end
154
- rd.each do |fd|
155
- begin
156
- if fd.handle.eof?
157
- remove_connection fd
158
- else
159
- read_connection fd
160
- end
161
- rescue Errno::ECONNRESET
162
- remove_connection fd
163
- end
164
- end
165
- end
166
- join_worker_threads(@shutdown_timeout)
167
- ensure
168
- @shutdown_queue.push :shutdown
169
- end
170
-
171
- def read_connection(fd)
172
- @buffers[fd] << fd.read(DEFAULT_BUFFER)
173
- while(frame = slice_frame!(@buffers[fd]))
174
- @logger.debug "#{self} is processing a frame"
175
- @worker_queue.push [:frame, fd, frame]
176
- end
177
- end
178
-
179
- def spin_worker_threads
180
- @logger.debug "#{self} is spinning up worker threads"
181
- @worker_threads = []
182
- @num_threads.times do
183
- @worker_threads << spin_thread
184
- end
185
- end
186
-
187
- def spin_thread
188
- Worker.new(@processor, @transport_factory, @protocol_factory, @logger, @worker_queue).spawn
189
- end
190
-
191
- def signal(msg)
192
- @signal_queue << msg
193
- @signal_pipes[1].write " "
194
- end
195
-
196
- def read_signals
197
- # clear the signal pipe
198
- # note that since read_nonblock is broken in jruby,
199
- # we can only read up to a set number of signals at once
200
- sigstr = @signal_pipes[0].readpartial(1024)
201
- # now read the signals
202
- begin
203
- sigstr.length.times do
204
- signal, obj = @signal_queue.pop(true)
205
- case signal
206
- when :connection
207
- @connections << obj
208
- when :shutdown
209
- @shutdown_timeout = obj
210
- return :shutdown
211
- end
212
- end
213
- rescue ThreadError
214
- # out of signals
215
- # note that in a perfect world this would never happen, since we're
216
- # only reading the number of signals pushed on the pipe, but given the lack
217
- # of locks, in theory we could clear the pipe/queue while a new signal is being
218
- # placed on the pipe, at which point our next read_signals would hit this error
219
- end
220
- end
221
-
222
- def remove_connection(fd)
223
- # don't explicitly close it, a thread may still be writing to it
224
- @connections.delete fd
225
- @buffers.delete fd
226
- end
227
-
228
- def join_worker_threads(shutdown_timeout)
229
- start = Time.now
230
- @worker_threads.each do |t|
231
- if shutdown_timeout > 0
232
- timeout = (start + shutdown_timeout) - Time.now
233
- break if timeout <= 0
234
- t.join(timeout)
235
- else
236
- t.join
237
- end
238
- end
239
- kill_worker_threads
240
- end
241
-
242
- def kill_worker_threads
243
- @worker_threads.each do |t|
244
- t.kill if t.status
245
- end
246
- @worker_threads.clear
247
- end
248
-
249
- def slice_frame!(buf)
250
- if buf.length >= 4
251
- size = buf.unpack('N').first
252
- if buf.length >= size + 4
253
- buf.slice!(0, size + 4)
254
- else
255
- nil
256
- end
257
- else
258
- nil
259
- end
260
- end
261
-
262
- class Worker # :nodoc:
263
- def initialize(processor, transport_factory, protocol_factory, logger, queue)
264
- @processor = processor
265
- @transport_factory = transport_factory
266
- @protocol_factory = protocol_factory
267
- @logger = logger
268
- @queue = queue
269
- end
270
-
271
- def spawn
272
- Thread.new do
273
- @logger.debug "#{self} is spawning"
274
- run
275
- end
276
- end
277
-
278
- private
279
-
280
- def run
281
- loop do
282
- cmd, *args = @queue.pop
283
- case cmd
284
- when :shutdown
285
- @logger.debug "#{self} is shutting down, goodbye"
286
- break
287
- when :frame
288
- fd, frame = args
289
- begin
290
- otrans = @transport_factory.get_transport(fd)
291
- oprot = @protocol_factory.get_protocol(otrans)
292
- membuf = MemoryBufferTransport.new(frame)
293
- itrans = @transport_factory.get_transport(membuf)
294
- iprot = @protocol_factory.get_protocol(itrans)
295
- @processor.process(iprot, oprot)
296
- rescue => e
297
- @logger.error "#{Thread.current.inspect} raised error: #{e.inspect}\n#{e.backtrace.join("\n")}"
298
- end
299
- end
300
- end
301
- end
302
- end
303
- end
304
- end
305
- end
@@ -1,43 +0,0 @@
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
@@ -1,75 +0,0 @@
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
@@ -1,47 +0,0 @@
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
@@ -1,237 +0,0 @@
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(name, type, 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