I am trying to integrate Thrift into our Rails app through the use of Rack, as
suggested in <a href="https://issues.apache.org/jira/browse/THRIFT-468">JIRA
THRIFT-468</a>. I am running into an error I just can't diagnose when
attempting to write from within the processor, where Thrift appears to be
trying to access the FIELDS element of a non-existent class, UserEmail. There
is a UserEmailRecord::FIELDS however, and the model includes a UserEmail class
which is in use.
I've included what I believe are some of the relevant data. Please let me know
if there's anything else that may help me get to the bottom of this.
Thanks,
Chris
Status: 500 Internal Server Error
uninitialized constant UserEmail::FIELDS
/Users/cwhite/devel/website/vendor/rails/activesupport/lib/active_support/dependencies.rb:105:in
`const_missing'
/opt/local/lib/ruby/site_ruby/1.8/thrift/processor.rb:52:in `write'
/opt/local/lib/ruby/site_ruby/1.8/thrift/processor.rb:52:in `write_result'
/Users/cwhite/devel/website/lib/thrift/gen-rb/user_email_service.rb:170:in
`process_getUserEmail'
/opt/local/lib/ruby/site_ruby/1.8/thrift/processor.rb:29:in `send'
/opt/local/lib/ruby/site_ruby/1.8/thrift/processor.rb:29:in `process'
/Users/cwhite/devel/website/lib/thrift/rack_useremail.rb:34:in `call'
The UserEmailRecord generated type:
class UserEmailRecord
include ::Thrift::Struct
ID = 1
EMAIL = 2
::Thrift::Struct.field_accessor self, :id, :email
FIELDS = {
ID => {:type => ::Thrift::Types::I32, :name => 'id'},
EMAIL => {:type => ::Thrift::Types::STRING, :name => 'email'}
}
def struct_fields; FIELDS; end
def validate
end
end
The middleware integration:
module ThriftRackIntegration
class UserEmailHook
attr_reader :hook_path, :processor, :protocol_factory
def initialize(app, options = {})
@app = app
@processor = options[:processor] ||
UserEmailService::Processor.new(UserEmailHandler.new)
@protocol_factory = options[:protocol_factory] ||
Thrift::BinaryProtocolFactory.new
@hook_path = options[:hook_path] || "/rpc_api"
end
def call(env)
request = Rack::Request.new(env)
if request.post? && request.path == hook_path
output = StringIO.new
transport = Thrift::IOStreamTransport.new(request.body, output)
protocol = @protocol_factory.get_protocol(transport)
@processor.process(protocol, protocol)
output.rewind
response = Rack::Response.new(output)
response["Content-Type"] = "application/x-thrift"
response.finish
else
@app.call(env)
end
end
end
end