RkBlog

Hardware, programming and astronomy tutorials and reviews.

Thrift - framework usług siecowych

Thrift pozwala tworzyć skalowalne i obsługujące wiele języków programistycznych usługi sieciowe na bazie RPC z wykorzystaniem złożonych struktur danych

thrift to framework skalowalnych usług sieciowych stworzony przez programistów Facebooka. Za jego pomocą można generować szkielet API RPC klient-serwer dla różnych języków: C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk i OCaml. Charakterystyka frameworka w punktach:

Instalacja

Wykorzystanie

Wykorzystanie Thrifta polega na stworzeniu pliku .thrift zawierającego definicję usług i wykorzystywanych w nich struktur. Dla przykładu wykorzystam przykład opublikowany przez Abhi Yerra na jego blogu. Plik thrift wygląda tak:
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)
}
Na początku określamy przestrzenie nazw dla wygenerowanego szkieletu usługi dla Pythona i Ruby (w tym przykładzie Python komunikuje się z Ruby). Następnie definiujemy strukturę User składającą się z dwóch łańcuchów. Na końcu definiujemy usługę Authentication zawierającą dwie metody - say_hello, która zwraca łańcuch i login, która zwraca "LoginStatus" przyjmując strukturę "User" jako argument. Pełne możliwości składni plików thrift przedstawiono na wiki frameworka.
Mając gotowy plik możemy wygenerować szkielet dla Pythona i Ruby za pomocą:
thrift --gen rb --gen py plik.thrift
Po ich wygenerowaniu można je wykorzystać tworząc serwer w 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."
I klienta w Pythonie:
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)
Obsługa wygenerowanego szkieletu w różnych językach opisana została mniej lub bardziej na wiki.
RkBlog

8 October 2009;

Comment article