Archive for March 2009
Being Thrifty with Thrift
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
end
handler = 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.
iPhone OS 3.0 Wants
Apple is set to announce about its upcoming OS 3.0 for the iPhone. There are a few things I really want which I thought I’d write since I am procrastinating studying for my midterm.
- Background apps – I really want to listen to Pandora while at the same time sending and receiving SMSes without the radio going off. Is that so hard to ask?
- MMS – I think it’d make the whole communicating thing a lot fluid as I’ll probably be much more likely to take pictures and send them to people since I tend to be a visual person anyways. The whole email thing is sort of out of the way.
- Copy and Paste – Seriously? It’s so annoying, for example, to find a song on Shazam wanting to send the name to a friend only to realize that you have to write down the name on a paper then send it by retyping it, good luck remembering a complicated foreign song title when you don’t have a pen at hand. Seriously what century are we in? Come on Apple!
- Tethering – Not a biggie, but would be nice especially since I’m giving AT&T $30 bucks for a shitty 3G connection that barely works if at all. Then again tethering would probably cripple the already bad network or force them to upgrade, but I’m betting on the former.
If they have those I’d be a happy poor-college-student-paying-for-an-overpriced-service-on-a-shitty-network-on-an-awesome-phone. I just feel that Apple has made a great phone which is great at individual tasks, but hasn’t worked on getting apps to talk together.
Update: A big sigh of relief as MMS and Copy and Paste have been implemented. Thank god! Also a pseudo background task ability. Still no way to listen to Pandora without getting cut off by replying to a message…