| 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. |