mongo 1.12.5 → 2.0.0.beta

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 (437) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/CONTRIBUTING.md +64 -0
  5. data/LICENSE +1 -1
  6. data/README.md +23 -125
  7. data/Rakefile +26 -21
  8. data/bin/mongo_console +6 -38
  9. data/lib/mongo.rb +23 -82
  10. data/lib/mongo/address.rb +111 -0
  11. data/lib/mongo/address/ipv4.rb +85 -0
  12. data/lib/mongo/address/ipv6.rb +85 -0
  13. data/lib/mongo/address/unix.rb +76 -0
  14. data/lib/mongo/auth.rb +108 -0
  15. data/lib/mongo/auth/cr.rb +44 -0
  16. data/lib/mongo/auth/cr/conversation.rb +119 -0
  17. data/lib/mongo/auth/executable.rb +52 -0
  18. data/lib/mongo/auth/ldap.rb +48 -0
  19. data/lib/mongo/auth/ldap/conversation.rb +92 -0
  20. data/lib/mongo/auth/roles.rb +104 -0
  21. data/lib/mongo/auth/scram.rb +53 -0
  22. data/lib/mongo/auth/scram/conversation.rb +450 -0
  23. data/lib/mongo/auth/user.rb +159 -0
  24. data/lib/mongo/auth/user/view.rb +102 -0
  25. data/lib/mongo/auth/x509.rb +48 -0
  26. data/lib/mongo/auth/x509/conversation.rb +92 -0
  27. data/lib/mongo/{gridfs.rb → bulk.rb} +2 -5
  28. data/lib/mongo/bulk/bulk_write.rb +307 -0
  29. data/lib/mongo/client.rb +233 -0
  30. data/lib/mongo/cluster.rb +203 -0
  31. data/lib/mongo/cluster/topology.rb +60 -0
  32. data/lib/mongo/cluster/topology/replica_set.rb +160 -0
  33. data/lib/mongo/cluster/topology/sharded.rb +132 -0
  34. data/lib/mongo/cluster/topology/standalone.rb +132 -0
  35. data/lib/mongo/cluster/topology/unknown.rb +155 -0
  36. data/lib/mongo/collection.rb +130 -1101
  37. data/lib/mongo/collection/view.rb +169 -0
  38. data/lib/mongo/collection/view/aggregation.rb +108 -0
  39. data/lib/mongo/collection/view/explainable.rb +49 -0
  40. data/lib/mongo/collection/view/immutable.rb +43 -0
  41. data/lib/mongo/collection/view/iterable.rb +48 -0
  42. data/lib/mongo/collection/view/map_reduce.rb +191 -0
  43. data/lib/mongo/collection/view/readable.rb +363 -0
  44. data/lib/mongo/collection/view/writable.rb +169 -0
  45. data/lib/mongo/cursor.rb +79 -680
  46. data/lib/mongo/database.rb +224 -0
  47. data/lib/mongo/database/view.rb +101 -0
  48. data/lib/mongo/error.rb +81 -0
  49. data/lib/mongo/error/bulk_write_failure.rb +41 -0
  50. data/lib/mongo/{utils/thread_local_variable_manager.rb → error/empty_batch.rb} +22 -8
  51. data/{test/functional/db_connection_test.rb → lib/mongo/error/invalid_bulk_operation.rb} +19 -8
  52. data/lib/mongo/error/invalid_collection_name.rb +39 -0
  53. data/lib/mongo/error/invalid_database_name.rb +39 -0
  54. data/{test/replica_set/ssl_test.rb → lib/mongo/error/invalid_document.rb} +21 -14
  55. data/lib/mongo/error/invalid_file.rb +38 -0
  56. data/lib/mongo/error/invalid_nonce.rb +46 -0
  57. data/lib/mongo/error/invalid_replacement_document.rb +39 -0
  58. data/lib/mongo/error/invalid_signature.rb +47 -0
  59. data/{test/functional/ssl_test.rb → lib/mongo/error/invalid_update_document.rb} +22 -12
  60. data/lib/mongo/error/max_bson_size.rb +40 -0
  61. data/lib/mongo/error/max_message_size.rb +42 -0
  62. data/lib/mongo/{utils.rb → error/need_primary_server.rb} +10 -6
  63. data/lib/mongo/{connection.rb → error/operation_failure.rb} +10 -6
  64. data/lib/mongo/error/parser.rb +77 -0
  65. data/lib/mongo/{connection/socket.rb → error/socket_error.rb} +10 -5
  66. data/lib/mongo/error/socket_timeout_error.rb +23 -0
  67. data/lib/mongo/error/unsupported_features.rb +43 -0
  68. data/lib/mongo/event.rb +40 -0
  69. data/lib/mongo/event/listeners.rb +63 -0
  70. data/lib/mongo/event/primary_elected.rb +53 -0
  71. data/lib/mongo/event/publisher.rb +42 -0
  72. data/lib/mongo/event/server_added.rb +53 -0
  73. data/lib/mongo/event/server_removed.rb +53 -0
  74. data/lib/mongo/event/subscriber.rb +41 -0
  75. data/lib/mongo/grid.rb +16 -0
  76. data/lib/mongo/grid/file.rb +94 -0
  77. data/lib/mongo/grid/file/chunk.rb +184 -0
  78. data/lib/mongo/grid/file/metadata.rb +223 -0
  79. data/lib/mongo/grid/fs.rb +149 -0
  80. data/lib/mongo/index.rb +64 -0
  81. data/lib/mongo/index/view.rb +205 -0
  82. data/lib/mongo/loggable.rb +126 -0
  83. data/lib/mongo/logger.rb +132 -0
  84. data/lib/mongo/operation.rb +26 -0
  85. data/lib/mongo/operation/aggregate.rb +100 -0
  86. data/lib/mongo/operation/aggregate/result.rb +84 -0
  87. data/lib/mongo/operation/batchable.rb +103 -0
  88. data/lib/mongo/operation/bulk_delete/result.rb +197 -0
  89. data/lib/mongo/operation/bulk_insert/result.rb +195 -0
  90. data/lib/mongo/operation/bulk_update/result.rb +295 -0
  91. data/lib/mongo/operation/command.rb +62 -0
  92. data/lib/mongo/operation/executable.rb +105 -0
  93. data/lib/mongo/operation/kill_cursors.rb +39 -0
  94. data/lib/mongo/operation/limited.rb +37 -0
  95. data/lib/mongo/operation/list_collections/result.rb +116 -0
  96. data/lib/mongo/operation/list_indexes/result.rb +118 -0
  97. data/lib/mongo/operation/map_reduce.rb +96 -0
  98. data/lib/mongo/operation/map_reduce/result.rb +122 -0
  99. data/lib/mongo/{functional.rb → operation/read.rb} +7 -7
  100. data/lib/mongo/operation/read/collections_info.rb +67 -0
  101. data/lib/mongo/operation/read/get_more.rb +71 -0
  102. data/lib/mongo/operation/read/indexes.rb +68 -0
  103. data/lib/mongo/operation/read/list_collections.rb +75 -0
  104. data/lib/mongo/operation/read/list_indexes.rb +77 -0
  105. data/lib/mongo/operation/read/query.rb +71 -0
  106. data/lib/mongo/operation/read_preferrable.rb +34 -0
  107. data/lib/mongo/operation/result.rb +259 -0
  108. data/lib/mongo/operation/specifiable.rb +380 -0
  109. data/lib/mongo/operation/write.rb +25 -0
  110. data/lib/mongo/operation/write/bulk_delete.rb +158 -0
  111. data/lib/mongo/operation/write/bulk_insert.rb +160 -0
  112. data/lib/mongo/operation/write/bulk_update.rb +167 -0
  113. data/lib/mongo/{connection/socket/socket_util.rb → operation/write/command.rb} +9 -24
  114. data/lib/mongo/operation/write/command/create_user.rb +43 -0
  115. data/lib/mongo/operation/write/command/delete.rb +56 -0
  116. data/lib/mongo/operation/write/command/drop_index.rb +51 -0
  117. data/lib/mongo/operation/write/command/ensure_index.rb +55 -0
  118. data/lib/mongo/operation/write/command/insert.rb +55 -0
  119. data/lib/mongo/operation/write/command/remove_user.rb +42 -0
  120. data/lib/mongo/operation/write/command/update.rb +60 -0
  121. data/lib/mongo/operation/write/command/writable.rb +61 -0
  122. data/lib/mongo/operation/write/create_index.rb +84 -0
  123. data/lib/mongo/operation/write/create_user.rb +75 -0
  124. data/lib/mongo/operation/write/delete.rb +91 -0
  125. data/lib/mongo/operation/write/drop_index.rb +62 -0
  126. data/lib/mongo/operation/write/insert.rb +88 -0
  127. data/lib/mongo/operation/write/remove_user.rb +70 -0
  128. data/lib/mongo/operation/write/update.rb +98 -0
  129. data/lib/mongo/protocol.rb +15 -0
  130. data/lib/mongo/protocol/bit_vector.rb +61 -0
  131. data/lib/mongo/protocol/delete.rb +94 -0
  132. data/lib/mongo/protocol/get_more.rb +99 -0
  133. data/lib/mongo/protocol/insert.rb +99 -0
  134. data/lib/mongo/protocol/kill_cursors.rb +74 -0
  135. data/lib/mongo/protocol/message.rb +252 -0
  136. data/lib/mongo/protocol/query.rb +147 -0
  137. data/lib/mongo/protocol/reply.rb +72 -0
  138. data/lib/mongo/protocol/serializers.rb +180 -0
  139. data/lib/mongo/protocol/update.rb +111 -0
  140. data/lib/mongo/server.rb +163 -0
  141. data/lib/mongo/server/connectable.rb +99 -0
  142. data/lib/mongo/server/connection.rb +133 -0
  143. data/lib/mongo/server/connection_pool.rb +141 -0
  144. data/lib/mongo/server/connection_pool/queue.rb +182 -0
  145. data/lib/mongo/server/context.rb +66 -0
  146. data/lib/mongo/server/description.rb +450 -0
  147. data/lib/mongo/server/description/features.rb +85 -0
  148. data/lib/mongo/server/description/inspector.rb +79 -0
  149. data/lib/mongo/server/description/inspector/primary_elected.rb +58 -0
  150. data/lib/mongo/server/description/inspector/server_added.rb +59 -0
  151. data/lib/mongo/server/description/inspector/server_removed.rb +59 -0
  152. data/lib/mongo/server/monitor.rb +160 -0
  153. data/lib/mongo/server/monitor/connection.rb +88 -0
  154. data/lib/mongo/server_selector.rb +81 -0
  155. data/lib/mongo/server_selector/nearest.rb +94 -0
  156. data/lib/mongo/server_selector/primary.rb +88 -0
  157. data/lib/mongo/server_selector/primary_preferred.rb +94 -0
  158. data/lib/mongo/server_selector/secondary.rb +91 -0
  159. data/lib/mongo/server_selector/secondary_preferred.rb +96 -0
  160. data/lib/mongo/server_selector/selectable.rb +209 -0
  161. data/lib/mongo/socket.rb +179 -0
  162. data/lib/mongo/socket/ssl.rb +108 -0
  163. data/lib/mongo/socket/tcp.rb +69 -0
  164. data/lib/mongo/socket/unix.rb +66 -0
  165. data/lib/mongo/uri.rb +504 -0
  166. data/lib/mongo/version.rb +21 -0
  167. data/lib/mongo/write_concern.rb +99 -0
  168. data/lib/mongo/write_concern/acknowledged.rb +38 -0
  169. data/lib/mongo/write_concern/normalizable.rb +73 -0
  170. data/lib/mongo/write_concern/unacknowledged.rb +43 -0
  171. data/mongo.gemspec +17 -14
  172. data/spec/mongo/address/ipv4_spec.rb +74 -0
  173. data/spec/mongo/address/ipv6_spec.rb +74 -0
  174. data/spec/mongo/address/unix_spec.rb +30 -0
  175. data/spec/mongo/address_spec.rb +206 -0
  176. data/spec/mongo/auth/cr_spec.rb +59 -0
  177. data/spec/mongo/auth/ldap_spec.rb +40 -0
  178. data/spec/mongo/auth/scram/conversation_spec.rb +197 -0
  179. data/spec/mongo/auth/scram_spec.rb +55 -0
  180. data/spec/mongo/auth/user/view_spec.rb +76 -0
  181. data/spec/mongo/auth/user_spec.rb +190 -0
  182. data/spec/mongo/auth/x509_spec.rb +40 -0
  183. data/spec/mongo/auth_spec.rb +65 -0
  184. data/spec/mongo/bulk/bulk_write_spec.rb +175 -0
  185. data/spec/mongo/client_spec.rb +564 -0
  186. data/spec/mongo/cluster/topology/replica_set_spec.rb +101 -0
  187. data/spec/mongo/cluster/topology/sharded_spec.rb +74 -0
  188. data/spec/mongo/cluster/topology/standalone_spec.rb +79 -0
  189. data/spec/mongo/cluster/topology_spec.rb +65 -0
  190. data/spec/mongo/cluster_spec.rb +129 -0
  191. data/spec/mongo/collection/view/aggregation_spec.rb +135 -0
  192. data/spec/mongo/collection/view/explainable_spec.rb +32 -0
  193. data/spec/mongo/collection/view/map_reduce_spec.rb +242 -0
  194. data/spec/mongo/collection/view/readable_spec.rb +603 -0
  195. data/spec/mongo/collection/view/writable_spec.rb +504 -0
  196. data/spec/mongo/collection/view_spec.rb +521 -0
  197. data/spec/mongo/collection_spec.rb +362 -0
  198. data/spec/mongo/cursor_spec.rb +295 -0
  199. data/spec/mongo/database_spec.rb +306 -0
  200. data/spec/mongo/error/parser_spec.rb +119 -0
  201. data/spec/mongo/event/publisher_spec.rb +50 -0
  202. data/spec/mongo/event/subscriber_spec.rb +34 -0
  203. data/spec/mongo/grid/file/chunk_spec.rb +226 -0
  204. data/spec/mongo/grid/file/metadata_spec.rb +69 -0
  205. data/spec/mongo/grid/file_spec.rb +138 -0
  206. data/spec/mongo/grid/fs_spec.rb +129 -0
  207. data/spec/mongo/index/view_spec.rb +226 -0
  208. data/spec/mongo/loggable_spec.rb +62 -0
  209. data/spec/mongo/logger_spec.rb +97 -0
  210. data/spec/mongo/operation/aggregate/result_spec.rb +80 -0
  211. data/spec/mongo/operation/aggregate_spec.rb +135 -0
  212. data/spec/mongo/operation/command_spec.rb +106 -0
  213. data/spec/mongo/operation/kill_cursors_spec.rb +66 -0
  214. data/spec/mongo/operation/limited_spec.rb +50 -0
  215. data/spec/mongo/operation/map_reduce_spec.rb +143 -0
  216. data/spec/mongo/operation/read/collections_info_spec.rb +40 -0
  217. data/spec/mongo/operation/read/get_more_spec.rb +81 -0
  218. data/spec/mongo/operation/read/indexes_spec.rb +31 -0
  219. data/spec/mongo/operation/read/query_spec.rb +84 -0
  220. data/spec/mongo/operation/result_spec.rb +275 -0
  221. data/spec/mongo/operation/specifiable_spec.rb +53 -0
  222. data/spec/mongo/operation/write/bulk_delete_spec.rb +473 -0
  223. data/spec/mongo/operation/write/bulk_insert_spec.rb +466 -0
  224. data/spec/mongo/operation/write/bulk_update_spec.rb +524 -0
  225. data/spec/mongo/operation/write/command/delete_spec.rb +116 -0
  226. data/spec/mongo/operation/write/command/insert_spec.rb +117 -0
  227. data/spec/mongo/operation/write/command/update_spec.rb +123 -0
  228. data/spec/mongo/operation/write/create_user_spec.rb +44 -0
  229. data/spec/mongo/operation/write/delete_spec.rb +178 -0
  230. data/spec/mongo/operation/write/drop_index_spec.rb +51 -0
  231. data/spec/mongo/operation/write/ensure_index_spec.rb +81 -0
  232. data/spec/mongo/operation/write/insert_spec.rb +231 -0
  233. data/spec/mongo/operation/write/remove_user_spec.rb +46 -0
  234. data/spec/mongo/operation/write/response_spec.rb +85 -0
  235. data/spec/mongo/operation/write/update_spec.rb +177 -0
  236. data/spec/mongo/protocol/delete_spec.rb +167 -0
  237. data/spec/mongo/protocol/get_more_spec.rb +146 -0
  238. data/spec/mongo/protocol/insert_spec.rb +161 -0
  239. data/spec/mongo/protocol/kill_cursors_spec.rb +101 -0
  240. data/spec/mongo/protocol/query_spec.rb +285 -0
  241. data/spec/mongo/protocol/reply_spec.rb +157 -0
  242. data/spec/mongo/protocol/update_spec.rb +186 -0
  243. data/spec/mongo/server/connection_pool/queue_spec.rb +170 -0
  244. data/spec/mongo/server/connection_pool_spec.rb +120 -0
  245. data/spec/mongo/server/connection_spec.rb +289 -0
  246. data/spec/mongo/server/description/features_spec.rb +138 -0
  247. data/spec/mongo/server/description/inspector/primary_elected_spec.rb +94 -0
  248. data/spec/mongo/server/description/inspector/server_added_spec.rb +92 -0
  249. data/spec/mongo/server/description/inspector/server_removed_spec.rb +95 -0
  250. data/spec/mongo/server/description_spec.rb +510 -0
  251. data/spec/mongo/server/monitor_spec.rb +130 -0
  252. data/spec/mongo/server_discovery_and_monitoring_spec.rb +103 -0
  253. data/spec/mongo/server_selection_rtt_spec.rb +104 -0
  254. data/spec/mongo/server_selection_spec.rb +89 -0
  255. data/spec/mongo/server_selector/nearest_spec.rb +250 -0
  256. data/spec/mongo/server_selector/primary_preferred_spec.rb +290 -0
  257. data/spec/mongo/server_selector/primary_spec.rb +114 -0
  258. data/spec/mongo/server_selector/secondary_preferred_spec.rb +252 -0
  259. data/spec/mongo/server_selector/secondary_spec.rb +196 -0
  260. data/spec/mongo/server_selector_spec.rb +101 -0
  261. data/spec/mongo/server_spec.rb +131 -0
  262. data/spec/mongo/uri_spec.rb +517 -0
  263. data/spec/mongo/write_concern/acknowledged_spec.rb +44 -0
  264. data/spec/mongo/write_concern/unacknowledged_spec.rb +15 -0
  265. data/spec/mongo_orchestration_spec.rb +70 -0
  266. data/spec/spec_helper.rb +148 -0
  267. data/spec/support/authorization.rb +245 -0
  268. data/spec/support/helpers.rb +140 -0
  269. data/spec/support/matchers.rb +37 -0
  270. data/spec/support/mongo_orchestration.rb +61 -0
  271. data/spec/support/mongo_orchestration/requestable.rb +109 -0
  272. data/spec/support/mongo_orchestration/standalone.rb +57 -0
  273. data/spec/support/sdam/rs/discover_arbiters.yml +41 -0
  274. data/spec/support/sdam/rs/discover_passives.yml +41 -0
  275. data/spec/support/sdam/rs/discover_primary.yml +40 -0
  276. data/spec/support/sdam/rs/discover_secondary.yml +41 -0
  277. data/spec/support/sdam/rs/discovery.yml +195 -0
  278. data/spec/support/sdam/rs/ghost_discovered.yml +39 -0
  279. data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +34 -0
  280. data/spec/support/sdam/rs/member_reconfig.yml +68 -0
  281. data/spec/support/sdam/rs/member_standalone.yml +60 -0
  282. data/spec/support/sdam/rs/new_primary.yml +74 -0
  283. data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +71 -0
  284. data/spec/support/sdam/rs/non_rs_member.yml +31 -0
  285. data/spec/support/sdam/rs/normalize_case.yml +49 -0
  286. data/spec/support/sdam/rs/primary_becomes_standalone.yml +52 -0
  287. data/spec/support/sdam/rs/primary_changes_set_name.yml +57 -0
  288. data/spec/support/sdam/rs/primary_disconnect.yml +56 -0
  289. data/spec/support/sdam/rs/primary_wrong_set_name.yml +27 -0
  290. data/spec/support/sdam/rs/response_from_removed.yml +63 -0
  291. data/spec/support/sdam/rs/rsother_discovered.yml +41 -0
  292. data/spec/support/sdam/rs/sec_not_auth.yml +49 -0
  293. data/spec/support/sdam/rs/secondary_wrong_set_name.yml +28 -0
  294. data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +69 -0
  295. data/spec/support/sdam/rs/unexpected_mongos.yml +26 -0
  296. data/spec/support/sdam/rs/wrong_set_name.yml +35 -0
  297. data/spec/support/sdam/sharded/multiple_mongoses.yml +46 -0
  298. data/spec/support/sdam/sharded/non_mongos_removed.yml +41 -0
  299. data/spec/support/sdam/sharded/normalize_uri_case.yml +32 -0
  300. data/spec/support/sdam/single/direct_connection_external_ip.yml +34 -0
  301. data/spec/support/sdam/single/direct_connection_mongos.yml +33 -0
  302. data/spec/support/sdam/single/direct_connection_rsarbiter.yml +35 -0
  303. data/spec/support/sdam/single/direct_connection_rsprimary.yml +34 -0
  304. data/spec/support/sdam/single/direct_connection_rssecondary.yml +35 -0
  305. data/spec/support/sdam/single/direct_connection_slave.yml +32 -0
  306. data/spec/support/sdam/single/direct_connection_standalone.yml +32 -0
  307. data/spec/support/sdam/single/not_ok_response.yml +39 -0
  308. data/spec/support/sdam/single/standalone_removed.yml +32 -0
  309. data/spec/support/sdam/single/unavailable_seed.yml +28 -0
  310. data/spec/support/server_discovery_and_monitoring.rb +167 -0
  311. data/spec/support/server_selection.rb +140 -0
  312. data/spec/support/server_selection/rtt/first_value.yml +4 -0
  313. data/spec/support/server_selection/rtt/first_value_zero.yml +4 -0
  314. data/spec/support/server_selection/rtt/value_test_1.yml +4 -0
  315. data/spec/support/server_selection/rtt/value_test_2.yml +4 -0
  316. data/spec/support/server_selection/rtt/value_test_3.yml +4 -0
  317. data/spec/support/server_selection/rtt/value_test_4.yml +4 -0
  318. data/spec/support/server_selection/rtt/value_test_5.yml +4 -0
  319. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest.yml +32 -0
  320. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest_non_matching.yml +27 -0
  321. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Primary.yml +23 -0
  322. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/PrimaryPreferred.yml +32 -0
  323. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/PrimaryPreferred_non_matching.yml +27 -0
  324. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary.yml +32 -0
  325. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/SecondaryPreferred.yml +32 -0
  326. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/SecondaryPreferred_non_matching.yml +27 -0
  327. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary_non_matching.yml +27 -0
  328. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest.yml +41 -0
  329. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest_non_matching.yml +34 -0
  330. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Primary.yml +33 -0
  331. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/PrimaryPreferred.yml +39 -0
  332. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/PrimaryPreferred_non_matching.yml +36 -0
  333. data/spec/support/server_selection/selection/Sharded/read/SecondaryPreferred.yml +32 -0
  334. data/spec/support/server_selection/selection/Single/read/SecondaryPreferred.yml +23 -0
  335. data/spec/support/server_selection/selection/Unknown/read/SecondaryPreferred.yml +13 -0
  336. data/spec/support/server_selection_rtt.rb +41 -0
  337. data/spec/support/shared/bulk_write.rb +498 -0
  338. data/spec/support/shared/cursor.rb +38 -0
  339. data/spec/support/shared/operation.rb +77 -0
  340. data/spec/support/shared/protocol.rb +31 -0
  341. data/spec/support/shared/server_selector.rb +111 -0
  342. data/spec/support/shared/socket.rb +82 -0
  343. data/spec/support/travis.rb +14 -0
  344. metadata +523 -189
  345. metadata.gz.sig +0 -0
  346. data/VERSION +0 -1
  347. data/lib/mongo/bulk_write_collection_view.rb +0 -387
  348. data/lib/mongo/collection_writer.rb +0 -364
  349. data/lib/mongo/connection/node.rb +0 -249
  350. data/lib/mongo/connection/pool.rb +0 -340
  351. data/lib/mongo/connection/pool_manager.rb +0 -320
  352. data/lib/mongo/connection/sharding_pool_manager.rb +0 -67
  353. data/lib/mongo/connection/socket/ssl_socket.rb +0 -95
  354. data/lib/mongo/connection/socket/tcp_socket.rb +0 -87
  355. data/lib/mongo/connection/socket/unix_socket.rb +0 -39
  356. data/lib/mongo/db.rb +0 -808
  357. data/lib/mongo/exception.rb +0 -145
  358. data/lib/mongo/functional/authentication.rb +0 -455
  359. data/lib/mongo/functional/logging.rb +0 -85
  360. data/lib/mongo/functional/read_preference.rb +0 -183
  361. data/lib/mongo/functional/scram.rb +0 -556
  362. data/lib/mongo/functional/uri_parser.rb +0 -409
  363. data/lib/mongo/functional/write_concern.rb +0 -66
  364. data/lib/mongo/gridfs/grid.rb +0 -112
  365. data/lib/mongo/gridfs/grid_ext.rb +0 -53
  366. data/lib/mongo/gridfs/grid_file_system.rb +0 -163
  367. data/lib/mongo/gridfs/grid_io.rb +0 -484
  368. data/lib/mongo/legacy.rb +0 -140
  369. data/lib/mongo/mongo_client.rb +0 -697
  370. data/lib/mongo/mongo_replica_set_client.rb +0 -535
  371. data/lib/mongo/mongo_sharded_client.rb +0 -159
  372. data/lib/mongo/networking.rb +0 -372
  373. data/lib/mongo/utils/conversions.rb +0 -110
  374. data/lib/mongo/utils/core_ext.rb +0 -70
  375. data/lib/mongo/utils/server_version.rb +0 -69
  376. data/lib/mongo/utils/support.rb +0 -80
  377. data/test/functional/authentication_test.rb +0 -39
  378. data/test/functional/bulk_api_stress_test.rb +0 -133
  379. data/test/functional/bulk_write_collection_view_test.rb +0 -1198
  380. data/test/functional/client_test.rb +0 -627
  381. data/test/functional/collection_test.rb +0 -2175
  382. data/test/functional/collection_writer_test.rb +0 -83
  383. data/test/functional/conversions_test.rb +0 -163
  384. data/test/functional/cursor_fail_test.rb +0 -57
  385. data/test/functional/cursor_message_test.rb +0 -56
  386. data/test/functional/cursor_test.rb +0 -683
  387. data/test/functional/db_api_test.rb +0 -835
  388. data/test/functional/db_test.rb +0 -348
  389. data/test/functional/grid_file_system_test.rb +0 -285
  390. data/test/functional/grid_io_test.rb +0 -252
  391. data/test/functional/grid_test.rb +0 -273
  392. data/test/functional/pool_test.rb +0 -136
  393. data/test/functional/safe_test.rb +0 -98
  394. data/test/functional/support_test.rb +0 -62
  395. data/test/functional/timeout_test.rb +0 -60
  396. data/test/functional/uri_test.rb +0 -446
  397. data/test/functional/write_concern_test.rb +0 -118
  398. data/test/helpers/general.rb +0 -50
  399. data/test/helpers/test_unit.rb +0 -476
  400. data/test/replica_set/authentication_test.rb +0 -37
  401. data/test/replica_set/basic_test.rb +0 -189
  402. data/test/replica_set/client_test.rb +0 -393
  403. data/test/replica_set/connection_test.rb +0 -138
  404. data/test/replica_set/count_test.rb +0 -66
  405. data/test/replica_set/cursor_test.rb +0 -220
  406. data/test/replica_set/insert_test.rb +0 -157
  407. data/test/replica_set/max_values_test.rb +0 -151
  408. data/test/replica_set/pinning_test.rb +0 -105
  409. data/test/replica_set/query_test.rb +0 -73
  410. data/test/replica_set/read_preference_test.rb +0 -219
  411. data/test/replica_set/refresh_test.rb +0 -211
  412. data/test/replica_set/replication_ack_test.rb +0 -95
  413. data/test/sharded_cluster/basic_test.rb +0 -203
  414. data/test/shared/authentication/basic_auth_shared.rb +0 -260
  415. data/test/shared/authentication/bulk_api_auth_shared.rb +0 -249
  416. data/test/shared/authentication/gssapi_shared.rb +0 -176
  417. data/test/shared/authentication/sasl_plain_shared.rb +0 -96
  418. data/test/shared/authentication/scram_shared.rb +0 -92
  419. data/test/shared/ssl_shared.rb +0 -235
  420. data/test/test_helper.rb +0 -61
  421. data/test/threading/basic_test.rb +0 -120
  422. data/test/tools/mongo_config.rb +0 -708
  423. data/test/tools/mongo_config_test.rb +0 -160
  424. data/test/unit/client_test.rb +0 -381
  425. data/test/unit/collection_test.rb +0 -166
  426. data/test/unit/connection_test.rb +0 -335
  427. data/test/unit/cursor_test.rb +0 -307
  428. data/test/unit/db_test.rb +0 -136
  429. data/test/unit/grid_test.rb +0 -76
  430. data/test/unit/mongo_sharded_client_test.rb +0 -48
  431. data/test/unit/node_test.rb +0 -93
  432. data/test/unit/pool_manager_test.rb +0 -111
  433. data/test/unit/read_pref_test.rb +0 -406
  434. data/test/unit/read_test.rb +0 -159
  435. data/test/unit/safe_test.rb +0 -158
  436. data/test/unit/sharding_pool_manager_test.rb +0 -84
  437. data/test/unit/write_concern_test.rb +0 -175
