auser-poolparty 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (353) hide show
  1. data/VERSION.yml +1 -1
  2. data/examples/monitored_cloud.rb +1 -1
  3. data/examples/thrift/thrift_example.rb +1 -1
  4. data/lib/proto/command_interface_handler.rb +1 -1
  5. data/vendor/gems/thrift/CHANGES +35 -0
  6. data/vendor/gems/thrift/CONTRIBUTORS +77 -0
  7. data/vendor/gems/thrift/DISCLAIMER +6 -0
  8. data/vendor/gems/thrift/LICENSE +202 -0
  9. data/vendor/gems/thrift/Makefile.am +28 -0
  10. data/vendor/gems/thrift/NEWS +79 -0
  11. data/vendor/gems/thrift/NOTICE +26 -0
  12. data/vendor/gems/thrift/README +137 -0
  13. data/vendor/gems/thrift/aclocal/ax_boost_base.m4 +198 -0
  14. data/vendor/gems/thrift/aclocal/ax_javac_and_java.m4 +107 -0
  15. data/vendor/gems/thrift/aclocal/ax_lib_event.m4 +194 -0
  16. data/vendor/gems/thrift/aclocal/ax_lib_zlib.m4 +173 -0
  17. data/vendor/gems/thrift/aclocal/ax_signed_right_shift.m4 +127 -0
  18. data/vendor/gems/thrift/aclocal/ax_thrift_internal.m4 +39 -0
  19. data/vendor/gems/thrift/bootstrap.sh +35 -0
  20. data/vendor/gems/thrift/cleanup.sh +58 -0
  21. data/vendor/gems/thrift/compiler/cpp/Makefile.am +136 -0
  22. data/vendor/gems/thrift/compiler/cpp/README +39 -0
  23. data/vendor/gems/thrift/compiler/cpp/src/generate/t_cocoa_generator.cc +2331 -0
  24. data/vendor/gems/thrift/compiler/cpp/src/generate/t_cpp_generator.cc +3003 -0
  25. data/vendor/gems/thrift/compiler/cpp/src/generate/t_csharp_generator.cc +1700 -0
  26. data/vendor/gems/thrift/compiler/cpp/src/generate/t_erl_generator.cc +932 -0
  27. data/vendor/gems/thrift/compiler/cpp/src/generate/t_generator.cc +173 -0
  28. data/vendor/gems/thrift/compiler/cpp/src/generate/t_generator.h +321 -0
  29. data/vendor/gems/thrift/compiler/cpp/src/generate/t_hs_generator.cc +1445 -0
  30. data/vendor/gems/thrift/compiler/cpp/src/generate/t_html_generator.cc +637 -0
  31. data/vendor/gems/thrift/compiler/cpp/src/generate/t_java_generator.cc +3069 -0
  32. data/vendor/gems/thrift/compiler/cpp/src/generate/t_ocaml_generator.cc +1673 -0
  33. data/vendor/gems/thrift/compiler/cpp/src/generate/t_oop_generator.h +77 -0
  34. data/vendor/gems/thrift/compiler/cpp/src/generate/t_perl_generator.cc +1812 -0
  35. data/vendor/gems/thrift/compiler/cpp/src/generate/t_php_generator.cc +2281 -0
  36. data/vendor/gems/thrift/compiler/cpp/src/generate/t_py_generator.cc +2310 -0
  37. data/vendor/gems/thrift/compiler/cpp/src/generate/t_rb_generator.cc +1114 -0
  38. data/vendor/gems/thrift/compiler/cpp/src/generate/t_st_generator.cc +1071 -0
  39. data/vendor/gems/thrift/compiler/cpp/src/generate/t_xsd_generator.cc +354 -0
  40. data/vendor/gems/thrift/compiler/cpp/src/globals.h +117 -0
  41. data/vendor/gems/thrift/compiler/cpp/src/main.cc +1207 -0
  42. data/vendor/gems/thrift/compiler/cpp/src/main.h +103 -0
  43. data/vendor/gems/thrift/compiler/cpp/src/md5.c +381 -0
  44. data/vendor/gems/thrift/compiler/cpp/src/md5.h +91 -0
  45. data/vendor/gems/thrift/compiler/cpp/src/parse/t_base_type.h +137 -0
  46. data/vendor/gems/thrift/compiler/cpp/src/parse/t_const.h +59 -0
  47. data/vendor/gems/thrift/compiler/cpp/src/parse/t_const_value.h +121 -0
  48. data/vendor/gems/thrift/compiler/cpp/src/parse/t_container.h +56 -0
  49. data/vendor/gems/thrift/compiler/cpp/src/parse/t_doc.h +51 -0
  50. data/vendor/gems/thrift/compiler/cpp/src/parse/t_enum.h +59 -0
  51. data/vendor/gems/thrift/compiler/cpp/src/parse/t_enum_value.h +64 -0
  52. data/vendor/gems/thrift/compiler/cpp/src/parse/t_field.h +150 -0
  53. data/vendor/gems/thrift/compiler/cpp/src/parse/t_function.h +93 -0
  54. data/vendor/gems/thrift/compiler/cpp/src/parse/t_list.h +56 -0
  55. data/vendor/gems/thrift/compiler/cpp/src/parse/t_map.h +64 -0
  56. data/vendor/gems/thrift/compiler/cpp/src/parse/t_program.h +223 -0
  57. data/vendor/gems/thrift/compiler/cpp/src/parse/t_scope.h +86 -0
  58. data/vendor/gems/thrift/compiler/cpp/src/parse/t_service.h +68 -0
  59. data/vendor/gems/thrift/compiler/cpp/src/parse/t_set.h +55 -0
  60. data/vendor/gems/thrift/compiler/cpp/src/parse/t_struct.h +127 -0
  61. data/vendor/gems/thrift/compiler/cpp/src/parse/t_type.h +176 -0
  62. data/vendor/gems/thrift/compiler/cpp/src/parse/t_typedef.h +70 -0
  63. data/vendor/gems/thrift/compiler/cpp/src/platform.h +36 -0
  64. data/vendor/gems/thrift/compiler/cpp/src/thriftl.ll +303 -0
  65. data/vendor/gems/thrift/compiler/cpp/src/thrifty.yy +1140 -0
  66. data/vendor/gems/thrift/configure.ac +255 -0
  67. data/vendor/gems/thrift/contrib/fb303/LICENSE +16 -0
  68. data/vendor/gems/thrift/contrib/fb303/Makefile.am +31 -0
  69. data/vendor/gems/thrift/contrib/fb303/README +37 -0
  70. data/vendor/gems/thrift/contrib/fb303/acinclude.m4 +258 -0
  71. data/vendor/gems/thrift/contrib/fb303/aclocal/ax_boost_base.m4 +198 -0
  72. data/vendor/gems/thrift/contrib/fb303/bootstrap.sh +26 -0
  73. data/vendor/gems/thrift/contrib/fb303/configure.ac +115 -0
  74. data/vendor/gems/thrift/contrib/fb303/cpp/FacebookBase.cpp +124 -0
  75. data/vendor/gems/thrift/contrib/fb303/cpp/FacebookBase.h +103 -0
  76. data/vendor/gems/thrift/contrib/fb303/cpp/Makefile.am +84 -0
  77. data/vendor/gems/thrift/contrib/fb303/cpp/ServiceTracker.cpp +481 -0
  78. data/vendor/gems/thrift/contrib/fb303/cpp/ServiceTracker.h +215 -0
  79. data/vendor/gems/thrift/contrib/fb303/global_footer.mk +21 -0
  80. data/vendor/gems/thrift/contrib/fb303/global_header.mk +38 -0
  81. data/vendor/gems/thrift/contrib/fb303/if/fb303.thrift +112 -0
  82. data/vendor/gems/thrift/contrib/fb303/java/FacebookBase.java +103 -0
  83. data/vendor/gems/thrift/contrib/fb303/java/build.xml +84 -0
  84. data/vendor/gems/thrift/contrib/fb303/php/FacebookBase.php +89 -0
  85. data/vendor/gems/thrift/contrib/fb303/py/Makefile.am +44 -0
  86. data/vendor/gems/thrift/contrib/fb303/py/fb303/FacebookBase.py +82 -0
  87. data/vendor/gems/thrift/contrib/fb303/py/fb303_scripts/__init__.py +20 -0
  88. data/vendor/gems/thrift/contrib/fb303/py/fb303_scripts/fb303_simple_mgmt.py +195 -0
  89. data/vendor/gems/thrift/contrib/fb303/py/setup.py +27 -0
  90. data/vendor/gems/thrift/contrib/thrift.el +126 -0
  91. data/vendor/gems/thrift/contrib/thrift.spec +206 -0
  92. data/vendor/gems/thrift/contrib/thrift.vim +91 -0
  93. data/vendor/gems/thrift/contrib/thrift_dump.cpp +91 -0
  94. data/vendor/gems/thrift/doc/lgpl-2.1.txt +504 -0
  95. data/vendor/gems/thrift/doc/otp-base-license.txt +20 -0
  96. data/vendor/gems/thrift/doc/thrift.bnf +96 -0
  97. data/vendor/gems/thrift/doc/thrift.tex +1057 -0
  98. data/vendor/gems/thrift/lib/Makefile.am +55 -0
  99. data/vendor/gems/thrift/lib/cocoa/README +21 -0
  100. data/vendor/gems/thrift/lib/cocoa/src/TApplicationException.h +44 -0
  101. data/vendor/gems/thrift/lib/cocoa/src/TApplicationException.m +130 -0
  102. data/vendor/gems/thrift/lib/cocoa/src/TException.h +34 -0
  103. data/vendor/gems/thrift/lib/cocoa/src/TException.m +64 -0
  104. data/vendor/gems/thrift/lib/cocoa/src/TProcessor.h +29 -0
  105. data/vendor/gems/thrift/lib/cocoa/src/TProcessorFactory.h +27 -0
  106. data/vendor/gems/thrift/lib/cocoa/src/TSharedProcessorFactory.h +27 -0
  107. data/vendor/gems/thrift/lib/cocoa/src/TSharedProcessorFactory.m +51 -0
  108. data/vendor/gems/thrift/lib/cocoa/src/protocol/TBinaryProtocol.h +51 -0
  109. data/vendor/gems/thrift/lib/cocoa/src/protocol/TBinaryProtocol.m +477 -0
  110. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocol.h +148 -0
  111. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolException.h +25 -0
  112. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolException.m +23 -0
  113. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolFactory.h +29 -0
  114. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolUtil.h +29 -0
  115. data/vendor/gems/thrift/lib/cocoa/src/protocol/TProtocolUtil.m +104 -0
  116. data/vendor/gems/thrift/lib/cocoa/src/server/TSocketServer.h +50 -0
  117. data/vendor/gems/thrift/lib/cocoa/src/server/TSocketServer.m +153 -0
  118. data/vendor/gems/thrift/lib/cocoa/src/transport/THTTPClient.h +42 -0
  119. data/vendor/gems/thrift/lib/cocoa/src/transport/THTTPClient.m +159 -0
  120. data/vendor/gems/thrift/lib/cocoa/src/transport/TNSFileHandleTransport.h +35 -0
  121. data/vendor/gems/thrift/lib/cocoa/src/transport/TNSFileHandleTransport.m +91 -0
  122. data/vendor/gems/thrift/lib/cocoa/src/transport/TNSStreamTransport.h +38 -0
  123. data/vendor/gems/thrift/lib/cocoa/src/transport/TNSStreamTransport.m +89 -0
  124. data/vendor/gems/thrift/lib/cocoa/src/transport/TSocketClient.h +32 -0
  125. data/vendor/gems/thrift/lib/cocoa/src/transport/TSocketClient.m +58 -0
  126. data/vendor/gems/thrift/lib/cocoa/src/transport/TTransport.h +36 -0
  127. data/vendor/gems/thrift/lib/cocoa/src/transport/TTransportException.h +30 -0
  128. data/vendor/gems/thrift/lib/cocoa/src/transport/TTransportException.m +43 -0
  129. data/vendor/gems/thrift/lib/cpp/Makefile.am +158 -0
  130. data/vendor/gems/thrift/lib/cpp/README +67 -0
  131. data/vendor/gems/thrift/lib/cpp/src/TLogging.h +163 -0
  132. data/vendor/gems/thrift/lib/cpp/src/TProcessor.h +53 -0
  133. data/vendor/gems/thrift/lib/cpp/src/TReflectionLocal.h +96 -0
  134. data/vendor/gems/thrift/lib/cpp/src/Thrift.cpp +148 -0
  135. data/vendor/gems/thrift/lib/cpp/src/Thrift.h +191 -0
  136. data/vendor/gems/thrift/lib/cpp/src/concurrency/Exception.h +60 -0
  137. data/vendor/gems/thrift/lib/cpp/src/concurrency/FunctionRunner.h +77 -0
  138. data/vendor/gems/thrift/lib/cpp/src/concurrency/Monitor.cpp +137 -0
  139. data/vendor/gems/thrift/lib/cpp/src/concurrency/Monitor.h +84 -0
  140. data/vendor/gems/thrift/lib/cpp/src/concurrency/Mutex.cpp +160 -0
  141. data/vendor/gems/thrift/lib/cpp/src/concurrency/Mutex.h +114 -0
  142. data/vendor/gems/thrift/lib/cpp/src/concurrency/PosixThreadFactory.cpp +314 -0
  143. data/vendor/gems/thrift/lib/cpp/src/concurrency/PosixThreadFactory.h +130 -0
  144. data/vendor/gems/thrift/lib/cpp/src/concurrency/Thread.h +125 -0
  145. data/vendor/gems/thrift/lib/cpp/src/concurrency/ThreadManager.cpp +493 -0
  146. data/vendor/gems/thrift/lib/cpp/src/concurrency/ThreadManager.h +169 -0
  147. data/vendor/gems/thrift/lib/cpp/src/concurrency/TimerManager.cpp +284 -0
  148. data/vendor/gems/thrift/lib/cpp/src/concurrency/TimerManager.h +122 -0
  149. data/vendor/gems/thrift/lib/cpp/src/concurrency/Util.cpp +55 -0
  150. data/vendor/gems/thrift/lib/cpp/src/concurrency/Util.h +100 -0
  151. data/vendor/gems/thrift/lib/cpp/src/concurrency/test/Tests.cpp +155 -0
  152. data/vendor/gems/thrift/lib/cpp/src/concurrency/test/ThreadFactoryTests.h +354 -0
  153. data/vendor/gems/thrift/lib/cpp/src/concurrency/test/ThreadManagerTests.h +379 -0
  154. data/vendor/gems/thrift/lib/cpp/src/concurrency/test/TimerManagerTests.h +155 -0
  155. data/vendor/gems/thrift/lib/cpp/src/processor/PeekProcessor.cpp +122 -0
  156. data/vendor/gems/thrift/lib/cpp/src/processor/PeekProcessor.h +77 -0
  157. data/vendor/gems/thrift/lib/cpp/src/processor/StatsProcessor.h +264 -0
  158. data/vendor/gems/thrift/lib/cpp/src/protocol/TBase64Utils.cpp +79 -0
  159. data/vendor/gems/thrift/lib/cpp/src/protocol/TBase64Utils.h +42 -0
  160. data/vendor/gems/thrift/lib/cpp/src/protocol/TBinaryProtocol.cpp +394 -0
  161. data/vendor/gems/thrift/lib/cpp/src/protocol/TBinaryProtocol.h +254 -0
  162. data/vendor/gems/thrift/lib/cpp/src/protocol/TCompactProtocol.cpp +736 -0
  163. data/vendor/gems/thrift/lib/cpp/src/protocol/TCompactProtocol.h +279 -0
  164. data/vendor/gems/thrift/lib/cpp/src/protocol/TDebugProtocol.cpp +346 -0
  165. data/vendor/gems/thrift/lib/cpp/src/protocol/TDebugProtocol.h +225 -0
  166. data/vendor/gems/thrift/lib/cpp/src/protocol/TDenseProtocol.cpp +762 -0
  167. data/vendor/gems/thrift/lib/cpp/src/protocol/TDenseProtocol.h +253 -0
  168. data/vendor/gems/thrift/lib/cpp/src/protocol/TJSONProtocol.cpp +998 -0
  169. data/vendor/gems/thrift/lib/cpp/src/protocol/TJSONProtocol.h +340 -0
  170. data/vendor/gems/thrift/lib/cpp/src/protocol/TOneWayProtocol.h +304 -0
  171. data/vendor/gems/thrift/lib/cpp/src/protocol/TProtocol.h +438 -0
  172. data/vendor/gems/thrift/lib/cpp/src/protocol/TProtocolException.h +104 -0
  173. data/vendor/gems/thrift/lib/cpp/src/protocol/TProtocolTap.h +187 -0
  174. data/vendor/gems/thrift/lib/cpp/src/server/TNonblockingServer.cpp +750 -0
  175. data/vendor/gems/thrift/lib/cpp/src/server/TNonblockingServer.h +435 -0
  176. data/vendor/gems/thrift/lib/cpp/src/server/TServer.cpp +38 -0
  177. data/vendor/gems/thrift/lib/cpp/src/server/TServer.h +213 -0
  178. data/vendor/gems/thrift/lib/cpp/src/server/TSimpleServer.cpp +118 -0
  179. data/vendor/gems/thrift/lib/cpp/src/server/TSimpleServer.h +70 -0
  180. data/vendor/gems/thrift/lib/cpp/src/server/TThreadPoolServer.cpp +217 -0
  181. data/vendor/gems/thrift/lib/cpp/src/server/TThreadPoolServer.h +79 -0
  182. data/vendor/gems/thrift/lib/cpp/src/server/TThreadedServer.cpp +243 -0
  183. data/vendor/gems/thrift/lib/cpp/src/server/TThreadedServer.h +74 -0
  184. data/vendor/gems/thrift/lib/cpp/src/transport/TBufferTransports.cpp +370 -0
  185. data/vendor/gems/thrift/lib/cpp/src/transport/TBufferTransports.h +667 -0
  186. data/vendor/gems/thrift/lib/cpp/src/transport/TFDTransport.cpp +77 -0
  187. data/vendor/gems/thrift/lib/cpp/src/transport/TFDTransport.h +73 -0
  188. data/vendor/gems/thrift/lib/cpp/src/transport/TFileTransport.cpp +953 -0
  189. data/vendor/gems/thrift/lib/cpp/src/transport/TFileTransport.h +442 -0
  190. data/vendor/gems/thrift/lib/cpp/src/transport/THttpClient.cpp +348 -0
  191. data/vendor/gems/thrift/lib/cpp/src/transport/THttpClient.h +111 -0
  192. data/vendor/gems/thrift/lib/cpp/src/transport/TServerSocket.cpp +368 -0
  193. data/vendor/gems/thrift/lib/cpp/src/transport/TServerSocket.h +76 -0
  194. data/vendor/gems/thrift/lib/cpp/src/transport/TServerTransport.h +92 -0
  195. data/vendor/gems/thrift/lib/cpp/src/transport/TShortReadTransport.h +96 -0
  196. data/vendor/gems/thrift/lib/cpp/src/transport/TSimpleFileTransport.cpp +54 -0
  197. data/vendor/gems/thrift/lib/cpp/src/transport/TSimpleFileTransport.h +41 -0
  198. data/vendor/gems/thrift/lib/cpp/src/transport/TSocket.cpp +591 -0
  199. data/vendor/gems/thrift/lib/cpp/src/transport/TSocket.h +242 -0
  200. data/vendor/gems/thrift/lib/cpp/src/transport/TSocketPool.cpp +235 -0
  201. data/vendor/gems/thrift/lib/cpp/src/transport/TSocketPool.h +191 -0
  202. data/vendor/gems/thrift/lib/cpp/src/transport/TTransport.h +224 -0
  203. data/vendor/gems/thrift/lib/cpp/src/transport/TTransportException.cpp +31 -0
  204. data/vendor/gems/thrift/lib/cpp/src/transport/TTransportException.h +117 -0
  205. data/vendor/gems/thrift/lib/cpp/src/transport/TTransportUtils.cpp +178 -0
  206. data/vendor/gems/thrift/lib/cpp/src/transport/TTransportUtils.h +287 -0
  207. data/vendor/gems/thrift/lib/cpp/src/transport/TZlibTransport.cpp +299 -0
  208. data/vendor/gems/thrift/lib/cpp/src/transport/TZlibTransport.h +219 -0
  209. data/vendor/gems/thrift/lib/cpp/thrift-nb.pc.in +30 -0
  210. data/vendor/gems/thrift/lib/cpp/thrift-z.pc.in +30 -0
  211. data/vendor/gems/thrift/lib/cpp/thrift.pc.in +29 -0
  212. data/vendor/gems/thrift/lib/csharp/Makefile.am +70 -0
  213. data/vendor/gems/thrift/lib/csharp/README +26 -0
  214. data/vendor/gems/thrift/lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs +55 -0
  215. data/vendor/gems/thrift/lib/csharp/ThriftMSBuildTask/ThriftBuild.cs +242 -0
  216. data/vendor/gems/thrift/lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj +62 -0
  217. data/vendor/gems/thrift/lib/csharp/src/Collections/THashSet.cs +142 -0
  218. data/vendor/gems/thrift/lib/csharp/src/Protocol/TBase.cs +34 -0
  219. data/vendor/gems/thrift/lib/csharp/src/Protocol/TBinaryProtocol.cs +392 -0
  220. data/vendor/gems/thrift/lib/csharp/src/Protocol/TField.cs +58 -0
  221. data/vendor/gems/thrift/lib/csharp/src/Protocol/TList.cs +50 -0
  222. data/vendor/gems/thrift/lib/csharp/src/Protocol/TMap.cs +58 -0
  223. data/vendor/gems/thrift/lib/csharp/src/Protocol/TMessage.cs +58 -0
  224. data/vendor/gems/thrift/lib/csharp/src/Protocol/TMessageType.cs +31 -0
  225. data/vendor/gems/thrift/lib/csharp/src/Protocol/TProtocol.cs +87 -0
  226. data/vendor/gems/thrift/lib/csharp/src/Protocol/TProtocolException.cs +61 -0
  227. data/vendor/gems/thrift/lib/csharp/src/Protocol/TProtocolFactory.cs +29 -0
  228. data/vendor/gems/thrift/lib/csharp/src/Protocol/TProtocolUtil.cs +94 -0
  229. data/vendor/gems/thrift/lib/csharp/src/Protocol/TSet.cs +50 -0
  230. data/vendor/gems/thrift/lib/csharp/src/Protocol/TStruct.cs +42 -0
  231. data/vendor/gems/thrift/lib/csharp/src/Protocol/TType.cs +40 -0
  232. data/vendor/gems/thrift/lib/csharp/src/Server/TServer.cs +135 -0
  233. data/vendor/gems/thrift/lib/csharp/src/Server/TSimpleServer.cs +148 -0
  234. data/vendor/gems/thrift/lib/csharp/src/Server/TThreadPoolServer.cs +186 -0
  235. data/vendor/gems/thrift/lib/csharp/src/Server/TThreadedServer.cs +234 -0
  236. data/vendor/gems/thrift/lib/csharp/src/TApplicationException.cs +131 -0
  237. data/vendor/gems/thrift/lib/csharp/src/TProcessor.cs +29 -0
  238. data/vendor/gems/thrift/lib/csharp/src/Thrift.csproj +73 -0
  239. data/vendor/gems/thrift/lib/csharp/src/Thrift.sln +35 -0
  240. data/vendor/gems/thrift/lib/csharp/src/Transport/TBufferedTransport.cs +100 -0
  241. data/vendor/gems/thrift/lib/csharp/src/Transport/TServerSocket.cs +157 -0
  242. data/vendor/gems/thrift/lib/csharp/src/Transport/TServerTransport.cs +39 -0
  243. data/vendor/gems/thrift/lib/csharp/src/Transport/TSocket.cs +144 -0
  244. data/vendor/gems/thrift/lib/csharp/src/Transport/TStreamTransport.cs +103 -0
  245. data/vendor/gems/thrift/lib/csharp/src/Transport/TTransport.cs +66 -0
  246. data/vendor/gems/thrift/lib/csharp/src/Transport/TTransportException.cs +64 -0
  247. data/vendor/gems/thrift/lib/csharp/src/Transport/TTransportFactory.cs +38 -0
  248. data/vendor/gems/thrift/lib/erl/Makefile +37 -0
  249. data/vendor/gems/thrift/lib/erl/README +56 -0
  250. data/vendor/gems/thrift/lib/erl/build/beamver +59 -0
  251. data/vendor/gems/thrift/lib/erl/build/buildtargets.mk +15 -0
  252. data/vendor/gems/thrift/lib/erl/build/colors.mk +24 -0
  253. data/vendor/gems/thrift/lib/erl/build/docs.mk +12 -0
  254. data/vendor/gems/thrift/lib/erl/build/mime.types +98 -0
  255. data/vendor/gems/thrift/lib/erl/build/otp.mk +146 -0
  256. data/vendor/gems/thrift/lib/erl/build/otp_subdir.mk +85 -0
  257. data/vendor/gems/thrift/lib/erl/build/raw_test.mk +29 -0
  258. data/vendor/gems/thrift/lib/erl/include/thrift_constants.hrl +54 -0
  259. data/vendor/gems/thrift/lib/erl/include/thrift_protocol.hrl +31 -0
  260. data/vendor/gems/thrift/lib/erl/src/Makefile +116 -0
  261. data/vendor/gems/thrift/lib/erl/src/test_handler.erl +26 -0
  262. data/vendor/gems/thrift/lib/erl/src/test_service.erl +29 -0
  263. data/vendor/gems/thrift/lib/erl/src/thrift.app.src +44 -0
  264. data/vendor/gems/thrift/lib/erl/src/thrift.appup.src +1 -0
  265. data/vendor/gems/thrift/lib/erl/src/thrift_base64_transport.erl +64 -0
  266. data/vendor/gems/thrift/lib/erl/src/thrift_binary_protocol.erl +325 -0
  267. data/vendor/gems/thrift/lib/erl/src/thrift_buffered_transport.erl +180 -0
  268. data/vendor/gems/thrift/lib/erl/src/thrift_client.erl +384 -0
  269. data/vendor/gems/thrift/lib/erl/src/thrift_disk_log_transport.erl +118 -0
  270. data/vendor/gems/thrift/lib/erl/src/thrift_file_transport.erl +87 -0
  271. data/vendor/gems/thrift/lib/erl/src/thrift_framed_transport.erl +208 -0
  272. data/vendor/gems/thrift/lib/erl/src/thrift_http_transport.erl +199 -0
  273. data/vendor/gems/thrift/lib/erl/src/thrift_memory_buffer.erl +164 -0
  274. data/vendor/gems/thrift/lib/erl/src/thrift_processor.erl +188 -0
  275. data/vendor/gems/thrift/lib/erl/src/thrift_protocol.erl +356 -0
  276. data/vendor/gems/thrift/lib/erl/src/thrift_server.erl +183 -0
  277. data/vendor/gems/thrift/lib/erl/src/thrift_service.erl +25 -0
  278. data/vendor/gems/thrift/lib/erl/src/thrift_socket_server.erl +249 -0
  279. data/vendor/gems/thrift/lib/erl/src/thrift_socket_transport.erl +119 -0
  280. data/vendor/gems/thrift/lib/erl/src/thrift_transport.erl +57 -0
  281. data/vendor/gems/thrift/lib/erl/vsn.mk +1 -0
  282. data/vendor/gems/thrift/lib/hs/README +82 -0
  283. data/vendor/gems/thrift/lib/hs/Setup.lhs +23 -0
  284. data/vendor/gems/thrift/lib/hs/TODO +2 -0
  285. data/vendor/gems/thrift/lib/hs/Thrift.cabal +20 -0
  286. data/vendor/gems/thrift/lib/hs/src/Thrift.hs +111 -0
  287. data/vendor/gems/thrift/lib/hs/src/Thrift/Protocol.hs +191 -0
  288. data/vendor/gems/thrift/lib/hs/src/Thrift/Protocol/Binary.hs +147 -0
  289. data/vendor/gems/thrift/lib/hs/src/Thrift/Server.hs +65 -0
  290. data/vendor/gems/thrift/lib/hs/src/Thrift/Transport.hs +60 -0
  291. data/vendor/gems/thrift/lib/hs/src/Thrift/Transport/Handle.hs +58 -0
  292. data/vendor/gems/thrift/lib/java/Makefile.am +38 -0
  293. data/vendor/gems/thrift/lib/java/README +43 -0
  294. data/vendor/gems/thrift/lib/java/build.xml +195 -0
  295. data/vendor/gems/thrift/lib/java/ivy.xml +8 -0
  296. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/IntRangeSet.java +171 -0
  297. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TApplicationException.java +123 -0
  298. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TBase.java +66 -0
  299. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TBaseHelper.java +102 -0
  300. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TByteArrayOutputStream.java +46 -0
  301. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TDeserializer.java +94 -0
  302. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TException.java +45 -0
  303. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TFieldRequirementType.java +30 -0
  304. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TProcessor.java +32 -0
  305. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TProcessorFactory.java +39 -0
  306. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/TSerializer.java +110 -0
  307. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/FieldMetaData.java +69 -0
  308. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/FieldValueMetaData.java +42 -0
  309. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/ListMetaData.java +29 -0
  310. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/MapMetaData.java +31 -0
  311. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/SetMetaData.java +29 -0
  312. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/meta_data/StructMetaData.java +31 -0
  313. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TBase64Utils.java +128 -0
  314. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TBinaryProtocol.java +331 -0
  315. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java +741 -0
  316. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TField.java +48 -0
  317. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TJSONProtocol.java +927 -0
  318. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TList.java +38 -0
  319. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TMap.java +40 -0
  320. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TMessage.java +48 -0
  321. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TMessageType.java +31 -0
  322. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TProtocol.java +146 -0
  323. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TProtocolException.java +81 -0
  324. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TProtocolFactory.java +30 -0
  325. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TProtocolUtil.java +158 -0
  326. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TSet.java +42 -0
  327. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TSimpleJSONProtocol.java +384 -0
  328. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TStruct.java +36 -0
  329. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/protocol/TType.java +40 -0
  330. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/THsHaServer.java +304 -0
  331. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/TNonblockingServer.java +772 -0
  332. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/TServer.java +126 -0
  333. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/TSimpleServer.java +145 -0
  334. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/server/TThreadPoolServer.java +271 -0
  335. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TFramedTransport.java +126 -0
  336. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/THttpClient.java +157 -0
  337. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TIOStreamTransport.java +159 -0
  338. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TMemoryBuffer.java +98 -0
  339. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TNonblockingServerSocket.java +160 -0
  340. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TNonblockingServerTransport.java +31 -0
  341. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TNonblockingSocket.java +213 -0
  342. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TNonblockingTransport.java +31 -0
  343. data/vendor/gems/thrift/lib/java/src/org/apache/thrift/transport/TServerSocket.java +145 -0
  344. metadata +348 -37
  345. data/vendor/gems/trollop/FAQ.txt +0 -35
  346. data/vendor/gems/trollop/History.txt +0 -84
  347. data/vendor/gems/trollop/Manifest.txt +0 -7
  348. data/vendor/gems/trollop/README.txt +0 -38
  349. data/vendor/gems/trollop/Rakefile +0 -36
  350. data/vendor/gems/trollop/lib/trollop.rb +0 -695
  351. data/vendor/gems/trollop/release-script.txt +0 -13
  352. data/vendor/gems/trollop/test/test_trollop.rb +0 -957
  353. data/vendor/gems/trollop/www/index.html +0 -167
