On Thu, May 26, 2011 at 1:45 AM, Mark Slee <ms...@fb.com> wrote: > (Sorry for the really slow response, I meant to respond to this weeks ago, > but got lost in the mailbox...)
no problem. I have "mailbox issues" too. I think that is a healthy sign. >>> 2) I'd replace the networking code for Java with Netty and I would look at >>> doing similar things in other languages. > > I don't know anything about Netty so can't comment specifically, but the hope > was that the TTransport > interface was general enough that you could plug in frameworks like this. > TTransport is pretty > low-level though, and I'm guessing Netty manages things at a higher level. I'm not entirely sure what you mean by high and low level here. in my lexicon, Netty takes care of all the low level stuff -- that is: it nicely abstracts away NIO and frees up the developer from having to think about any low-level networking detail. essentially, to implement a protocol you build a "codec" where you just focus on how data is converted to objects and vice versa. since codecs can be layered you can leverage existing codecs. for instance if you want to add compression or encryption you just add existing codecs for that. one of the existing codecs for Netty is the Protobuffer codec. a few months ago I wrote the networking code for a log server which uses Protobuffers to encode messages in the protocol. This is what the code looks like to set up the networking pipeline. public ChannelPipeline getPipeline() throws Exception { ChannelPipeline p = Channels.pipeline(); p.addLast("frameDecoder", new ProtobufVarint32FrameDecoder()); p.addLast("protobufDecoder", new ProtobufDecoder(Timber.LogEvent.getDefaultInstance())); p.addLast("frameEncoder", new ProtobufVarint32LengthFieldPrepender()); p.addLast("protobufEncoder", new ProtobufEncoder()); p.addLast("handler", new TimberServerHandler(logEventDispatcher)); return p; } The application never deals with buffers or sockets or any of that. Unless it wants to, of course. I get ready made (protobuffer) objects from the pipeline and I write Protobuffer objects to the pipeline when I need to send messages. note that both the frame codec and the protobuf codec came with Netty. this meant that developing the networking layer of my logserver took all of 10 minutes. (setting up a listener, a few threadpools and some TCP options is another 20 or so lines of code). adding encryption to the above is as easy as adding: p.addLast("ssl", new SslHandler(engine)); and the performance is decent too. Without any JVM warm-up my log server manages about 350.000 log messages per second on my workstation. With warm-up it managed something like 450.000 messages per second. and that was when both test clients and server were running on the same host. (quite frankly, I don't need 450k msg/sec since I will be limited by network bandwidth and disk write speeds, but it is nice to know that I don't have to think about the networking code again) I think using netty rather than maintaining our own (sometimes buggy) networking code would definitively be a big win. (yes, that frame bug came back to bite us in the ass when we had a release a couple of days ago because we had one service that had to use Thrift 0.5.0 and where no sensible frame size limit was set) > People do seem to have a high opinion of it, the big question for me is > interop with other language > stacks. I haven't heard of too many networking libraries in other languages > that are near-universally > liked (maybe twisted in python but it's sort of specific to a particular type > of programming). I would assume that it should be doable to port the protocol to Netty and break things neatly into codecs. > >>> why we are now gradually drifting away from it and reverting to REST/JSON >>> APIs. > > I actually think this is the right choice for a lot of projects, *especially* > projects in a "large, heterogenous development environment" like you > describe. Much like Google's RPC stuff, Thrift was really designed for use in > an uber-performance-sensitive environment behind a firewall, alongside a > bunch of other dev tools and standards. We have a big diversity of > programming languages, but otherwise a pretty consistent approach to building > and deploying things. after working with Google's RPC stuff for a few years I did some SOAP and REST stuff. the problem with SOAP and REST is that a lot of the framework software is brittle and fiddly and just plain badly written. for instance you can't just take schema files from some standard, throw them at the code generation tools and hope that it works. there is always fiddling involved. and luck. lots of luck. the RPC stuff in Google just worked. you wrote a proto file and you wouldn't have to dick around. there's always a need for stuff that "just works". > Personally, I would definitely first evaluate REST/JSON for any project that > required interacting with another organization or trying to interop with > other parties. Yes, there is a performance cost, but it's pretty negligible > for most people's use cases. I think a lot of people actually make a mistake > in defaulting to systems like protobuf/Thrift/avro/etc. for basic service > implementations. These are tools that aim to make doing hard things easier, > but you're still doing tricky things at the end of the day. If your needs are > relatively simple, the simpler tools (like braindead JSON/RPC implementations > on off-the-shelf webservers) are often more productive. for inter-organization stuff I would agree that REST/JSON is the better choice. although the types of people that made SOAP unusable are now catching on, so expect there to me a lot more bloated and broken tools in the REST/JSON arena :-(. >>> but as I said, if I had the time I'd much rather contribute code than what >>> could be construed as whiny, long-winded criticisms. > > Appreciate the sentiment. No worries, didn't come across as whiny. thanks for responding. -Bjørn