@@ -1,159 +0,0 @@
1
- # Copyright (C) 2009-2013 MongoDB, Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- module Mongo
16
-
17
- # Instantiates and manages connections to a MongoDB sharded cluster for high availability.
18
- class MongoShardedClient < MongoReplicaSetClient
19
- include ThreadLocalVariableManager
20
-
21
- SHARDED_CLUSTER_OPTS = [:refresh_mode, :refresh_interval, :tag_sets, :read]
22
-
23
- attr_reader :seeds, :refresh_interval, :refresh_mode,
24
- :refresh_version, :manager
25
-
26
- def initialize(*args)
27
- opts = args.last.is_a?(Hash) ? args.pop : {}
28
-
29
- nodes = args.flatten
30
-
31
- if nodes.empty? and ENV.has_key?('MONGODB_URI')
32
- parser = URIParser.new ENV['MONGODB_URI']
33
- opts = parser.connection_options.merge! opts
34
- nodes = parser.node_strings
35
- end
36
-
37
- unless nodes.length > 0
38
- raise MongoArgumentError, "A MongoShardedClient requires at least one seed node."
39
- end
40
-
41
- @seeds = nodes.map do |host_port|
42
- Support.normalize_seeds(host_port)
43
- end
44
-
45
- # TODO: add a method for replacing this list of node.
46
- @seeds.freeze
47
-
48
- # Refresh
49
- @last_refresh = Time.now
50
- @refresh_version = 0
51
-
52
- # No connection manager by default.
53
- @manager = nil
54
-
55
- # Lock for request ids.
56
- @id_lock = Mutex.new
57
-
58
- @connected = false
59
-
60
- @connect_mutex = Mutex.new
61
-
62
- @mongos = true
63
-
64
- check_opts(opts)
65
- setup(opts)
66
- end
67
-
68
- def valid_opts
69
- super + SHARDED_CLUSTER_OPTS
70
- end
71
-
72
- def inspect
73
- "<Mongo::MongoShardedClient:0x#{self.object_id.to_s(16)} @seeds=#{@seeds.inspect} " +
74
- "@connected=#{@connected}>"
75
- end
76
-
77
- # Initiate a connection to the sharded cluster.
78
- def connect(force = !connected?)
79
- return unless force
80
- log(:info, "Connecting...")
81
-
82
- # Prevent recursive connection attempts from the same thread.
83
- # This is done rather than using a Monitor to prevent potentially recursing
84
- # infinitely while attempting to connect and continually failing. Instead, fail fast.
85
- raise ConnectionFailure, "Failed to get node data." if thread_local[:locks][:connecting]
86
-
87
- @connect_mutex.synchronize do
88
- begin
89
- thread_local[:locks][:connecting] = true
90
- if @manager
91
- thread_local[:managers][self] = @manager
92
- @manager.refresh! @seeds
93
- else
94
- @manager = ShardingPoolManager.new(self, @seeds)
95
- ensure_manager
96
- @manager.connect
97
- check_wire_version_in_range
98
- end
99
- ensure
100
- thread_local[:locks][:connecting] = false
101
- end
102
-
103
- @refresh_version += 1
104
- @last_refresh = Time.now
105
- @connected = true
106
- end
107
- end
108
-
109
- # Force a hard refresh of this connection's view
110
- # of the sharded cluster.
111
- #
112
- # @return [Boolean] +true+ if hard refresh
113
- # occurred. +false+ is returned when unable
114
- # to get the refresh lock.
115
- def hard_refresh!
116
- log(:info, "Initiating hard refresh...")
117
- connect(true)
118
- return true
119
- end
120
-
121
- def connected?
122
- !!(@connected && @manager.primary_pool)
123
- end
124
-
125
- # Returns +true+ if it's okay to read from a secondary node.
126
- # Since this is a sharded cluster, this must always be false.
127
- #
128
- # This method exist primarily so that Cursor objects will
129
- # generate query messages with a slaveOkay value of +true+.
130
- #
131
- # @return [Boolean] +true+
132
- def slave_ok?
133
- false
134
- end
135
-
136
- def checkout(&block)
137
- tries = 0
138
- begin
139
- super(&block)
140
- rescue ConnectionFailure
141
- tries +=1
142
- tries < 2 ? retry : raise
143
- end
144
- end
145
-
146
- # Initialize a connection to MongoDB using the MongoDB URI spec.
147
- #
148
- # @param uri [ String ] string of the format:
149
- # mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/database]
150
- #
151
- # @param options [ Hash ] Any of the options available for MongoShardedClient.new
152
- #
153
- # @return [ Mongo::MongoShardedClient ] The sharded client.
154
- def self.from_uri(uri, options={})
155
- uri ||= ENV['MONGODB_URI']
156
- URIParser.new(uri).connection(options, false, true)
157
- end
158
- end
159
- end
@@ -1,372 +0,0 @@
1
- # Copyright (C) 2009-2013 MongoDB, Inc.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- module Mongo
16
- module Networking
17
-
18
- STANDARD_HEADER_SIZE = 16
19
- RESPONSE_HEADER_SIZE = 20
20
-
21
- # Counter for generating unique request ids.
22
- @@current_request_id = 0
23
-
24
- # Send a message to MongoDB, adding the necessary headers.
25
- #
26
- # @param [Integer] operation a MongoDB opcode.
27
- # @param [BSON::ByteBuffer] message a message to send to the database.
28
- #
29
- # @option opts [Symbol] :connection (:writer) The connection to which
30
- # this message should be sent. Valid options are :writer and :reader.
31
- #
32
- # @return [Integer] number of bytes sent
33
- def send_message(operation, message, opts={})
34
- if opts.is_a?(String)
35
- warn "MongoClient#send_message no longer takes a string log message. " +
36
- "Logging is now handled within the Collection and Cursor classes."
37
- opts = {}
38
- end
39
-
40
- add_message_headers(message, operation)
41
- packed_message = message.to_s
42
-
43
- sock = nil
44
- pool = opts.fetch(:pool, nil)
45
- begin
46
- if pool
47
- #puts "send_message pool.port:#{pool.port}"
48
- sock = pool.checkout
49
- else
50
- sock ||= checkout_writer
51
- end
52
- send_message_on_socket(packed_message, sock)
53
- rescue SystemStackError, NoMemoryError, SystemCallError => ex
54
- close
55
- raise ex
56
- ensure
57
- if sock
58
- sock.checkin
59
- end
60
- end
61
- true
62
- end
63
-
64
- # Sends a message to the database, waits for a response, and raises
65
- # an exception if the operation has failed.
66
- #
67
- # @param [Integer] operation a MongoDB opcode.
68
- # @param [BSON::ByteBuffer] message a message to send to the database.
69
- # @param [String] db_name the name of the database. used on call to get_last_error.
70
- # @param [String] log_message this is currently a no-op and will be removed.
71
- # @param [Hash] write_concern write concern.
72
- #
73
- # @see DB#get_last_error for valid last error params.
74
- #
75
- # @return [Hash] The document returned by the call to getlasterror.
76
- def send_message_with_gle(operation, message, db_name, log_message=nil, write_concern=false)
77
- docs = num_received = cursor_id = ''
78
- add_message_headers(message, operation)
79
-
80
- last_error_message = build_get_last_error_message(db_name, write_concern)
81
- last_error_id = add_message_headers(last_error_message, Mongo::Constants::OP_QUERY)
82
-
83
- packed_message = message.append!(last_error_message).to_s
84
- sock = nil
85
- begin
86
- sock = checkout_writer
87
- send_message_on_socket(packed_message, sock)
88
- docs, num_received, cursor_id = receive(sock, last_error_id)
89
- rescue ConnectionFailure, OperationFailure, OperationTimeout => ex
90
- raise ex
91
- rescue SystemStackError, NoMemoryError, SystemCallError => ex
92
- close
93
- sock = nil
94
- raise ex
95
- ensure
96
- checkin(sock) if sock
97
- sock = nil
98
- end
99
-
100
- if num_received == 1
101
- error = docs[0]['err'] || docs[0]['errmsg']
102
- if error && error.include?("not master")
103
- close
104
- raise ConnectionFailure.new(docs[0]['code'].to_s + ': ' + error, docs[0]['code'], docs[0])
105
- elsif (!error.nil? && note = docs[0]['jnote'] || docs[0]['wnote']) # assignment
106
- code = docs[0]['code'] || Mongo::ErrorCode::BAD_VALUE # as of server version 2.5.5
107
- raise WriteConcernError.new(code.to_s + ': ' + note, code, docs[0])
108
- elsif error
109
- code = docs[0]['code'] || Mongo::ErrorCode::UNKNOWN_ERROR
110
- error = "wtimeout" if error == "timeout"
111
- raise WriteConcernError.new(code.to_s + ': ' + error, code, docs[0]) if error == "wtimeout"
112
- raise OperationFailure.new(code.to_s + ': ' + error, code, docs[0])
113
- end
114
- end
115
-
116
- docs[0]
117
- end
118
-
119
- # Sends a message to the database and waits for the response.
120
- #
121
- # @param [Integer] operation a MongoDB opcode.
122
- # @param [BSON::ByteBuffer] message a message to send to the database.
123
- # @param [String] log_message this is currently a no-op and will be removed.
124
- # @param [Socket] socket a socket to use in lieu of checking out a new one.
125
- # @param [Boolean] command (false) indicate whether this is a command. If this is a command,
126
- # the message will be sent to the primary node.
127
- # @param [Symbol] read the read preference.
128
- # @param [Boolean] exhaust (false) indicate whether the cursor should be exhausted. Set
129
- # this to true only when the OP_QUERY_EXHAUST flag is set.
130
- # @param [Boolean] compile_regex whether BSON regex objects should be compiled into Ruby regexes.
131
- #
132
- # @return [Array]
133
- # An array whose indexes include [0] documents returned, [1] number of document received,
134
- # and [3] a cursor_id.
135
- def receive_message(operation, message, log_message=nil, socket=nil, command=false,
136
- read=:primary, exhaust=false, compile_regex=true)
137
- request_id = add_message_headers(message, operation)
138
- packed_message = message.to_s
139
- opts = { :exhaust => exhaust,
140
- :compile_regex => compile_regex }
141
-
142
- result = ''
143
-
144
- begin
145
- send_message_on_socket(packed_message, socket)
146
- result = receive(socket, request_id, opts)
147
- rescue ConnectionFailure => ex
148
- socket.close
149
- checkin(socket)
150
- raise ex
151
- rescue SystemStackError, NoMemoryError, SystemCallError => ex
152
- close
153
- raise ex
154
- rescue Exception => ex
155
- if defined?(IRB)
156
- close if ex.class == IRB::Abort
157
- end
158
- raise ex
159
- end
160
- result
161
- end
162
-
163
- private
164
-
165
- def receive(sock, cursor_id, opts={})
166
- exhaust = !!opts.delete(:exhaust)
167
-
168
- if exhaust
169
- docs = []
170
- num_received = 0
171
-
172
- while(cursor_id != 0) do
173
- receive_header(sock, cursor_id, exhaust)
174
- number_received, cursor_id = receive_response_header(sock)
175
- new_docs, n = read_documents(number_received, sock, opts)
176
- docs += new_docs
177
- num_received += n
178
- end
179
-
180
- return [docs, num_received, cursor_id]
181
- else
182
- receive_header(sock, cursor_id, exhaust)
183
- number_received, cursor_id = receive_response_header(sock)
184
- docs, num_received = read_documents(number_received, sock, opts)
185
-
186
- return [docs, num_received, cursor_id]
187
- end
188
- end
189
-
190
- def receive_header(sock, expected_response, exhaust=false)
191
- header = receive_message_on_socket(16, sock)
192
-
193
- # unpacks to size, request_id, response_to
194
- response_to = header.unpack('VVV')[2]
195
- if !exhaust && expected_response != response_to
196
- raise Mongo::ConnectionFailure, "Expected response #{expected_response} but got #{response_to}"
197
- end
198
-
199
- unless header.size == STANDARD_HEADER_SIZE
200
- raise "Short read for DB response header: " +
201
- "expected #{STANDARD_HEADER_SIZE} bytes, saw #{header.size}"
202
- end
203
- nil
204
- end
205
-
206
- def receive_response_header(sock)
207
- header_buf = receive_message_on_socket(RESPONSE_HEADER_SIZE, sock)
208
- if header_buf.length != RESPONSE_HEADER_SIZE
209
- raise "Short read for DB response header; " +
210
- "expected #{RESPONSE_HEADER_SIZE} bytes, saw #{header_buf.length}"
211
- end
212
-
213
- # unpacks to flags, cursor_id_a, cursor_id_b, starting_from, number_remaining
214
- flags, cursor_id_a, cursor_id_b, _, number_remaining = header_buf.unpack('VVVVV')
215
-
216
- check_response_flags(flags)
217
- cursor_id = (cursor_id_b << 32) + cursor_id_a
218
- [number_remaining, cursor_id]
219
- end
220
-
221
- def check_response_flags(flags)
222
- if flags & Mongo::Constants::REPLY_CURSOR_NOT_FOUND != 0
223
- raise Mongo::OperationFailure, "Query response returned CURSOR_NOT_FOUND. " +
224
- "Either an invalid cursor was specified, or the cursor may have timed out on the server."
225
- elsif flags & Mongo::Constants::REPLY_QUERY_FAILURE != 0
226
- # Mongo query reply failures are handled in Cursor#next.
227
- end
228
- end
229
-
230
- def read_documents(number_received, sock, opts)
231
- docs = []
232
- number_remaining = number_received
233
- while number_remaining > 0 do
234
- buf = receive_message_on_socket(4, sock)
235
- size = buf.unpack('V')[0]
236
- buf << receive_message_on_socket(size - 4, sock)
237
- number_remaining -= 1
238
- docs << BSON::BSON_CODER.deserialize(buf, opts)
239
- end
240
- [docs, number_received]
241
- end
242
-
243
- def build_command_message(db_name, query, projection=nil, skip=0, limit=-1)
244
- message = BSON::ByteBuffer.new("", max_message_size)
245
- message.put_int(0)
246
- BSON::BSON_RUBY.serialize_cstr(message, "#{db_name}.$cmd")
247
- message.put_int(skip)
248
- message.put_int(limit)
249
- message.put_binary(BSON::BSON_CODER.serialize(query, false, false, max_bson_size).to_s)
250
- message.put_binary(BSON::BSON_CODER.serialize(projection, false, false, max_bson_size).to_s) if projection
251
- message
252
- end
253
-
254
- # Constructs a getlasterror message. This method is used exclusively by
255
- # MongoClient#send_message_with_gle.
256
- def build_get_last_error_message(db_name, write_concern)
257
- gle = BSON::OrderedHash.new
258
- gle[:getlasterror] = 1
259
- if write_concern.is_a?(Hash)
260
- write_concern.assert_valid_keys(:w, :wtimeout, :fsync, :j)
261
- gle.merge!(write_concern)
262
- gle.delete(:w) if gle[:w] == 1
263
- end
264
- gle[:w] = gle[:w].to_s if gle[:w].is_a?(Symbol)
265
- build_command_message(db_name, gle)
266
- end
267
-
268
- # Prepares a message for transmission to MongoDB by
269
- # constructing a valid message header.
270
- #
271
- # Note: this method modifies message by reference.
272
- #
273
- # @return [Integer] the request id used in the header
274
- def add_message_headers(message, operation)
275
- headers = [
276
- # Message size.
277
- 16 + message.size,
278
-
279
- # Unique request id.
280
- request_id = get_request_id,
281
-
282
- # Response id.
283
- 0,
284
-
285
- # Opcode.
286
- operation
287
- ].pack('VVVV')
288
-
289
- message.prepend!(headers)
290
-
291
- request_id
292
- end
293
-
294
- # Increment and return the next available request id.
295
- #
296
- # return [Integer]
297
- def get_request_id
298
- request_id = ''
299
- @id_lock.synchronize do
300
- request_id = @@current_request_id += 1
301
- end
302
- request_id
303
- end
304
-
305
- # Low-level method for sending a message on a socket.
306
- # Requires a packed message and an available socket,
307
- #
308
- # @return [Integer] number of bytes sent
309
- def send_message_on_socket(packed_message, socket)
310
- begin
311
- total_bytes_sent = socket.send(packed_message)
312
- if total_bytes_sent != packed_message.size
313
- packed_message.slice!(0, total_bytes_sent)
314
- while packed_message.size > 0
315
- byte_sent = socket.send(packed_message)
316
- total_bytes_sent += byte_sent
317
- packed_message.slice!(0, byte_sent)
318
- end
319
- end
320
- total_bytes_sent
321
- rescue => ex
322
- socket.close
323
- raise ConnectionFailure, "Operation failed with the following exception: #{ex}:#{ex.message}"
324
- end
325
- end
326
-
327
- # Low-level method for receiving data from socket.
328
- # Requires length and an available socket.
329
- def receive_message_on_socket(length, socket)
330
- begin
331
- message = receive_data(length, socket)
332
- rescue OperationTimeout, ConnectionFailure => ex
333
- socket.close
334
-
335
- if ex.class == OperationTimeout
336
- raise OperationTimeout, "Timed out waiting on socket read."
337
- else
338
- raise ConnectionFailure, "Operation failed with the following exception: #{ex}"
339
- end
340
- end
341
- message
342
- end
343
-
344
- def receive_data(length, socket)
345
- message = new_binary_string
346
- socket.read(length, message)
347
-
348
- raise ConnectionFailure, "connection closed" unless message && message.length > 0
349
- if message.length < length
350
- chunk = new_binary_string
351
- while message.length < length
352
- socket.read(length - message.length, chunk)
353
- raise ConnectionFailure, "connection closed" unless chunk.length > 0
354
- message << chunk
355
- end
356
- end
357
- message
358
- end
359
-
360
- if defined?(Encoding)
361
- BINARY_ENCODING = Encoding.find("binary")
362
-
363
- def new_binary_string
364
- "".force_encoding(BINARY_ENCODING)
365
- end
366
- else
367
- def new_binary_string
368
- ""
369
- end
370
- end
371
- end
372
- end