Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 1 | Thrift Erlang Library |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 2 | |
Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 3 | README Author: Chris Piro (cpiro@facebook.com) |
| 4 | Last Modified: 2007-Sep-17 |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 5 | |
Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 6 | Thrift is distributed under the Thrift open source software license. |
| 7 | Please see the included LICENSE file. |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 8 | |
Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 9 | Using Thrift with Erlang |
| 10 | ======================== |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 11 | |
Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 12 | The Thrift Erlang binding is built using GNU make. Run `make' in |
| 13 | lib/erl to generate the necessary .beam object files in lib/erl/ebin/. |
| 14 | Although the directories are laid out much like an OTP application, |
| 15 | these bindings (as you will soon discover) are not an OTP application |
| 16 | proper. When starting the Erlang emulator (interpreter) you must use |
| 17 | `-pa /path/to/thrift/lib/erl/ebin' to load the bindings. |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 18 | |
Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 19 | Running the Tutorial |
| 20 | ==================== |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 21 | |
Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 22 | It is recommended to pattern your own servers after the tutorial |
| 23 | included in tutorial/. Generate the gen-erl/ directory by running |
| 24 | tutorial.thrift, then cd to tutorial/erl/ and run server.sh. This |
| 25 | script includes the commmands necessary to compile the generated |
| 26 | Erlang source, compile the tutorial server itself, and open the Erlang |
| 27 | emulator. At the emulator prompt, type `server:start()' to begin |
| 28 | listening for connections. |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 29 | |
Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 30 | Note that there is no tutorial client; you may use a supplied client |
| 31 | in another language. |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 32 | |
Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 33 | Implementation Notes |
| 34 | ==================== |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 35 | |
Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 36 | tExecptions and t*Factorys are straight "new" -- e.g. TF = |
| 37 | tTransportFactory:new() everything else is start_new |
| 38 | (i.e. gen_server:start_link) -- this spawns a process and returns a |
| 39 | pid |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 40 | |
Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 41 | tErlProcessor is a shim around the generated code (which is not |
| 42 | actually a gen_server). Of course tErlProcessor isn't a gen_server |
| 43 | either ... thrift_oop_server is a shim to make our "Thrift objects" |
| 44 | gen_servers. Maybe we should remove some layers? |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 45 | |
Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 46 | get/set never means process dictionary |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 47 | |
Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 48 | Use tErlServer and tErlAcceptor. tSimpleServer and tServerSocket as |
| 49 | are present in the other bindings are incompatible by design ... the |
| 50 | call trace is spastic across the process tree. tErlServer and |
| 51 | tErlAcceptor follow the same model as iserve: |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 52 | |
Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 53 | * the top level code spawns a tErlServer, which listens on a socket |
| 54 | * a tErlAcceptor is spawned and calls accept() on the listening |
| 55 | socket |
| 56 | * when accept() finishes, the tErlAcceptor |
| 57 | * tells the tErlServer to spawn a new acceptor |
| 58 | * handles the requests by spawning a processor, a transport, and a |
| 59 | protocol |
| 60 | * (the tricky part) when the socket closes, the protocol exits, so: |
| 61 | * the transport exits because it's the one caller of the protocol |
| 62 | * likewise, the processor exits because it's the caller of the |
| 63 | transport |
| 64 | * the tErlAcceptor traps the protocol's exit and exits with an |
| 65 | acceptor_done |
| 66 | * the tErlServer sees that the acceptor exited and does nothing |
| 67 | since there is already another acceptor accept()ing on the listen |
| 68 | socket |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 69 | |
Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 70 | For info about iserve: http://www.trapexit.org/A_fast_web_server_demonstrating_some_undocumented_Erlang_features |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 71 | |
Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 72 | Final Thoughts |
| 73 | ============== |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 74 | |
Christopher Piro | 93a0664 | 2007-09-18 06:23:33 +0000 | [diff] [blame] | 75 | This binding is a work in progress. It's certainly less thoroughly |
| 76 | tested than the other, older bindings. Despite using parts from |
| 77 | otp_base it is not packaged well, nor is it an OTP application (not to |
| 78 | mention its many smaller transgressions). This implementation |
| 79 | intentionally patterns after the other bindings (which is why there's |
| 80 | oop.erl and thrift_oop_server), but regretfully it departs from |
| 81 | idiomatic Erlang. Please see the included TODO and contribute your |
| 82 | improvements back to the project. |