Back to site
Since 2004, our University project has become the Internet's most widespread web hosting directory. Here we like to talk a lot about web servers, web development, networking and security services. It is, after all, our expertise. To make things better we've launched this science section with the free access to educational resources and important scientific material translated to different languages.

Thrift: Uputstvo koje nedostaje

Thrift je software framework (okvir) za razvoj skalabilnih unakrsnih-jezičkih (cross-language) servisa. Kombinuje software stack (naslagana memorija)sa mašinom za generisanje koda radi izgradnje servisa koji rade efikasno i besprekorno među C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, i OCaml-om.

Thrift jasno obiluje svojstvima. Ono što ipak jako nedostaje je dobra dokumentacija. Ovo uputstvo je pokušaj da popunimo tu rupu. Ali imajte u vidu da je ovo priručnik — za primer korak-po-korak o tome kako da koristite Thrift, pogledajte Thrift tutorijal.

Mnogi aspekti strukture i organizacije ovog uputstva su pozajmljeni od (odličnog) Google Protocol Buffer Language Guide-a (Uputstvo Google-a za protokol buffer jezika) . Zahvaljujem autorima za taj dokument.

Takođe je dostupna PDF verzija .

Copyright (autorska prava)

Copyright © 2011 Diwaker Gupta

Ovaj rad je pod licencom: Creative Commons Attribution-NonCommercial 3.0 Unported License .

Doprinosi

Pozdravljam feedback i doprinose za ovo uputstvo. Možete naći source code preko GitHub . Alternativno možete “fajlovati” bug.

Priznanja

Zahvaljujem se autorima Thrift-a za software, autorima Google Protocol Buffer dokumentacije za inspiraciju i Thrift zajednici za feedback. Posebno se zahvaljujem Dave-u Engberg-u iz Evernote za njegov input (unos).

O autoru

