A recently developed project, the backend uses the thrift framework to provide RPC services (Java language Implementation), and then the front end uses the PHP language to generate thrift client calls to the background RPC service. For some reason, last week I changed the name of a struct in the thrift definition file, and of course I didn't think much of it, so I could recompile the Java server and deploy it without any change in the deployment of the PHP front-end, and by conventional understanding the class name in the service contract changed from A to B, The caller of the service is supposed to synchronize the update deployment, otherwise it should feel like an error.
However, the good things just happen, everything runs normally, still silky smooth!
Then, I began to think about life, to re-understand the thrift internal serialization and deserialization mechanism, soon to understand, borrow the blog before the RPC framework of the Avro Learning 2-efficient serialization of a picture:
Thrift internal storage of binary data, in order to improve storage efficiency, each field is assigned a numeric number, so in the serialization and deserialization, in fact, is only a numeric number, regardless of the name, this is the thrift IDL file definition of the struct, Why force each member to specify a numeric ordinal that is not duplicated within the struct itself
struct Personmodel { 10, 2string name, 3 BOOL Sex, 4 Double salary, 5 byte Childrencount}
In the source code of the specific language generated by IDL, when parsing an object, it also looks at the ordinal only, taking the code generated in C # as an example:
1 Public voidRead (tprotocol Iprot)2 {3 Iprot. Incrementrecursiondepth ();4 Try5 {6 tfield field;7 Iprot. Readstructbegin ();8 while(true)9 {Tenfield =Iprot. Readfieldbegin (); One if(field. Type = =ttype.stop) { A Break; - } - Switch(field.id) the { - Case 1: - if(field. Type = =ttype.i16) { -Age =Iprot. ReadI16 (); +}Else { - Tprotocolutil.skip (Iprot, field. Type); + } A Break; at Case 2: - if(field. Type = =ttype.string) { -Name =Iprot. ReadString (); -}Else { - Tprotocolutil.skip (Iprot, field. Type); - } in Break; - Case 3: to if(field. Type = =ttype.bool) { +Sex =Iprot. Readbool (); -}Else { the Tprotocolutil.skip (Iprot, field. Type); * } $ Break;Panax Notoginseng Case 4: - if(field. Type = =ttype.double) { theSalary =Iprot. Readdouble (); +}Else { A Tprotocolutil.skip (Iprot, field. Type); the } + Break; - Case 5: $ if(field. Type = =ttype.byte) { $Childrencount =Iprot. ReadByte (); -}Else { - Tprotocolutil.skip (Iprot, field. Type); the } - Break;Wuyi default: the Tprotocolutil.skip (Iprot, field. Type); - Break; Wu } - Iprot. Readfieldend (); About } $ Iprot. Readstructend (); - } - finally - { A Iprot. Decrementrecursiondepth (); + } the}
It is clear from the case statement above that the code internally only knows the number ordinal and does not care about the name.
Conclusion: As long as the member types and number numbers inside the struct are not changed, the class name of the struct can be changed with confidence.
Thrift An interesting feature: class name independence