auser-poolparty 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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}