@@ -0,0 +1,20 @@
1
+ Tue Oct 24 12:28:44 CDT 2006
2
+
3
+ Copyright (c) <2006> <Martin J. Logan, Erlware>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software (OTP Base, fslib, G.A.S) and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9
+ of the Software, and to permit persons to whom the Software is furnished to do
10
+ so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16
+ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
17
+ PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
20
+ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,96 @@
1
+ Thrift Protocol Structure
2
+
3
+ Last Modified: 2007-Jun-29
4
+
5
+ --------------------------------------------------------------------
6
+
7
+ Licensed to the Apache Software Foundation (ASF) under one
8
+ or more contributor license agreements. See the NOTICE file
9
+ distributed with this work for additional information
10
+ regarding copyright ownership. The ASF licenses this file
11
+ to you under the Apache License, Version 2.0 (the
12
+ "License"); you may not use this file except in compliance
13
+ with the License. You may obtain a copy of the License at
14
+
15
+ http://www.apache.org/licenses/LICENSE-2.0
16
+
17
+ Unless required by applicable law or agreed to in writing,
18
+ software distributed under the License is distributed on an
19
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20
+ KIND, either express or implied. See the License for the
21
+ specific language governing permissions and limitations
22
+ under the License.
23
+
24
+ --------------------------------------------------------------------
25
+
26
+ This document describes the structure of the Thrift protocol
27
+ without specifying the encoding. Thus, the order of elements
28
+ could in some cases be rearranged depending upon the TProtocol
29
+ implementation, but this document specifies the minimum required
30
+ structure. There are some "dumb" terminals like STRING and INT
31
+ that take the place of an actual encoding specification.
32
+
33
+ They key point to notice is that ALL messages are just one wrapped
34
+ <struct>. Depending upon the message type, the <struct> can be
35
+ interpreted as the argument list to a function, the return value
36
+ of a function, or an exception.
37
+
38
+ --------------------------------------------------------------------
39
+
40
+ <message> ::= <message-begin> <struct> <message-end>
41
+
42
+ <message-begin> ::= <method-name> <message-type> <message-seqid>
43
+
44
+ <method-name> ::= STRING
45
+
46
+ <message-type> ::= T_CALL | T_REPLY | T_EXCEPTION
47
+
48
+ <message-seqid> ::= I32
49
+
50
+ <struct> ::= <struct-begin> <field>* <field-stop> <struct-end>
51
+
52
+ <struct-begin> ::= <struct-name>
53
+
54
+ <struct-name> ::= STRING
55
+
56
+ <field-stop> ::= T_STOP
57
+
58
+ <field> ::= <field-begin> <field-data> <field-end>
59
+
60
+ <field-begin> ::= <field-name> <field-type> <field-id>
61
+
62
+ <field-name> ::= STRING
63
+
64
+ <field-type> ::= T_BOOL | T_BYTE | T_I8 | T_I16 | T_I32 | T_I64 | T_DOUBLE
65
+ | T_STRING | T_BINARY | T_STRUCT | T_MAP | T_SET | T_LIST
66
+
67
+ <field-id> ::= I16
68
+
69
+ <field-data> ::= I8 | I16 | I32 | I64 | DOUBLE | STRING | BINARY
70
+ <struct> | <map> | <list> | <set>
71
+
72
+ <map> ::= <map-begin> <field-datum>* <map-end>
73
+
74
+ <map-begin> ::= <map-key-type> <map-value-type> <map-size>
75
+
76
+ <map-key-type> ::= <field-type>
77
+
78
+ <map-value-type> ::= <field-type>
79
+
80
+ <map-size> ::= I32
81
+
82
+ <list> ::= <list-begin> <field-data>* <list-end>
83
+
84
+ <list-begin> ::= <list-elem-type> <list-size>
85
+
86
+ <list-elem-type> ::= <field-type>
87
+
88
+ <list-size> ::= I32
89
+
90
+ <set> ::= <set-begin> <field-data>* <set-end>
91
+
92
+ <set-begin> ::= <set-elem-type> <set-size>
93
+
94
+ <set-elem-type> ::= <field-type>
95
+
96
+ <set-size> ::= I32
@@ -0,0 +1,1057 @@
1
+ %-----------------------------------------------------------------------------
2
+ %
3
+ % Thrift whitepaper
4
+ %
5
+ % Name: thrift.tex
6
+ %
7
+ % Authors: Mark Slee (mcslee@facebook.com)
8
+ %
9
+ % Created: 05 March 2007
10
+ %
11
+ % You will need a copy of sigplanconf.cls to format this document.
12
+ % It is available at <http://www.sigplan.org/authorInformation.htm>.
13
+ %
14
+ %-----------------------------------------------------------------------------
15
+
16
+
17
+ \documentclass[nocopyrightspace,blockstyle]{sigplanconf}
18
+
19
+ \usepackage{amssymb}
20
+ \usepackage{amsfonts}
21
+ \usepackage{amsmath}
22
+ \usepackage{url}
23
+
24
+ \begin{document}
25
+
26
+ % \conferenceinfo{WXYZ '05}{date, City.}
27
+ % \copyrightyear{2007}
28
+ % \copyrightdata{[to be supplied]}
29
+
30
+ % \titlebanner{banner above paper title} % These are ignored unless
31
+ % \preprintfooter{short description of paper} % 'preprint' option specified.
32
+
33
+ \title{Thrift: Scalable Cross-Language Services Implementation}
34
+ \subtitle{}
35
+
36
+ \authorinfo{Mark Slee, Aditya Agarwal and Marc Kwiatkowski}
37
+ {Facebook, 156 University Ave, Palo Alto, CA}
38
+ {\{mcslee,aditya,marc\}@facebook.com}
39
+
40
+ \maketitle
41
+
42
+ \begin{abstract}
43
+ Thrift is a software library and set of code-generation tools developed at
44
+ Facebook to expedite development and implementation of efficient and scalable
45
+ backend services. Its primary goal is to enable efficient and reliable
46
+ communication across programming languages by abstracting the portions of each
47
+ language that tend to require the most customization into a common library
48
+ that is implemented in each language. Specifically, Thrift allows developers to
49
+ define datatypes and service interfaces in a single language-neutral file
50
+ and generate all the necessary code to build RPC clients and servers.
51
+
52
+ This paper details the motivations and design choices we made in Thrift, as
53
+ well as some of the more interesting implementation details. It is not
54
+ intended to be taken as research, but rather it is an exposition on what we did
55
+ and why.
56
+ \end{abstract}
57
+
58
+ % \category{D.3.3}{Programming Languages}{Language constructs and features}
59
+
60
+ %\terms
61
+ %Languages, serialization, remote procedure call
62
+
63
+ %\keywords
64
+ %Data description language, interface definition language, remote procedure call
65
+
66
+ \section{Introduction}
67
+ As Facebook's traffic and network structure have scaled, the resource
68
+ demands of many operations on the site (i.e. search,
69
+ ad selection and delivery, event logging) have presented technical requirements
70
+ drastically outside the scope of the LAMP framework. In our implementation of
71
+ these services, various programming languages have been selected to
72
+ optimize for the right combination of performance, ease and speed of
73
+ development, availability of existing libraries, etc. By and large,
74
+ Facebook's engineering culture has tended towards choosing the best
75
+ tools and implementations available over standardizing on any one
76
+ programming language and begrudgingly accepting its inherent limitations.
77
+
78
+ Given this design choice, we were presented with the challenge of building
79
+ a transparent, high-performance bridge across many programming languages.
80
+ We found that most available solutions were either too limited, did not offer
81
+ sufficient datatype freedom, or suffered from subpar performance.
82
+ \footnote{See Appendix A for a discussion of alternative systems.}
83
+
84
+ The solution that we have implemented combines a language-neutral software
85
+ stack implemented across numerous programming languages and an associated code
86
+ generation engine that transforms a simple interface and data definition
87
+ language into client and server remote procedure call libraries.
88
+ Choosing static code generation over a dynamic system allows us to create
89
+ validated code that can be run without the need for
90
+ any advanced introspective run-time type checking. It is also designed to
91
+ be as simple as possible for the developer, who can typically define all
92
+ the necessary data structures and interfaces for a complex service in a single
93
+ short file.
94
+
95
+ Surprised that a robust open solution to these relatively common problems
96
+ did not yet exist, we committed early on to making the Thrift implementation
97
+ open source.
98
+
99
+ In evaluating the challenges of cross-language interaction in a networked
100
+ environment, some key components were identified:
101
+
102
+ \textit{Types.} A common type system must exist across programming languages
103
+ without requiring that the application developer use custom Thrift datatypes
104
+ or write their own serialization code. That is,
105
+ a C++ programmer should be able to transparently exchange a strongly typed
106
+ STL map for a dynamic Python dictionary. Neither
107
+ programmer should be forced to write any code below the application layer
108
+ to achieve this. Section 2 details the Thrift type system.
109
+
110
+ \textit{Transport.} Each language must have a common interface to
111
+ bidirectional raw data transport. The specifics of how a given
112
+ transport is implemented should not matter to the service developer.
113
+ The same application code should be able to run against TCP stream sockets,
114
+ raw data in memory, or files on disk. Section 3 details the Thrift Transport
115
+ layer.
116
+
117
+ \textit{Protocol.} Datatypes must have some way of using the Transport
118
+ layer to encode and decode themselves. Again, the application
119
+ developer need not be concerned by this layer. Whether the service uses
120
+ an XML or binary protocol is immaterial to the application code.
121
+ All that matters is that the data can be read and written in a consistent,
122
+ deterministic matter. Section 4 details the Thrift Protocol layer.
123
+
124
+ \textit{Versioning.} For robust services, the involved datatypes must
125
+ provide a mechanism for versioning themselves. Specifically,
126
+ it should be possible to add or remove fields in an object or alter the
127
+ argument list of a function without any interruption in service (or,
128
+ worse yet, nasty segmentation faults). Section 5 details Thrift's versioning
129
+ system.
130
+
131
+ \textit{Processors.} Finally, we generate code capable of processing data
132
+ streams to accomplish remote procedure calls. Section 6 details the generated
133
+ code and TProcessor paradigm.
134
+
135
+ Section 7 discusses implementation details, and Section 8 describes
136
+ our conclusions.
137
+
138
+ \section{Types}
139
+
140
+ The goal of the Thrift type system is to enable programmers to develop using
141
+ completely natively defined types, no matter what programming language they
142
+ use. By design, the Thrift type system does not introduce any special dynamic
143
+ types or wrapper objects. It also does not require that the developer write
144
+ any code for object serialization or transport. The Thrift IDL (Interface
145
+ Definition Language) file is
146
+ logically a way for developers to annotate their data structures with the
147
+ minimal amount of extra information necessary to tell a code generator
148
+ how to safely transport the objects across languages.
149
+
150
+ \subsection{Base Types}
151
+
152
+ The type system rests upon a few base types. In considering which types to
153
+ support, we aimed for clarity and simplicity over abundance, focusing
154
+ on the key types available in all programming languages, ommitting any
155
+ niche types available only in specific languages.
156
+
157
+ The base types supported by Thrift are:
158
+ \begin{itemize}
159
+ \item \texttt{bool} A boolean value, true or false
160
+ \item \texttt{byte} A signed byte
161
+ \item \texttt{i16} A 16-bit signed integer
162
+ \item \texttt{i32} A 32-bit signed integer
163
+ \item \texttt{i64} A 64-bit signed integer
164
+ \item \texttt{double} A 64-bit floating point number
165
+ \item \texttt{string} An encoding-agnostic text or binary string
166
+ \item \texttt{binary} A byte array representation for blobs
167
+ \end{itemize}
168
+
169
+ Of particular note is the absence of unsigned integer types. Because these
170
+ types have no direct translation to native primitive types in many languages,
171
+ the advantages they afford are lost. Further, there is no way to prevent the
172
+ application developer in a language like Python from assigning a negative value
173
+ to an integer variable, leading to unpredictable behavior. From a design
174
+ standpoint, we observed that unsigned integers were very rarely, if ever, used
175
+ for arithmetic purposes, but in practice were much more often used as keys or
176
+ identifiers. In this case, the sign is irrelevant. Signed integers serve this
177
+ same purpose and can be safely cast to their unsigned counterparts (most
178
+ commonly in C++) when absolutely necessary.
179
+
180
+ \subsection{Structs}
181
+
182
+ A Thrift struct defines a common object to be used across languages. A struct
183
+ is essentially equivalent to a class in object oriented programming
184
+ languages. A struct has a set of strongly typed fields, each with a unique
185
+ name identifier. The basic syntax for defining a Thrift struct looks very
186
+ similar to a C struct definition. Fields may be annotated with an integer field
187
+ identifier (unique to the scope of that struct) and optional default values.
188
+ Field identifiers will be automatically assigned if omitted, though they are
189
+ strongly encouraged for versioning reasons discussed later.
190
+
191
+ \subsection{Containers}
192
+
193
+ Thrift containers are strongly typed containers that map to the most commonly
194
+ used containers in common programming languages. They are annotated using
195
+ the C++ template (or Java Generics) style. There are three types available:
196
+ \begin{itemize}
197
+ \item \texttt{list<type>} An ordered list of elements. Translates directly into
198
+ an STL \texttt{vector}, Java \texttt{ArrayList}, or native array in scripting languages. May
199
+ contain duplicates.
200
+ \item \texttt{set<type>} An unordered set of unique elements. Translates into
201
+ an STL \texttt{set}, Java \texttt{HashSet}, \texttt{set} in Python, or native
202
+ dictionary in PHP/Ruby.
203
+ \item \texttt{map<type1,type2>} A map of strictly unique keys to values
204
+ Translates into an STL \texttt{map}, Java \texttt{HashMap}, PHP associative
205
+ array, or Python/Ruby dictionary.
206
+ \end{itemize}
207
+
208
+ While defaults are provided, the type mappings are not explicitly fixed. Custom
209
+ code generator directives have been added to substitute custom types in
210
+ destination languages (i.e.
211
+ \texttt{hash\_map} or Google's sparse hash map can be used in C++). The
212
+ only requirement is that the custom types support all the necessary iteration
213
+ primitives. Container elements may be of any valid Thrift type, including other
214
+ containers or structs.
215
+
216
+ \begin{verbatim}
217
+ struct Example {
218
+ 1:i32 number=10,
219
+ 2:i64 bigNumber,
220
+ 3:double decimals,
221
+ 4:string name="thrifty"
222
+ }\end{verbatim}
223
+
224
+ In the target language, each definition generates a type with two methods,
225
+ \texttt{read} and \texttt{write}, which perform serialization and transport
226
+ of the objects using a Thrift TProtocol object.
227
+
228
+ \subsection{Exceptions}
229
+
230
+ Exceptions are syntactically and functionally equivalent to structs except
231
+ that they are declared using the \texttt{exception} keyword instead of the
232
+ \texttt{struct} keyword.
233
+
234
+ The generated objects inherit from an exception base class as appropriate
235
+ in each target programming language, in order to seamlessly
236
+ integrate with native exception handling in any given
237
+ language. Again, the design emphasis is on making the code familiar to the
238
+ application developer.
239
+
240
+ \subsection{Services}
241
+
242
+ Services are defined using Thrift types. Definition of a service is
243
+ semantically equivalent to defining an interface (or a pure virtual abstract
244
+ class) in object oriented
245
+ programming. The Thrift compiler generates fully functional client and
246
+ server stubs that implement the interface. Services are defined as follows:
247
+
248
+ \begin{verbatim}
249
+ service <name> {
250
+ <returntype> <name>(<arguments>)
251
+ [throws (<exceptions>)]
252
+ ...
253
+ }\end{verbatim}
254
+
255
+ An example:
256
+
257
+ \begin{verbatim}
258
+ service StringCache {
259
+ void set(1:i32 key, 2:string value),
260
+ string get(1:i32 key) throws (1:KeyNotFound knf),
261
+ void delete(1:i32 key)
262
+ }
263
+ \end{verbatim}
264
+
265
+ Note that \texttt{void} is a valid type for a function return, in addition to
266
+ all other defined Thrift types. Additionally, an \texttt{async} modifier
267
+ keyword may be added to a \texttt{void} function, which will generate code that does
268
+ not wait for a response from the server. Note that a pure \texttt{void}
269
+ function will return a response to the client which guarantees that the
270
+ operation has completed on the server side. With \texttt{async} method calls
271
+ the client will only be guaranteed that the request succeeded at the
272
+ transport layer. (In many transport scenarios this is inherently unreliable
273
+ due to the Byzantine Generals' Problem. Therefore, application developers
274
+ should take care only to use the async optimization in cases where dropped
275
+ method calls are acceptable or the transport is known to be reliable.)
276
+
277
+ Also of note is the fact that argument lists and exception lists for functions
278
+ are implemented as Thrift structs. All three constructs are identical in both
279
+ notation and behavior.
280
+
281
+ \section{Transport}
282
+
283
+ The transport layer is used by the generated code to facilitate data transfer.
284
+
285
+ \subsection{Interface}
286
+
287
+ A key design choice in the implementation of Thrift was to decouple the
288
+ transport layer from the code generation layer. Though Thrift is typically
289
+ used on top of the TCP/IP stack with streaming sockets as the base layer of
290
+ communication, there was no compelling reason to build that constraint into
291
+ the system. The performance tradeoff incurred by an abstracted I/O layer
292
+ (roughly one virtual method lookup / function call per operation) was
293
+ immaterial compared to the cost of actual I/O operations (typically invoking
294
+ system calls).
295
+
296
+ Fundamentally, generated Thrift code only needs to know how to read and
297
+ write data. The origin and destination of the data are irrelevant; it may be a
298
+ socket, a segment of shared memory, or a file on the local disk. The Thrift
299
+ transport interface supports the following methods:
300
+
301
+ \begin{itemize}
302
+ \item \texttt{open} Opens the tranpsort
303
+ \item \texttt{close} Closes the tranport
304
+ \item \texttt{isOpen} Indicates whether the transport is open
305
+ \item \texttt{read} Reads from the transport
306
+ \item \texttt{write} Writes to the transport
307
+ \item \texttt{flush} Forces any pending writes
308
+ \end{itemize}
309
+
310
+ There are a few additional methods not documented here which are used to aid
311
+ in batching reads and optionally signaling the completion of a read or
312
+ write operation from the generated code.
313
+
314
+ In addition to the above
315
+ \texttt{TTransport} interface, there is a\\
316
+ \texttt{TServerTransport} interface
317
+ used to accept or create primitive transport objects. Its interface is as
318
+ follows:
319
+
320
+ \begin{itemize}
321
+ \item \texttt{open} Opens the transport
322
+ \item \texttt{listen} Begins listening for connections
323
+ \item \texttt{accept} Returns a new client transport
324
+ \item \texttt{close} Closes the transport
325
+ \end{itemize}
326
+
327
+ \subsection{Implementation}
328
+
329
+ The transport interface is designed for simple implementation in any
330
+ programming language. New transport mechanisms can be easily defined as needed
331
+ by application developers.
332
+
333
+ \subsubsection{TSocket}
334
+
335
+ The \texttt{TSocket} class is implemented across all target languages. It
336
+ provides a common, simple interface to a TCP/IP stream socket.
337
+
338
+ \subsubsection{TFileTransport}
339
+
340
+ The \texttt{TFileTransport} is an abstraction of an on-disk file to a data
341
+ stream. It can be used to write out a set of incoming Thrift requests to a file
342
+ on disk. The on-disk data can then be replayed from the log, either for
343
+ post-processing or for reproduction and/or simulation of past events.
344
+
345
+ \subsubsection{Utilities}
346
+
347
+ The Transport interface is designed to support easy extension using common
348
+ OOP techniques, such as composition. Some simple utilites include the
349
+ \texttt{TBufferedTransport}, which buffers the writes and reads on an
350
+ underlying transport, the \texttt{TFramedTransport}, which transmits data with frame
351
+ size headers for chunking optimization or nonblocking operation, and the
352
+ \texttt{TMemoryBuffer}, which allows reading and writing directly from the heap
353
+ or stack memory owned by the process.
354
+
355
+ \section{Protocol}
356
+
357
+ A second major abstraction in Thrift is the separation of data structure from
358
+ transport representation. Thrift enforces a certain messaging structure when
359
+ transporting data, but it is agnostic to the protocol encoding in use. That is,
360
+ it does not matter whether data is encoded as XML, human-readable ASCII, or a
361
+ dense binary format as long as the data supports a fixed set of operations
362
+ that allow it to be deterministically read and written by generated code.
363
+
364
+ \subsection{Interface}
365
+
366
+ The Thrift Protocol interface is very straightforward. It fundamentally
367
+ supports two things: 1) bidirectional sequenced messaging, and
368
+ 2) encoding of base types, containers, and structs.
369
+
370
+ \begin{verbatim}
371
+ writeMessageBegin(name, type, seq)
372
+ writeMessageEnd()
373
+ writeStructBegin(name)
374
+ writeStructEnd()
375
+ writeFieldBegin(name, type, id)
376
+ writeFieldEnd()
377
+ writeFieldStop()
378
+ writeMapBegin(ktype, vtype, size)
379
+ writeMapEnd()
380
+ writeListBegin(etype, size)
381
+ writeListEnd()
382
+ writeSetBegin(etype, size)
383
+ writeSetEnd()
384
+ writeBool(bool)
385
+ writeByte(byte)
386
+ writeI16(i16)
387
+ writeI32(i32)
388
+ writeI64(i64)
389
+ writeDouble(double)
390
+ writeString(string)
391
+
392
+ name, type, seq = readMessageBegin()
393
+ readMessageEnd()
394
+ name = readStructBegin()
395
+ readStructEnd()
396
+ name, type, id = readFieldBegin()
397
+ readFieldEnd()
398
+ k, v, size = readMapBegin()
399
+ readMapEnd()
400
+ etype, size = readListBegin()
401
+ readListEnd()
402
+ etype, size = readSetBegin()
403
+ readSetEnd()
404
+ bool = readBool()
405
+ byte = readByte()
406
+ i16 = readI16()
407
+ i32 = readI32()
408
+ i64 = readI64()
409
+ double = readDouble()
410
+ string = readString()
411
+ \end{verbatim}
412
+
413
+ Note that every \texttt{write} function has exactly one \texttt{read} counterpart, with
414
+ the exception of \texttt{writeFieldStop()}. This is a special method
415
+ that signals the end of a struct. The procedure for reading a struct is to
416
+ \texttt{readFieldBegin()} until the stop field is encountered, and then to
417
+ \texttt{readStructEnd()}. The
418
+ generated code relies upon this call sequence to ensure that everything written by
419
+ a protocol encoder can be read by a matching protocol decoder. Further note
420
+ that this set of functions is by design more robust than necessary.
421
+ For example, \texttt{writeStructEnd()} is not strictly necessary, as the end of
422
+ a struct may be implied by the stop field. This method is a convenience for
423
+ verbose protocols in which it is cleaner to separate these calls (e.g. a closing
424
+ \texttt{</struct>} tag in XML).
425
+
426
+ \subsection{Structure}
427
+
428
+ Thrift structures are designed to support encoding into a streaming
429
+ protocol. The implementation should never need to frame or compute the
430
+ entire data length of a structure prior to encoding it. This is critical to
431
+ performance in many scenarios. Consider a long list of relatively large
432
+ strings. If the protocol interface required reading or writing a list to be an
433
+ atomic operation, then the implementation would need to perform a linear pass over the
434
+ entire list before encoding any data. However, if the list can be written
435
+ as iteration is performed, the corresponding read may begin in parallel,
436
+ theoretically offering an end-to-end speedup of $(kN - C)$, where $N$ is the size
437
+ of the list, $k$ the cost factor associated with serializing a single
438
+ element, and $C$ is fixed offset for the delay between data being written
439
+ and becoming available to read.
440
+
441
+ Similarly, structs do not encode their data lengths a priori. Instead, they are
442
+ encoded as a sequence of fields, with each field having a type specifier and a
443
+ unique field identifier. Note that the inclusion of type specifiers allows
444
+ the protocol to be safely parsed and decoded without any generated code
445
+ or access to the original IDL file. Structs are terminated by a field header
446
+ with a special \texttt{STOP} type. Because all the basic types can be read
447
+ deterministically, all structs (even those containing other structs) can be
448
+ read deterministically. The Thrift protocol is self-delimiting without any
449
+ framing and regardless of the encoding format.
450
+
451
+ In situations where streaming is unnecessary or framing is advantageous, it
452
+ can be very simply added into the transport layer, using the
453
+ \texttt{TFramedTransport} abstraction.
454
+
455
+ \subsection{Implementation}
456
+
457
+ Facebook has implemented and deployed a space-efficient binary protocol which
458
+ is used by most backend services. Essentially, it writes all data
459
+ in a flat binary format. Integer types are converted to network byte order,
460
+ strings are prepended with their byte length, and all message and field headers
461
+ are written using the primitive integer serialization constructs. String names
462
+ for fields are omitted - when using generated code, field identifiers are
463
+ sufficient.
464
+
465
+ We decided against some extreme storage optimizations (i.e. packing
466
+ small integers into ASCII or using a 7-bit continuation format) for the sake
467
+ of simplicity and clarity in the code. These alterations can easily be made
468
+ if and when we encounter a performance-critical use case that demands them.
469
+
470
+ \section{Versioning}
471
+
472
+ Thrift is robust in the face of versioning and data definition changes. This
473
+ is critical to enable staged rollouts of changes to deployed services. The
474
+ system must be able to support reading of old data from log files, as well as
475
+ requests from out-of-date clients to new servers, and vice versa.
476
+
477
+ \subsection{Field Identifiers}
478
+
479
+ Versioning in Thrift is implemented via field identifiers. The field header
480
+ for every member of a struct in Thrift is encoded with a unique field
481
+ identifier. The combination of this field identifier and its type specifier
482
+ is used to uniquely identify the field. The Thrift definition language
483
+ supports automatic assignment of field identifiers, but it is good
484
+ programming practice to always explicitly specify field identifiers.
485
+ Identifiers are specified as follows:
486
+
487
+ \begin{verbatim}
488
+ struct Example {
489
+ 1:i32 number=10,
490
+ 2:i64 bigNumber,
491
+ 3:double decimals,
492
+ 4:string name="thrifty"
493
+ }\end{verbatim}
494
+
495
+ To avoid conflicts between manually and automatically assigned identifiers,
496
+ fields with identifiers omitted are assigned identifiers
497
+ decrementing from -1, and the language only supports the manual assignment of
498
+ positive identifiers.
499
+
500
+ When data is being deserialized, the generated code can use these identifiers
501
+ to properly identify the field and determine whether it aligns with a field in
502
+ its definition file. If a field identifier is not recognized, the generated
503
+ code can use the type specifier to skip the unknown field without any error.
504
+ Again, this is possible due to the fact that all datatypes are self
505
+ delimiting.
506
+
507
+ Field identifiers can (and should) also be specified in function argument
508
+ lists. In fact, argument lists are not only represented as structs on the
509
+ backend, but actually share the same code in the compiler frontend. This
510
+ allows for version-safe modification of method parameters
511
+
512
+ \begin{verbatim}
513
+ service StringCache {
514
+ void set(1:i32 key, 2:string value),
515
+ string get(1:i32 key) throws (1:KeyNotFound knf),
516
+ void delete(1:i32 key)
517
+ }
518
+ \end{verbatim}
519
+
520
+ The syntax for specifying field identifiers was chosen to echo their structure.
521
+ Structs can be thought of as a dictionary where the identifiers are keys, and
522
+ the values are strongly-typed named fields.
523
+
524
+ Field identifiers internally use the \texttt{i16} Thrift type. Note, however,
525
+ that the \texttt{TProtocol} abstraction may encode identifiers in any format.
526
+
527
+ \subsection{Isset}
528
+
529
+ When an unexpected field is encountered, it can be safely ignored and
530
+ discarded. When an expected field is not found, there must be some way to
531
+ signal to the developer that it was not present. This is implemented via an
532
+ inner \texttt{isset} structure inside the defined objects. (Isset functionality
533
+ is implicit with a \texttt{null} value in PHP, \texttt{None} in Python
534
+ and \texttt{nil} in Ruby.) Essentially,
535
+ the inner \texttt{isset} object of each Thrift struct contains a boolean value
536
+ for each field which denotes whether or not that field is present in the
537
+ struct. When a reader receives a struct, it should check for a field being set
538
+ before operating directly on it.
539
+
540
+ \begin{verbatim}
541
+ class Example {
542
+ public:
543
+ Example() :
544
+ number(10),
545
+ bigNumber(0),
546
+ decimals(0),
547
+ name("thrifty") {}
548
+
549
+ int32_t number;
550
+ int64_t bigNumber;
551
+ double decimals;
552
+ std::string name;
553
+
554
+ struct __isset {
555
+ __isset() :
556
+ number(false),
557
+ bigNumber(false),
558
+ decimals(false),
559
+ name(false) {}
560
+ bool number;
561
+ bool bigNumber;
562
+ bool decimals;
563
+ bool name;
564
+ } __isset;
565
+ ...
566
+ }
567
+ \end{verbatim}
568
+
569
+ \subsection{Case Analysis}
570
+
571
+ There are four cases in which version mismatches may occur.
572
+
573
+ \begin{enumerate}
574
+ \item \textit{Added field, old client, new server.} In this case, the old
575
+ client does not send the new field. The new server recognizes that the field
576
+ is not set, and implements default behavior for out-of-date requests.
577
+ \item \textit{Removed field, old client, new server.} In this case, the old
578
+ client sends the removed field. The new server simply ignores it.
579
+ \item \textit{Added field, new client, old server.} The new client sends a
580
+ field that the old server does not recognize. The old server simply ignores
581
+ it and processes as normal.
582
+ \item \textit{Removed field, new client, old server.} This is the most
583
+ dangerous case, as the old server is unlikely to have suitable default
584
+ behavior implemented for the missing field. It is recommended that in this
585
+ situation the new server be rolled out prior to the new clients.
586
+ \end{enumerate}
587
+
588
+ \subsection{Protocol/Transport Versioning}
589
+ The \texttt{TProtocol} abstractions are also designed to give protocol
590
+ implementations the freedom to version themselves in whatever manner they
591
+ see fit. Specifically, any protocol implementation is free to send whatever
592
+ it likes in the \texttt{writeMessageBegin()} call. It is entirely up to the
593
+ implementor how to handle versioning at the protocol level. The key point is
594
+ that protocol encoding changes are safely isolated from interface definition
595
+ version changes.
596
+
597
+ Note that the exact same is true of the \texttt{TTransport} interface. For
598
+ example, if we wished to add some new checksumming or error detection to the
599
+ \texttt{TFileTransport}, we could simply add a version header into the
600
+ data it writes to the file in such a way that it would still accept old
601
+ log files without the given header.
602
+
603
+ \section{RPC Implementation}
604
+
605
+ \subsection{TProcessor}
606
+
607
+ The last core interface in the Thrift design is the \texttt{TProcessor},
608
+ perhaps the most simple of the constructs. The interface is as follows:
609
+
610
+ \begin{verbatim}
611
+ interface TProcessor {
612
+ bool process(TProtocol in, TProtocol out)
613
+ throws TException
614
+ }
615
+ \end{verbatim}
616
+
617
+ The key design idea here is that the complex systems we build can fundamentally
618
+ be broken down into agents or services that operate on inputs and outputs. In
619
+ most cases, there is actually just one input and output (an RPC client) that
620
+ needs handling.
621
+
622
+ \subsection{Generated Code}
623
+
624
+ When a service is defined, we generate a
625
+ \texttt{TProcessor} instance capable of handling RPC requests to that service,
626
+ using a few helpers. The fundamental structure (illustrated in pseudo-C++) is
627
+ as follows:
628
+
629
+ \begin{verbatim}
630
+ Service.thrift
631
+ => Service.cpp
632
+ interface ServiceIf
633
+ class ServiceClient : virtual ServiceIf
634
+ TProtocol in
635
+ TProtocol out
636
+ class ServiceProcessor : TProcessor
637
+ ServiceIf handler
638
+
639
+ ServiceHandler.cpp
640
+ class ServiceHandler : virtual ServiceIf
641
+
642
+ TServer.cpp
643
+ TServer(TProcessor processor,
644
+ TServerTransport transport,
645
+ TTransportFactory tfactory,
646
+ TProtocolFactory pfactory)
647
+ serve()
648
+ \end{verbatim}
649
+
650
+ From the Thrift definition file, we generate the virtual service interface.
651
+ A client class is generated, which implements the interface and
652
+ uses two \texttt{TProtocol} instances to perform the I/O operations. The
653
+ generated processor implements the \texttt{TProcessor} interface. The generated
654
+ code has all the logic to handle RPC invocations via the \texttt{process()}
655
+ call, and takes as a parameter an instance of the service interface, as
656
+ implemented by the application developer.
657
+
658
+ The user provides an implementation of the application interface in separate,
659
+ non-generated source code.
660
+
661
+ \subsection{TServer}
662
+
663
+ Finally, the Thrift core libraries provide a \texttt{TServer} abstraction.
664
+ The \texttt{TServer} object generally works as follows.
665
+
666
+ \begin{itemize}
667
+ \item Use the \texttt{TServerTransport} to get a \texttt{TTransport}
668
+ \item Use the \texttt{TTransportFactory} to optionally convert the primitive
669
+ transport into a suitable application transport (typically the
670
+ \texttt{TBufferedTransportFactory} is used here)
671
+ \item Use the \texttt{TProtocolFactory} to create an input and output protocol
672
+ for the \texttt{TTransport}
673
+ \item Invoke the \texttt{process()} method of the \texttt{TProcessor} object
674
+ \end{itemize}
675
+
676
+ The layers are appropriately separated such that the server code needs to know
677
+ nothing about any of the transports, encodings, or applications in play. The
678
+ server encapsulates the logic around connection handling, threading, etc.
679
+ while the processor deals with RPC. The only code written by the application
680
+ developer lives in the definitional Thrift file and the interface
681
+ implementation.
682
+
683
+ Facebook has deployed multiple \texttt{TServer} implementations, including
684
+ the single-threaded \texttt{TSimpleServer}, thread-per-connection
685
+ \texttt{TThreadedServer}, and thread-pooling \texttt{TThreadPoolServer}.
686
+
687
+ The \texttt{TProcessor} interface is very general by design. There is no
688
+ requirement that a \texttt{TServer} take a generated \texttt{TProcessor}
689
+ object. Thrift allows the application developer to easily write any type of
690
+ server that operates on \texttt{TProtocol} objects (for instance, a server
691
+ could simply stream a certain type of object without any actual RPC method
692
+ invocation).
693
+
694
+ \section{Implementation Details}
695
+ \subsection{Target Languages}
696
+ Thrift currently supports five target languages: C++, Java, Python, Ruby, and
697
+ PHP. At Facebook, we have deployed servers predominantly in C++, Java, and
698
+ Python. Thrift services implemented in PHP have also been embedded into the
699
+ Apache web server, providing transparent backend access to many of our
700
+ frontend constructs using a \texttt{THttpClient} implementation of the
701
+ \texttt{TTransport} interface.
702
+
703
+ Though Thrift was explicitly designed to be much more efficient and robust
704
+ than typical web technologies, as we were designing our XML-based REST web
705
+ services API we noticed that Thrift could be easily used to define our
706
+ service interface. Though we do not currently employ SOAP envelopes (in the
707
+ authors' opinions there is already far too much repetitive enterprise Java
708
+ software to do that sort of thing), we were able to quickly extend Thrift to
709
+ generate XML Schema Definition files for our service, as well as a framework
710
+ for versioning different implementations of our web service. Though public
711
+ web services are admittedly tangential to Thrift's core use case and design,
712
+ Thrift facilitated rapid iteration and affords us the ability to quickly
713
+ migrate our entire XML-based web service onto a higher performance system
714
+ should the need arise.
715
+
716
+ \subsection{Generated Structs}
717
+ We made a conscious decision to make our generated structs as transparent as
718
+ possible. All fields are publicly accessible; there are no \texttt{set()} and
719
+ \texttt{get()} methods. Similarly, use of the \texttt{isset} object is not
720
+ enforced. We do not include any \texttt{FieldNotSetException} construct.
721
+ Developers have the option to use these fields to write more robust code, but
722
+ the system is robust to the developer ignoring the \texttt{isset} construct
723
+ entirely and will provide suitable default behavior in all cases.
724
+
725
+ This choice was motivated by the desire to ease application development. Our stated
726
+ goal is not to make developers learn a rich new library in their language of
727
+ choice, but rather to generate code that allow them to work with the constructs
728
+ that are most familiar in each language.
729
+
730
+ We also made the \texttt{read()} and \texttt{write()} methods of the generated
731
+ objects public so that the objects can be used outside of the context
732
+ of RPC clients and servers. Thrift is a useful tool simply for generating
733
+ objects that are easily serializable across programming languages.
734
+
735
+ \subsection{RPC Method Identification}
736
+ Method calls in RPC are implemented by sending the method name as a string. One
737
+ issue with this approach is that longer method names require more bandwidth.
738
+ We experimented with using fixed-size hashes to identify methods, but in the
739
+ end concluded that the savings were not worth the headaches incurred. Reliably
740
+ dealing with conflicts across versions of an interface definition file is
741
+ impossible without a meta-storage system (i.e. to generate non-conflicting
742
+ hashes for the current version of a file, we would have to know about all
743
+ conflicts that ever existed in any previous version of the file).
744
+
745
+ We wanted to avoid too many unnecessary string comparisons upon
746
+ method invocation. To deal with this, we generate maps from strings to function
747
+ pointers, so that invocation is effectively accomplished via a constant-time
748
+ hash lookup in the common case. This requires the use of a couple interesting
749
+ code constructs. Because Java does not have function pointers, process
750
+ functions are all private member classes implementing a common interface.
751
+
752
+ \begin{verbatim}
753
+ private class ping implements ProcessFunction {
754
+ public void process(int seqid,
755
+ TProtocol iprot,
756
+ TProtocol oprot)
757
+ throws TException
758
+ { ...}
759
+ }
760
+
761
+ HashMap<String,ProcessFunction> processMap_ =
762
+ new HashMap<String,ProcessFunction>();
763
+ \end{verbatim}
764
+
765
+ In C++, we use a relatively esoteric language construct: member function
766
+ pointers.
767
+
768
+ \begin{verbatim}
769
+ std::map<std::string,
770
+ void (ExampleServiceProcessor::*)(int32_t,
771
+ facebook::thrift::protocol::TProtocol*,
772
+ facebook::thrift::protocol::TProtocol*)>
773
+ processMap_;
774
+ \end{verbatim}
775
+
776
+ Using these techniques, the cost of string processing is minimized, and we
777
+ reap the benefit of being able to easily debug corrupt or misunderstood data by
778
+ inspecting it for known string method names.
779
+
780
+ \subsection{Servers and Multithreading}
781
+ Thrift services require basic multithreading to handle simultaneous
782
+ requests from multiple clients. For the Python and Java implementations of
783
+ Thrift server logic, the standard threading libraries distributed with the
784
+ languages provide adequate support. For the C++ implementation, no standard multithread runtime
785
+ library exists. Specifically, robust, lightweight, and portable
786
+ thread manager and timer class implementations do not exist. We investigated
787
+ existing implementations, namely \texttt{boost::thread},
788
+ \texttt{boost::threadpool}, \texttt{ACE\_Thread\_Manager} and
789
+ \texttt{ACE\_Timer}.
790
+
791
+ While \texttt{boost::threads}\cite{boost.threads} provides clean,
792
+ lightweight and robust implementations of multi-thread primitives (mutexes,
793
+ conditions, threads) it does not provide a thread manager or timer
794
+ implementation.
795
+
796
+ \texttt{boost::threadpool}\cite{boost.threadpool} also looked promising but
797
+ was not far enough along for our purposes. We wanted to limit the dependency on
798
+ third-party libraries as much as possible. Because\\
799
+ \texttt{boost::threadpool} is
800
+ not a pure template library and requires runtime libraries and because it is
801
+ not yet part of the official Boost distribution we felt it was not ready for
802
+ use in Thrift. As \texttt{boost::threadpool} evolves and especially if it is
803
+ added to the Boost distribution we may reconsider our decision to not use it.
804
+
805
+ ACE has both a thread manager and timer class in addition to multi-thread
806
+ primitives. The biggest problem with ACE is that it is ACE. Unlike Boost, ACE
807
+ API quality is poor. Everything in ACE has large numbers of dependencies on
808
+ everything else in ACE - thus forcing developers to throw out standard
809
+ classes, such as STL collections, in favor of ACE's homebrewed implementations. In
810
+ addition, unlike Boost, ACE implementations demonstrate little understanding
811
+ of the power and pitfalls of C++ programming and take no advantage of modern
812
+ templating techniques to ensure compile time safety and reasonable compiler
813
+ error messages. For all these reasons, ACE was rejected. Instead, we chose
814
+ to implement our own library, described in the following sections.
815
+
816
+ \subsection{Thread Primitives}
817
+
818
+ The Thrift thread libraries are implemented in the namespace\\
819
+ \texttt{facebook::thrift::concurrency} and have three components:
820
+ \begin{itemize}
821
+ \item primitives
822
+ \item thread pool manager
823
+ \item timer manager
824
+ \end{itemize}
825
+
826
+ As mentioned above, we were hesitant to introduce any additional dependencies
827
+ on Thrift. We decided to use \texttt{boost::shared\_ptr} because it is so
828
+ useful for multithreaded application, it requires no link-time or
829
+ runtime libraries (i.e. it is a pure template library) and it is due
830
+ to become part of the C++0x standard.
831
+
832
+ We implement standard \texttt{Mutex} and \texttt{Condition} classes, and a
833
+ \texttt{Monitor} class. The latter is simply a combination of a mutex and
834
+ condition variable and is analogous to the \texttt{Monitor} implementation provided for
835
+ the Java \texttt{Object} class. This is also sometimes referred to as a barrier. We
836
+ provide a \texttt{Synchronized} guard class to allow Java-like synchronized blocks.
837
+ This is just a bit of syntactic sugar, but, like its Java counterpart, clearly
838
+ delimits critical sections of code. Unlike its Java counterpart, we still
839
+ have the ability to programmatically lock, unlock, block, and signal monitors.
840
+
841
+ \begin{verbatim}
842
+ void run() {
843
+ {Synchronized s(manager->monitor);
844
+ if (manager->state == TimerManager::STARTING) {
845
+ manager->state = TimerManager::STARTED;
846
+ manager->monitor.notifyAll();
847
+ }
848
+ }
849
+ }
850
+ \end{verbatim}
851
+
852
+ We again borrowed from Java the distinction between a thread and a runnable
853
+ class. A \texttt{Thread} is the actual schedulable object. The
854
+ \texttt{Runnable} is the logic to execute within the thread.
855
+ The \texttt{Thread} implementation deals with all the platform-specific thread
856
+ creation and destruction issues, while the \texttt{Runnable} implementation deals
857
+ with the application-specific per-thread logic. The benefit of this approach
858
+ is that developers can easily subclass the Runnable class without pulling in
859
+ platform-specific super-classes.
860
+
861
+ \subsection{Thread, Runnable, and shared\_ptr}
862
+ We use \texttt{boost::shared\_ptr} throughout the \texttt{ThreadManager} and
863
+ \texttt{TimerManager} implementations to guarantee cleanup of dead objects that can
864
+ be accessed by multiple threads. For \texttt{Thread} class implementations,
865
+ \texttt{boost::shared\_ptr} usage requires particular attention to make sure
866
+ \texttt{Thread} objects are neither leaked nor dereferenced prematurely while
867
+ creating and shutting down threads.
868
+
869
+ Thread creation requires calling into a C library. (In our case the POSIX
870
+ thread library, \texttt{libpthread}, but the same would be true for WIN32 threads).
871
+ Typically, the OS makes few, if any, guarantees about when \texttt{ThreadMain}, a C thread's entry-point function, will be called. Therefore, it is
872
+ possible that our thread create call,
873
+ \texttt{ThreadFactory::newThread()} could return to the caller
874
+ well before that time. To ensure that the returned \texttt{Thread} object is not
875
+ prematurely cleaned up if the caller gives up its reference prior to the
876
+ \texttt{ThreadMain} call, the \texttt{Thread} object makes a weak referenence to
877
+ itself in its \texttt{start} method.
878
+
879
+ With the weak reference in hand the \texttt{ThreadMain} function can attempt to get
880
+ a strong reference before entering the \texttt{Runnable::run} method of the
881
+ \texttt{Runnable} object bound to the \texttt{Thread}. If no strong references to the
882
+ thread are obtained between exiting \texttt{Thread::start} and entering \texttt{ThreadMain}, the weak reference returns \texttt{null} and the function
883
+ exits immediately.
884
+
885
+ The need for the \texttt{Thread} to make a weak reference to itself has a
886
+ significant impact on the API. Since references are managed through the
887
+ \texttt{boost::shared\_ptr} templates, the \texttt{Thread} object must have a reference
888
+ to itself wrapped by the same \texttt{boost::shared\_ptr} envelope that is returned
889
+ to the caller. This necessitated the use of the factory pattern.
890
+ \texttt{ThreadFactory} creates the raw \texttt{Thread} object and a
891
+ \texttt{boost::shared\_ptr} wrapper, and calls a private helper method of the class
892
+ implementing the \texttt{Thread} interface (in this case, \texttt{PosixThread::weakRef})
893
+ to allow it to make add weak reference to itself through the
894
+ \texttt{boost::shared\_ptr} envelope.
895
+
896
+ \texttt{Thread} and \texttt{Runnable} objects reference each other. A \texttt{Runnable}
897
+ object may need to know about the thread in which it is executing, and a Thread, obviously,
898
+ needs to know what \texttt{Runnable} object it is hosting. This interdependency is
899
+ further complicated because the lifecycle of each object is independent of the
900
+ other. An application may create a set of \texttt{Runnable} object to be reused in different threads, or it may create and forget a \texttt{Runnable} object
901
+ once a thread has been created and started for it.
902
+
903
+ The \texttt{Thread} class takes a \texttt{boost::shared\_ptr} reference to the hosted
904
+ \texttt{Runnable} object in its constructor, while the \texttt{Runnable} class has an
905
+ explicit \texttt{thread} method to allow explicit binding of the hosted thread.
906
+ \texttt{ThreadFactory::newThread} binds the objects to each other.
907
+
908
+ \subsection{ThreadManager}
909
+
910
+ \texttt{ThreadManager} creates a pool of worker threads and
911
+ allows applications to schedule tasks for execution as free worker threads
912
+ become available. The \texttt{ThreadManager} does not implement dynamic
913
+ thread pool resizing, but provides primitives so that applications can add
914
+ and remove threads based on load. This approach was chosen because
915
+ implementing load metrics and thread pool size is very application
916
+ specific. For example some applications may want to adjust pool size based
917
+ on running-average of work arrival rates that are measured via polled
918
+ samples. Others may simply wish to react immediately to work-queue
919
+ depth high and low water marks. Rather than trying to create a complex
920
+ API abstract enough to capture these different approaches, we
921
+ simply leave it up to the particular application and provide the
922
+ primitives to enact the desired policy and sample current status.
923
+
924
+ \subsection{TimerManager}
925
+
926
+ \texttt{TimerManager} allows applications to schedule
927
+ \texttt{Runnable} objects for execution at some point in the future. Its specific task
928
+ is to allows applications to sample \texttt{ThreadManager} load at regular
929
+ intervals and make changes to the thread pool size based on application policy.
930
+ Of course, it can be used to generate any number of timer or alarm events.
931
+
932
+ The default implementation of \texttt{TimerManager} uses a single thread to
933
+ execute expired \texttt{Runnable} objects. Thus, if a timer operation needs to
934
+ do a large amount of work and especially if it needs to do blocking I/O,
935
+ that should be done in a separate thread.
936
+
937
+ \subsection{Nonblocking Operation}
938
+ Though the Thrift transport interfaces map more directly to a blocking I/O
939
+ model, we have implemented a high performance \texttt{TNonBlockingServer}
940
+ in C++ based on \texttt{libevent} and the \texttt{TFramedTransport}. We
941
+ implemented this by moving all I/O into one tight event loop using a
942
+ state machine. Essentially, the event loop reads framed requests into
943
+ \texttt{TMemoryBuffer} objects. Once entire requests are ready, they are
944
+ dispatched to the \texttt{TProcessor} object which can read directly from
945
+ the data in memory.
946
+
947
+ \subsection{Compiler}
948
+ The Thrift compiler is implemented in C++ using standard \texttt{lex}/\texttt{yacc}
949
+ lexing and parsing. Though it could have been implemented with fewer
950
+ lines of code in another language (i.e. Python Lex-Yacc (PLY) or \texttt{ocamlyacc}), using C++
951
+ forces explicit definition of the language constructs. Strongly typing the
952
+ parse tree elements (debatably) makes the code more approachable for new
953
+ developers.
954
+
955
+ Code generation is done using two passes. The first pass looks only for
956
+ include files and type definitions. Type definitions are not checked during
957
+ this phase, since they may depend upon include files. All included files
958
+ are sequentially scanned in a first pass. Once the include tree has been
959
+ resolved, a second pass over all files is taken that inserts type definitions
960
+ into the parse tree and raises an error on any undefined types. The program is
961
+ then generated against the parse tree.
962
+
963
+ Due to inherent complexities and potential for circular dependencies,
964
+ we explicitly disallow forward declaration. Two Thrift structs cannot
965
+ each contain an instance of the other. (Since we do not allow \texttt{null}
966
+ struct instances in the generated C++ code, this would actually be impossible.)
967
+
968
+ \subsection{TFileTransport}
969
+ The \texttt{TFileTransport} logs Thrift requests/structs by
970
+ framing incoming data with its length and writing it out to disk.
971
+ Using a framed on-disk format allows for better error checking and
972
+ helps with the processing of a finite number of discrete events. The\\
973
+ \texttt{TFileWriterTransport} uses a system of swapping in-memory buffers
974
+ to ensure good performance while logging large amounts of data.
975
+ A Thrift log file is split up into chunks of a specified size; logged messages
976
+ are not allowed to cross chunk boundaries. A message that would cross a chunk
977
+ boundary will cause padding to be added until the end of the chunk and the
978
+ first byte of the message are aligned to the beginning of the next chunk.
979
+ Partitioning the file into chunks makes it possible to read and interpret data
980
+ from a particular point in the file.
981
+
982
+ \section{Facebook Thrift Services}
983
+ Thrift has been employed in a large number of applications at Facebook, including
984
+ search, logging, mobile, ads and the developer platform. Two specific usages are discussed below.
985
+
986
+ \subsection{Search}
987
+ Thrift is used as the underlying protocol and transport layer for the Facebook Search service.
988
+ The multi-language code generation is well suited for search because it allows for application
989
+ development in an efficient server side language (C++) and allows the Facebook PHP-based web application
990
+ to make calls to the search service using Thrift PHP libraries. There is also a large
991
+ variety of search stats, deployment and testing functionality that is built on top
992
+ of generated Python code. Additionally, the Thrift log file format is
993
+ used as a redo log for providing real-time search index updates. Thrift has allowed the
994
+ search team to leverage each language for its strengths and to develop code at a rapid pace.
995
+
996
+ \subsection{Logging}
997
+ The Thrift \texttt{TFileTransport} functionality is used for structured logging. Each
998
+ service function definition along with its parameters can be considered to be
999
+ a structured log entry identified by the function name. This log can then be used for
1000
+ a variety of purposes, including inline and offline processing, stats aggregation and as a redo log.
1001
+
1002
+ \section{Conclusions}
1003
+ Thrift has enabled Facebook to build scalable backend
1004
+ services efficiently by enabling engineers to divide and conquer. Application
1005
+ developers can focus on application code without worrying about the
1006
+ sockets layer. We avoid duplicated work by writing buffering and I/O logic
1007
+ in one place, rather than interspersing it in each application.
1008
+
1009
+ Thrift has been employed in a wide variety of applications at Facebook,
1010
+ including search, logging, mobile, ads, and the developer platform. We have
1011
+ found that the marginal performance cost incurred by an extra layer of
1012
+ software abstraction is far eclipsed by the gains in developer efficiency and
1013
+ systems reliability.
1014
+
1015
+ \appendix
1016
+
1017
+ \section{Similar Systems}
1018
+ The following are software systems similar to Thrift. Each is (very!) briefly
1019
+ described:
1020
+
1021
+ \begin{itemize}
1022
+ \item \textit{SOAP.} XML-based. Designed for web services via HTTP, excessive
1023
+ XML parsing overhead.
1024
+ \item \textit{CORBA.} Relatively comprehensive, debatably overdesigned and
1025
+ heavyweight. Comparably cumbersome software installation.
1026
+ \item \textit{COM.} Embraced mainly in Windows client softare. Not an entirely
1027
+ open solution.
1028
+ \item \textit{Pillar.} Lightweight and high-performance, but missing versioning
1029
+ and abstraction.
1030
+ \item \textit{Protocol Buffers.} Closed-source, owned by Google. Described in
1031
+ Sawzall paper.
1032
+ \end{itemize}
1033
+
1034
+ \acks
1035
+
1036
+ Many thanks for feedback on Thrift (and extreme trial by fire) are due to
1037
+ Martin Smith, Karl Voskuil and Yishan Wong.
1038
+
1039
+ Thrift is a successor to Pillar, a similar system developed
1040
+ by Adam D'Angelo, first while at Caltech and continued later at Facebook.
1041
+ Thrift simply would not have happened without Adam's insights.
1042
+
1043
+ \begin{thebibliography}{}
1044
+
1045
+ \bibitem{boost.threads}
1046
+ Kempf, William,
1047
+ ``Boost.Threads'',
1048
+ \url{http://www.boost.org/doc/html/threads.html}
1049
+
1050
+ \bibitem{boost.threadpool}
1051
+ Henkel, Philipp,
1052
+ ``threadpool'',
1053
+ \url{http://threadpool.sourceforge.net}
1054
+
1055
+ \end{thebibliography}
1056
+
1057
+ \end{document}