An entity composed of reality and pseudo-reality. Enjoys coding, news, history, photography.
A bit of Ruby, a bit of JavaScript, a bit of love...
I've been using Thrift a RPC framework from Facebook. It allows you to define a service outline and generate a template in various languages which you can then use to create the service. What this means is you can say use Haskell for you server and hook it up with a Ruby client or vice versa. I installed thrift on my Mac from the subversion repository. Here are the commands to install the pre-reqs and thrift itself assuming you have MacPorts. sudo port install boost libevent svn co https://svn.apache.org/repos/asf/incubator/thrift/trunk thrift cd thrift ./bootstrap ./configure --prefix=/opt/local/ make make install Now that's settled here is an example of a thrift definition file. Named myauth.thrift
namespace rb MyAuth
namespace py myauth struct User {
1: string username,
2: string password
} enum LoginStatus {
SUCCESS,
FAIL
} service Authentication {
string say_hello(),
LoginStatus login(1:User cred)
}
As you can see this has several components to it. The first the namespace definitions. These are the modules/packages/namespaces which this service belongs to. You can define one for each of the languages that you are going to code for. The second is the User struct which holds the data that we will be working with in the service, third the enums and finally the service definition. The service definition has two methods: say_hello which returns a string and login which returns a LoginStatus taking in a User struct as an argument. This only uses a subset of the definition syntax to show a small example of what you can do with the service. To see a more thorough example of the definition file go to the Thrift Wiki. Once you have written the definition compile the file (here I'm going to use Ruby and Python): thrift --gen rb --gen py myauth.thrift Now write the server code (in ruby):
require 'thrift'
$:.push('gen-rb')require 'Authentication'
require 'myauth_constants'class AuthenticationHandler
def say_hello
puts "thrift client connected"
"hello thrift client"
end def login cred
if cred.username == 'hello' && cred.password == 'world'
puts "logged in"
return MyAuth::LoginStatus::SUCCESS
end puts "great pie of fail"
MyAuth::LoginStatus::FAIL
end
endhandler = AuthenticationHandler.new
processor = MyAuth::Authentication::Processor.new(handler)
transport = Thrift::ServerSocket.new(9090)
transportFactory = Thrift::BufferedTransportFactory.new()
server = Thrift::SimpleServer.new(processor, transport, transportFactory)puts "Starting the server..."
server.serve()
puts "done."
Write the client code (in python):
import sys
sys.path.append('gen-py') from myauth import Authentication
from myauth.constants import * from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol transport = TSocket.TSocket('localhost', 9090)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(transport) auth = Authentication.Client(protocol) transport.open() print auth.say_hello() user = User()
user.username = 'hello'
user.password = 'world' print "Login: %s" % auth.login(user) user2 = User()
user2.username = 'failed'
user2.password = 'world' print "Login: %s" % auth.login(user2)
What thrift gives you is a transport layer as well as a protocol layer so you don't have to worry about mucking around with sockets. There are also several protocol layers defined so you could use a JSON protocol for example. All in all this is a useful technology for using the right tool for the job, i.e the right programming language for the job. By working with different languages thrift gives the programmer the capability of writing different services using the strengths of the appropriate language.
Comments 0 Comments