|  | Thrift Erlang Library | 
|  |  | 
|  | README Author: Chris Piro (cpiro@facebook.com) | 
|  | Last Modified: 2007-Sep-17 | 
|  |  | 
|  | Thrift is distributed under the Thrift open source software license. | 
|  | Please see the included LICENSE file. | 
|  |  | 
|  | Using Thrift with Erlang | 
|  | ======================== | 
|  |  | 
|  | The Thrift Erlang binding is built using GNU make.  Run `make' in | 
|  | lib/erl to generate the necessary .beam object files in lib/erl/ebin/. | 
|  | Although the directories are laid out much like an OTP application, | 
|  | these bindings (as you will soon discover) are not an OTP application | 
|  | proper.  When starting the Erlang emulator (interpreter) you must use | 
|  | `-pa /path/to/thrift/lib/erl/ebin' to load the bindings. | 
|  |  | 
|  | Running the Tutorial | 
|  | ==================== | 
|  |  | 
|  | It is recommended to pattern your own servers after the tutorial | 
|  | included in tutorial/.  Generate the gen-erl/ directory by running | 
|  | tutorial.thrift, then cd to tutorial/erl/ and run server.sh.  This | 
|  | script includes the commmands necessary to compile the generated | 
|  | Erlang source, compile the tutorial server itself, and open the Erlang | 
|  | emulator.  At the emulator prompt, type `server:start()' to begin | 
|  | listening for connections. | 
|  |  | 
|  | Note that there is no tutorial client; you may use a supplied client | 
|  | in another language. | 
|  |  | 
|  | Implementation Notes | 
|  | ==================== | 
|  |  | 
|  | tExecptions and t*Factorys are straight "new" -- e.g. TF = | 
|  | tTransportFactory:new() everything else is start_new | 
|  | (i.e. gen_server:start_link) -- this spawns a process and returns a | 
|  | pid | 
|  |  | 
|  | tErlProcessor is a shim around the generated code (which is not | 
|  | actually a gen_server).  Of course tErlProcessor isn't a gen_server | 
|  | either ... thrift_oop_server is a shim to make our "Thrift objects" | 
|  | gen_servers.  Maybe we should remove some layers? | 
|  |  | 
|  | get/set never means process dictionary | 
|  |  | 
|  | Use tErlServer and tErlAcceptor.  tSimpleServer and tServerSocket as | 
|  | are present in the other bindings are incompatible by design ... the | 
|  | call trace is spastic across the process tree.  tErlServer and | 
|  | tErlAcceptor follow the same model as iserve: | 
|  |  | 
|  | * the top level code spawns a tErlServer, which listens on a socket | 
|  | * a tErlAcceptor is spawned and calls accept() on the listening | 
|  | socket | 
|  | * when accept() finishes, the tErlAcceptor | 
|  | * tells the tErlServer to spawn a new acceptor | 
|  | * handles the requests by spawning a processor, a transport, and a | 
|  | protocol | 
|  | * (the tricky part) when the socket closes, the protocol exits, so: | 
|  | * the transport exits because it's the one caller of the protocol | 
|  | * likewise, the processor exits because it's the caller of the | 
|  | transport | 
|  | * the tErlAcceptor traps the protocol's exit and exits with an | 
|  | acceptor_done | 
|  | * the tErlServer sees that the acceptor exited and does nothing | 
|  | since there is already another acceptor accept()ing on the listen | 
|  | socket | 
|  |  | 
|  | For info about iserve: http://www.trapexit.org/A_fast_web_server_demonstrating_some_undocumented_Erlang_features | 
|  |  | 
|  | Final Thoughts | 
|  | ============== | 
|  |  | 
|  | This binding is a work in progress.  It's certainly less thoroughly | 
|  | tested than the other, older bindings.  Despite using parts from | 
|  | otp_base it is not packaged well, nor is it an OTP application (not to | 
|  | mention its many smaller transgressions).  This implementation | 
|  | intentionally patterns after the other bindings (which is why there's | 
|  | oop.erl and thrift_oop_server), but regretfully it departs from | 
|  | idiomatic Erlang.  Please see the included TODO and contribute your | 
|  | improvements back to the project. |