2007-09-18 06:23:33 +00:00
|
|
|
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.
|