Ja sam “geek” (“ludak” za open source i arhitekta za software. Ja blog-ujem preko Floating Sun-a i više o meni možete naći ovde .

Jezička referenca

Tipovi

Sistem tipa Thrift se sastoji od pre-definisanih baznih tipova, korisnički-definisanih struktura, tipova kontejnera, izuzetaka i definicija servisa.

Bazni tipovi

  • bool: A boolean value (true or false), one byte

  • byte: A signed byte

  • i16: A 16-bit signed integer

  • i32: A 32-bit signed integer

  • i64: A 64-bit signed integer

  • double: A 64-bit floating point number

  • string: Encoding agnostic text or binary string

Imajte u vidu da Thrift ne podržava neoznačene cele brojeve,jer nemaju direktan prevod na nativne (primitivne) tipove u mnogim od Thrift-ovih ciljnih (target) jezika.

Kontejneri

Thrift kontejneri su snažno tipizirani kontejneri koji mapiraju najrasprostarnjenije kontejnere u popularnim programskim jezicima. Označeni su korišćenjem Java Generics stila. Dostupna su tri tipa kontejnera:

  • list<t1>: An ordered list of elements of type t1. May contain duplicates.

  • set<t1>: An unordered set of unique elements of type t1.

  • map<t1,t2>: A map of strictly unique keys of type t1 to values of type t2.

Tipovi korišćeni u kontejnerima mogu biti bilo koji validan Thrift tip (uključujući strukture i izuzetke) isključujući servise.

Strukture i izuzeci

Thrift struktura je konceptualno slična C strukturi — zgodan način grupisanja (i obuhvatanja) odnosnih stavki zajedno. Strukture se prevode u klase u objektno-orijentisanim jezicima.

Izuzeci su sintaksički i funkcionalno ekvivalentni strukturama,osim što su deklarisani da koriste exception (izuzetak) ključnu reč umesto struct (struktura) ključne reči. Oni se razlikuju od struktura u semantici — prilikom definisanja RPC servisa, developeri će možda deklarisati da daljinska metoda izbacuje izuzetak.

Detalji o definisanju struktura i izuzetaka su tema kasnijeg odeljka .

Servisi

Definicije servisa su semantički ekvivalentne dedfinisanju interface-a (ili čiste virtuelne apstraktne klase) u objektno-orijentisanom programiranju. Thrift kompajler generiše potpuno funkcionalne stub-ove (vezivna funkcija) klijenata i servera koji implementiraju interface.

Detalji o definisanju servisa su tema kasnijeg odeljka.

Typedefs (definicije tipova)

Thrift podržava C/C++ style typedefs.

typedef i32 MyInteger // 1 typedef Tweet ReTweet // 2
1 Imajte u vidu da ne postoje prateći tačka i zarez
2 Strukture se takođe mogu koristiti u typedefs

Enum-i

Prilikom definisanja tipa poruke, možda ćete želeti da jedno od njenih polja ima samo jednu od prethodno definisanih lista vrednosti. Na primer,recimo da želite da dodate tweetType polje za svaki Tweet, gde tweetType može biti TWEET, RETWEET, DM, ili REPLY. Ovo možete uraditi vrlo prosto dodavanjem enum-a definiciji vaše poruke — polje sa enum tipom može imati samo jedan od specificiranih skupova konstanti kao svoju vrednost (ako pokušate da date drugu vrednost,parser (raščlanjivač) će je tretirati kao nepoznato polje). U primeru koji sledi smo doadli enum nazvan TweetType sa svim mogućim vrednostima,i polje istog tipa:

enum TweetType { TWEET, // 1 RETWEET = 2, // 2 DM = 0xa, // 3 REPLY } // 4 struct Tweet { 1: required i32 userId; 2: required string userName; 3: required string text; 4: optional Location loc; 5: optional TweetType tweetType = TweetType.TWEET // 5 16: optional string language = "english" }
1 Enum-i su specificirani C-style. Kompajler dodeljuje default vrednosti počevši sa 0.
2 Možete,naravno, dobaviti specifične integralne vrednosti za konstante.
3 Hex vrednosti su takođe prihvatljive.
4 Još jednom napominjemo da ne postoje prateći tačka i zarez
5 Koristite puno kvalifikovano ime konstante kod dodeljivanja default vrednosti.

Napominjemo da za razliku od Protocol Buffers-a, Thrift još uvek NE podržava “ugnežđene” (nested) enum-e (ili strukture,u tom slučaju).

Konstante enumerator-a (popisivač) MORAJU biti u opsegu postive 32-bit integer-a (celih brojeva).

Komentari

Thrift podržava shell-style, C-style više-linijske,kao i jedno-linijske Java/C++ style komentare.

# This is a valid comment. /* * This is a multi-line comment. * Just like in C. */ // C++/Java style single-line comments work just as well.

Namespaces (prostori imena)

Namespaces u Thrift-u su srodni namespaces-u u C++-u ili pkaetima u Java-i — oni nude zgodan način za organizaciju (ili izolaciju) vašeg koda. Namespaces se takođe mogu koristiti da spreče sudaranje imena među definicijama tipova.

Iz razloga što svaki jezik ima sopstvene mehanizme nalik paketima (npr.Python ima module), Thrift vam dopušta da prilagodite ponašanje namespace-a na osnovama “po jeziku”:

namespace cpp com.example.project // 1 namespace java com.example.project // 2
1 Prevodi na namespace com { namespace example { namespace project {
2 Prevodi na package com.example.project

Uključuje

Često je korisno podeliti Thrift definicije u odvojene fajlove radi olakšavanja održavanja,osposobljavanja ponovne upotrebe i poboljšanja modularnosti/organizacije. Thrift dopušta fajlovima da uključuju druge Thrift fajlove. Uključeni fajlovi se pregledaju u aktuelnom direktorijumu i traženjem odnosnog na bilo koju putanju (path) specificiranu sa -I kompajler flag-om (zastavicom).

Uključenim objektima se pristupa korišćenjem imena Thrift fajla kao prefiksa.

include "tweet.thrift" // 1 ... struct TweetSearchResult { 1: list<tweet.Tweet> tweets; // 2 }
1 Imena fajlova moraju biti pod navodnicima; još jednom napominjemo odsustvo tačke i zareza.
2 Napominjemo tweet prefiks.

Konstante

Thrift vas pušta da konstante za upotrebu definišete preko jezika. Kompleksni tipovi i strukture su specificirani korišćenjem JSON notacije.

const i32 INT_CONST = 1234; // 1 const map<string,string> MAP_CONST = {"hello": "world", "goodnight": "moon"}
1 Tačka i zarez su (zbunjujuće) opcioni; hex vrednosti su validne ovde.

Definisanje struktura (structs)

Structs (strukture) (poznate i kao poruke u nekim sistemima) su bazni blokovi za izgradnju u Thrift IDL. Struct je sastavljena od polja; svako polje ima jedinstveni identifikator celog broja (integer),tip,ime i opcionu default vrednost.

Razmotrite prosti primer. Pretpostavimo da želite da izgradite Twitter -nalik servis. Evo kako možete definisati Tweet:

struct Tweet { 1: required i32 userId; // 1 2: required string userName; // 2 3: required string text; 4: optional Location loc; // 3 16: optional string language = "english" // 4 } struct Location { // 5 1: required double latitude; 2: required double longitude; }
1 Svako polje mora imati jedinstveni, pozitivni identifikator integer-a
2 Polja moraju biti markirana kao required (zahtevano) ili optional (opciono)
3 Structs mogu da sadrže druge structs
4 Možete specificirati opcionu "default" vrednost za polje
5 Višestruke structs mogu biti definisane u i mogu se odnositi na isti Thrift fajl

Kao što možete da vidite, svako polje u definiciji poruke ima jedinstveni brojčani tag. Ovi tag-ovi se koriste da identifikuju vaša polja u wire formatu,i ne bi trebalo da se menjaju kada je jednom tip vaše poruke u upotrebi.

Polja mogu biti markirana required ili optional sa očiglednim značenjima dobro formiranih structs-a. Thrift će se žaliti ako tražena (required) polja nisu postavljena u struct,na primer. Ako neko opciono polje nije postavljeno u struct,neće biti serijalizovano preko wire-a. Ako je default vrednost specificirana za opciono polje,polje je dodeljeno default vrednosti kada se struct parsira (raščlani) i kada nijedna vrednost nije eksplicitno dodeljena za to polje.

Za razliku od servisa, structs ne podržavaju nasleđe, to jest, struct ne može da ekstenduje druge structs.

Traženo (Required) je zauvek

Trebalo bi da budete veoma pažljivi u vezi markiranja polja kako je traženo. Ako u nekom trenutku želite da prestanete da pišete ili šaljete traženo polje,biće problematično da promenite polje na neko opciono polje  — stari čitači će uzeti u obzir poruke bez ovog polja,da budu nedovršene i možda će ih odbaciti ili ih nenamerno ostaviti. Trebalo bi da razmotrite umesto toga pisanje aplikaciono-specifičnih rutina uobičajene validacije za vaše buffer-e. Neki su došli do zaključka da korišćenje traženog čini više lošeg nego dobrog; oni preferiraju korišćenje samo opcionog i ponovljenog. Međutim,ovo gledište nije univerzalno.

Definisanje servisa

Dok postoji nekoliko popularnih framework-ova serijalizacije/deserijalizacije (kao Protocol Buffers), postoji malo framework-ova koji obezbeđuju podršku izvan-box-a za servise bazirane na RPC-u preko višestrukih jezika. Ovo je jedna od glavnih atrakcija Thrift-a.

Pomislite na definicije servisa kao Java interface-e — treba da pribavite ime i potpise za metode. Opciono, jedan servis može da ekstenduje druge servise.

Thrift kompajler će generisati kod interface-a servisa (za server) i stub-ove (za klijenta) na jeziku koji ste vi izabrali. Thrift isporučuje sa RPC bibliotekama za većinu jezika koje zatim možete koristiti da pokrenete svog klijenta i server.

service Twitter { // A method definition looks like C code. It has a return type, arguments, // and optionally a list of exceptions that it may throw. Note that argument // lists and exception list are specified using the exact same syntax as // field lists in structs. void ping(), // 1 bool postTweet(1:Tweet tweet); // 2 TweetSearchResult searchTweets(1:string query); // 3 // The 'oneway' modifier indicates that the client only makes a request and // does not wait for any response at all. Oneway methods MUST be void. oneway void zip() // 4 }
1 Zbunjujuće, definicije metoda se mogu završavati korišćenjem zareza ili tačke i zareza
2 Argumenti mogu biti primitivni tipovi ili structs
3 Isto važi i za povratne (return) tipove
4 void je validni povratni tip za funkcije

Napominjemo da su liste argumenta (i liste izuzetaka) za funkcije specificirane baš kao structs.

Nasleđe podrške servisa: servis može opciono da nasledi od drugog servisa korišćenjem extends ključne reči.

“Ugnežđeni” (nested) tipovi

Kao kod ovog pisanja, Thrift NE “ugnežđuje” definicije tipova. To jest,ne možete da definišete struct (ili enum) unutar struct-a; možete,naravno,da koristite structs/enum-e unutar drugih structs.

Generisani kod

Ovaj odeljak sadrži dokumentaciju za rad sa Thrift generisanim kodom u raznim ciljnim jezicima. Počinjemo uvođenjem uobičajenih koncepata koji se koriste preko table — oni određuju kako je generisani kod strukturiran i nadamo se da će vam biti od pomoći da razumete kako da ga efektivno koristite.

<>Koncepti

Ovde je slikoviti pregled Thrift mrežnog stack-a:

Slika 1. Thrift Network (mrežni) Stack

Transport

Transport sloj obezbeđuje jednostavnu apstrakciju za čitanje/pisanje iz/na mrežu (network). Ovo osposobljava Thrift da odvoji osnovni transport od ostatka sistema (serijalizacija/deserijalizacija, na primer).

Ovde su neke od metoda izložene od strane Transport interface-a:

  • open

  • close

  • read

  • write

  • flush

Dodatno gore pomenutom Transport interface-u, Thrift takođe koristi ServerTransport interface upotrebljen da prihavti ili kreira primitivne transportne objekte. Kao što ime sugerira, ServerTransport se uglavnom koristi na strani servera da kreira nove Transport objekte za dolazeće konekcije.

  • open

  • listen

  • accept

  • close

Ovde su neki od transporta dostupni za većinu Thrift-podržanih jezika:

  • fajl čitanje/pisanje na/sa fjla na disku

  • http: kako ime sugeriše

Protokol

Protokol apstrakcija definiše mehanizam da mapira strukture podataka u memoriji u wire-format. Drugim rečima protockl specificira kako tipovi podataka koriste osnovni Transport za kodiranje/dekodiranje njih samih. Stoga implementacija protokola određuje šemu kodiranja i odgovoran je za (de)serijalizaciju. Neki primeri protokola u ovom smislu uključuju JSON, XML, običan takst, kompaktni binarni,itd.

Ovde je Protocol interface:

writeMessageBegin(name, type, seq) writeMessageEnd() writeStructBegin(name) writeStructEnd() writeFieldBegin(name, type, id) writeFieldEnd() writeFieldStop() writeMapBegin(ktype, vtype, size) writeMapEnd() writeListBegin(etype, size) writeListEnd() writeSetBegin(etype, size) writeSetEnd() writeBool(bool) writeByte(byte) writeI16(i16) writeI32(i32) writeI64(i64) writeDouble(double) writeString(string) name, type, seq = readMessageBegin() readMessageEnd() name = readStructBegin() readStructEnd() name, type, id = readFieldBegin() readFieldEnd() k, v, size = readMapBegin() readMapEnd() etype, size = readListBegin() readListEnd() etype, size = readSetBegin() readSetEnd() bool = readBool() byte = readByte() i16 = readI16() i32 = readI32() i64 = readI64() double = readDouble() string = readString()

Thrift Protocol-i su stream orijentisani po dizajnu. Nema potrebe za ikakvim eksplicitnim uokvirenjem. Na primer,nije neophodno znati dužinu string-a (niza) ili broj stavki na listi pre nego što počnemo da h serijalizujemo.

Ovde su neki od protokola dostupni za većinu Thrift-podržanih jezika:

  • binarni: Prilično jednostavno binarno kodiranje — dužina i tip polja su kodirani kao bajtovi koje sledi prava vrednost polja.

  • kompaktni: opisani u THRIFT-110

  • json:

Procesor

Procesor zatvara sposobnost čitanja podataka iz input strema-ova i pisanja na output strema-ove. Input i output stream-ovi su predstavljeni od strane Protocol objekata. Processor interface je krajnje jednostavan:

interface TProcessor { bool process(TProtocol in, TProtocol out) throws TException }

Implementacije servisno-specifičnog procesora su generisane od strane kompajlera. Procesor suštinski čita podatke iz wire-a (koristeći input protokol), poverava procesiranje handler-u (implementirano od strane korisnika) i piše odgovor preko wire-a (koristeći output protokol).

Server

Server sakuplja zajedno sva gore navedena raznovrsna svojstva:

  • Kreira transport

  • Kreira input/output protokole za transport

  • Kreira procesor baziran na input/output protokolima

  • Čeka na dolazeće konekcije i predaje ih procesoru

Sledeće o čemu ćemo diskutovati je generisani kod za specifične jezike. Osim ako nije pomenuto drugačije,odeljci dole će pretpostaviti sledeću Thrift specifikaciju:

Primer IDL

namespace cpp thrift.example namespace java thrift.example enum TweetType { TWEET, RETWEET = 2, DM = 0xa, REPLY } struct Location { 1: required double latitude; 2: required double longitude; } struct Tweet { 1: required i32 userId; 2: required string userName; 3: required string text; 4: optional Location loc; 5: optional TweetType tweetType = TweetType.TWEET; 16: optional string language = "english"; } typedef list<Tweet> TweetList struct TweetSearchResult { 1: TweetList tweets; } const i32 MAX_RESULTS = 100; service Twitter { void ping(), bool postTweet(1:Tweet tweet); TweetSearchResult searchTweets(1:string query); oneway void zip() }

Kako se “ugnežđene” structs inicijalizuju?

U ranijem odeljku,videli smo kako Thrift dopušta strukturama da sadrže druge strukture (structs) (ipak još nema definicija ugnežđenog!) U većini objektno-orijentisanih i/ili dinamičkih jezika, structs mapira objekte i stoga je poučno razumeti kako Thrift inicijalizuje ugnežđene structs. Jedan razuman pristup bi bio da ugnežđene strukture tretiramo kao pointer-e (pokazivače) ili reference i inicijalizujemo ih sa NULOM,sve dok korisnik to eksplicitno ne podesi.

Na žalost,za mnoge jezike, Thrift koristi model prenos po vrednosti (pass by value) .Kao konkretan primer, razmotrite generisani C++ kod za Tweet struct u našem primeru gore:

... int32_t userId; std::string userName; std::string text; Location loc; TweetType::type tweetType; std::string language; ...

Kao što možete da vidite,ugnežđena Location struktura je u potpunosti postavljena u skladu. Iz razloga što je Location opciona, kod koristi unutrašnje __isset flag-ove (zastavice) u cilju određivanja da li je polje zapravo bilo “podešeno” od strane korisnika.

Ovo može odvesti do nekog iznenađujućeg i ne-intuitivnog ponašanja:

  • Pošto puna veličina svake sub-strukture može biti postavljena na inicijalizaciji u nekim jezicima,upotreba memorije može biti viša nego što očekujete,naročito za komplikovane strukture sa mnogim ne-podešenim poljima.

  • Parametri i povratni tipovi za metode servisa ne mogu biti “opcioni” i ne možete dodeliti ili povratiti null (nulu) u bilo koji dinamički jezik. Stoga,da biste povratili "bezvredni" rezultat iz metode, morate deklarisati strukturu koverta (envelope structure) sa opcionim poljem koje sadrži vrednost,a zatim povratiti koverat (envelope) sa tim nepodešenim poljem.

  • Transportni sloj može, međutim, dovesti u red pozive metoda iz starijih verzija definicije servisa sa parametrima koji nedostaju. Stoga,ako je originalni servis sadržao metodu postTweet(1: Tweet tweet) i kasnija verzija to menja na postTweet(1: Tweet tweet, 2: string group), onda će stariji klijent koji priziva prethodnu metodu za rezultat imati noviji server koji prima poziv sa novim nepodešenim parametrom. Ako je novi server u Java-i,na primer,vi zapravo možete da primite null vrednost za novi parametar. A ipak ne možete da deklarišete da parametar bude na stanju nule unutar IDL-a.

Java

Generisani fajlovi

  • pojedinačni fajl (Constants.java) koji sadrži sve konstantne definicije

  • jedan fajl po struct-u, enum-u i servisu
$ tree gen-java `-- thrift `-- example |-- Constants.java |-- Location.java |-- Tweet.java |-- TweetSearchResult.java |-- TweetType.java `-- Twitter.java

Konvencije o imenovanju

Dok Thrift kompajler ne nameće nikakve konvencije o imenovanju,savetuje se da se držite standardnih konvencija o imenovanju,inače možete naići na neka iznenađenja. Na primer,ako imate strukturu po imenu tweetSearchResults (napominjemo mixedCase), Thrift kompajler će generisati Java fajl po imenu TweetSearchResults (napominjemo CamelCase) koji sadrži klasu po imenu tweetSearchResults (kao originalna struktura). Ovo se očigledno neće kompilirati pod Java-om.

Tipovi

Thrift mapira različite tipobe baze i kontejnera za Java tipove kako sledi:

  • bool: boolean

  • binary: byte[]

  • byte: byte

  • i16: short

  • i32: int

  • i64: long

  • double: double

  • string: String

  • list<t1>: List<t1>

  • set<t1>: Set<t1>

  • map<t1,t2>: Map<t1, t2>

Kao što možete da vidite,mapiranje je ravno napred i jedno-po-jedno u većem delu. Ovo ne iznenađuje obzirom da je Java primarno bila ciljni jezik kada je Thrift projekat započet.

Typedefs (definicije tipova)

Java jezik nema nikakvu nativnu podršku za "typedefs". Dakle,kada Thrit Java kod generator naiđe na deklaraciju typedef-a, on je samo zamenjuje sa originalnim tipom. To jest,čak i ako možda imate typedefd TypeA u TypeB, u generisanom Java kodu, sve reference za TypeB će biti zamenjene sa TypeA.

Razmotrite primer IDL-a gore. Deklaracija za tweets u generisanom kodu za TweetSearchResults je prosto public List <Tweets> tweets.

Enum-i

Thrift enum-i mapiraju u Java enum tipove. Možete dobiti numeričku vrednost jednog enum-a korišćenjem getValue metode (putem interface-a TEnum). Dodatno tome,kompajler generiše findByValue metodu za dobijanje enum-a koji odgovara numeričkoj vrednosti. Ovo je robustnije od upotrebe ordinal svojstva Java enum-a.

Konstante

Thrift sve definisane konstante stavlja u javnu klasu nazvanu Constants kao public static final članovi. Podržane su konstante od svakog od primitivnih tipova.

Sadržite (contain) vaše konstante

Ako imate višestruke Thrift fajove (u istom prostoru za imena) koji sadrže definicije konstanti, Thrift kompajler će precrtati Constants.java fajl sa definicijama nađenim u poslednjem obrađenom fajlu. Morate ili definisati sve svoje konstante u pojedinačnom fajlu,ili prizvati kompajler na pojedinačni fajl koji uključuje sve druge fajlove.

C++

Generisani fajlovi

  • sve konstante idu u jednu .cpp/.h pair

  • sve definicije tipova (enum-i i structs) idu u drugi .cpp/.h pair

  • svaki servis dobija sopstveni .cpp/.h pair
$ tree gen-cpp |-- example_constants.cpp |-- example_constants.h |-- example_types.cpp |-- example_types.h |-- Twitter.cpp |-- Twitter.h `-- Twitter_server.skeleton.cpp

Tipovi

Thrift mapira razne tipove baze i kontejnera u C++ tipove kako sledi:

  • bool: bool

  • binary: std::string

  • byte: int8_t

  • i16: int16_t

  • i32: int32_t

  • i64: int64_t

  • double: double

  • string: std::string

  • list<t1>: std::vector<t1>

  • set<t1>: std::set<t1>

  • map<t1,t2>: std::map<T1, T2>

Drugi jezici

Python, Ruby, Javascript ,itd.

Najbolja praksa

Verziranje/Kompatibilnost

Protokoli se razvijaju vremenom. Ako neki postojeći zip poruke više ne odgovara vašim potrebama — na primer,želeli biste da format poruke ima neko ekstra polje — ali biste i dalje želeli da koristite kod kreiran sa starim formatom,ne brinite! Veoma je jednostavno ažurirati tipove poruka bez razbijanja ičega u vašem postojećem kodu. Samo upamtite sledeća pravila:

  • Ne menjajte numeričke tag-ove za bilo koje od postojećih polja.

  • Svako novo polje koje dodate bi trebalo da je opciono. To znači da sve poruke serijalizovane kodom uz korišćenje vašeg “starog” formata poruke mogu biti parsirane (razdvojene) od strane vašeg novog generisanog koda,kao što im neće nedostajati nijedan od traženih elemenata. Trebalo bi da postavite osetljive default vrednosti za ove elemente,tako da novi kod može biti u pravilnoj interakciji sa porukama generisanim od strane starog koda. Slično tome,poruke kreirane od strane vašeg novog koda mogu biti parsirane od strane vašeg starog koda: stare binarne prosto ignorišu novo polje prilikom parsiranja. Međutim, nepoznata polja nisu odstranjena (discarded),i ako je poruka kasnije serijalizovana,nepoznata polja su serijalizovana zajedno sa njom — dakle,ako je poruka preneta na novi kod, nova polja su i dalje dostupna.

  • Ne-tražena polja mogu biti uklonjena,sve dok se broj tag-a ponovo ne koristi u vašem ažuriranom tipu poruke (možda bi bilo bolje preimenovati polje umesto toga,možda dodavanjem prefiksa "OBSOLETE_", tako da budući korisnici vašeg .thrift-a ne mogu slučajno ponovo da koriste taj broj).

  • Promena default vrednosti je genralno OK, sve dok pamtite da se default vrednosti nikada ne šalju preko wire-a. Stoga,ako program primi poruku u kojoj određeno polje nije podešeno,program će videti default vrednost kao da je definisana u programskoj verziji protokola. NEĆE videti default vrednost koja je definisana u kodu pošiljaoca.




Published (Last edited): 13-03-2013 , source: http://diwakergupta.github.com/thrift-missing-guide/