couchbase 3.1.1 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (220) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/ext/CMakeLists.txt +3 -1
  4. data/ext/build_version.hxx.in +1 -1
  5. data/ext/cmake/Testing.cmake +1 -0
  6. data/ext/cmake/ThirdPartyDependencies.cmake +6 -0
  7. data/ext/cmake/VersionInfo.cmake +3 -0
  8. data/ext/couchbase/bucket.hxx +47 -28
  9. data/ext/couchbase/cbsasl/client.h +1 -1
  10. data/ext/couchbase/cbsasl/context.cc +1 -1
  11. data/ext/couchbase/cbsasl/context.h +3 -3
  12. data/ext/couchbase/cbsasl/mechanism.cc +5 -8
  13. data/ext/couchbase/cbsasl/mechanism.h +1 -4
  14. data/ext/couchbase/cbsasl/plain/plain.cc +1 -1
  15. data/ext/couchbase/cbsasl/scram-sha/scram-sha.cc +30 -36
  16. data/ext/couchbase/cluster.hxx +40 -22
  17. data/ext/couchbase/cluster_options.hxx +7 -1
  18. data/ext/couchbase/configuration.hxx +37 -16
  19. data/ext/couchbase/couchbase.cxx +1145 -291
  20. data/ext/couchbase/error_map.hxx +1 -1
  21. data/ext/couchbase/errors.hxx +25 -17
  22. data/ext/couchbase/io/dns_client.hxx +3 -3
  23. data/ext/couchbase/io/dns_codec.hxx +4 -5
  24. data/ext/couchbase/io/dns_config.hxx +5 -6
  25. data/ext/couchbase/io/dns_message.hxx +3 -3
  26. data/ext/couchbase/io/http_command.hxx +70 -35
  27. data/ext/couchbase/io/http_session.hxx +4 -3
  28. data/ext/couchbase/io/http_session_manager.hxx +28 -19
  29. data/ext/couchbase/io/mcbp_command.hxx +51 -19
  30. data/ext/couchbase/io/mcbp_context.hxx +1 -1
  31. data/ext/couchbase/io/mcbp_parser.hxx +4 -4
  32. data/ext/couchbase/io/mcbp_session.hxx +91 -101
  33. data/ext/couchbase/io/query_cache.hxx +2 -2
  34. data/ext/couchbase/io/retry_orchestrator.hxx +2 -4
  35. data/ext/couchbase/io/retry_reason.hxx +2 -2
  36. data/ext/couchbase/io/retry_strategy.hxx +1 -6
  37. data/ext/couchbase/io/streams.hxx +7 -7
  38. data/ext/couchbase/metrics/logging_meter.hxx +228 -0
  39. data/ext/couchbase/metrics/logging_meter_options.hxx +28 -0
  40. data/ext/couchbase/metrics/meter.hxx +49 -0
  41. data/ext/couchbase/metrics/noop_meter.hxx +43 -0
  42. data/ext/couchbase/operations/analytics_dataset_create.hxx +16 -12
  43. data/ext/couchbase/operations/analytics_dataset_drop.hxx +11 -11
  44. data/ext/couchbase/operations/analytics_dataset_get_all.hxx +6 -6
  45. data/ext/couchbase/operations/analytics_dataverse_create.hxx +10 -11
  46. data/ext/couchbase/operations/analytics_dataverse_drop.hxx +10 -11
  47. data/ext/couchbase/operations/analytics_get_pending_mutations.hxx +9 -11
  48. data/ext/couchbase/operations/analytics_index_create.hxx +14 -13
  49. data/ext/couchbase/operations/analytics_index_drop.hxx +18 -12
  50. data/ext/couchbase/operations/analytics_index_get_all.hxx +8 -6
  51. data/ext/couchbase/operations/analytics_link.hxx +39 -0
  52. data/ext/couchbase/operations/analytics_link_azure_blob_external.hxx +145 -0
  53. data/ext/couchbase/operations/analytics_link_connect.hxx +14 -12
  54. data/ext/couchbase/operations/analytics_link_couchbase_remote.hxx +220 -0
  55. data/ext/couchbase/operations/analytics_link_create.hxx +128 -0
  56. data/ext/couchbase/operations/analytics_link_disconnect.hxx +11 -12
  57. data/ext/couchbase/operations/analytics_link_drop.hxx +130 -0
  58. data/ext/couchbase/operations/analytics_link_get_all.hxx +160 -0
  59. data/ext/couchbase/operations/analytics_link_replace.hxx +128 -0
  60. data/ext/couchbase/operations/analytics_link_s3_external.hxx +122 -0
  61. data/ext/couchbase/operations/bucket_create.hxx +8 -8
  62. data/ext/couchbase/operations/bucket_drop.hxx +5 -5
  63. data/ext/couchbase/operations/bucket_flush.hxx +5 -5
  64. data/ext/couchbase/operations/bucket_get.hxx +7 -7
  65. data/ext/couchbase/operations/bucket_get_all.hxx +7 -5
  66. data/ext/couchbase/operations/bucket_settings.hxx +40 -49
  67. data/ext/couchbase/operations/bucket_update.hxx +8 -8
  68. data/ext/couchbase/operations/cluster_developer_preview_enable.hxx +7 -7
  69. data/ext/couchbase/operations/collection_create.hxx +11 -11
  70. data/ext/couchbase/operations/collection_drop.hxx +12 -10
  71. data/ext/couchbase/operations/collections_manifest_get.hxx +3 -3
  72. data/ext/couchbase/operations/design_document.hxx +2 -2
  73. data/ext/couchbase/operations/document_analytics.hxx +29 -36
  74. data/ext/couchbase/operations/document_append.hxx +3 -3
  75. data/ext/couchbase/operations/document_decrement.hxx +3 -3
  76. data/ext/couchbase/operations/document_exists.hxx +2 -2
  77. data/ext/couchbase/operations/document_get.hxx +3 -3
  78. data/ext/couchbase/operations/document_get_and_lock.hxx +5 -3
  79. data/ext/couchbase/operations/document_get_and_touch.hxx +5 -3
  80. data/ext/couchbase/operations/document_get_projected.hxx +10 -11
  81. data/ext/couchbase/operations/document_increment.hxx +3 -3
  82. data/ext/couchbase/operations/document_insert.hxx +3 -3
  83. data/ext/couchbase/operations/document_lookup_in.hxx +12 -18
  84. data/ext/couchbase/operations/document_mutate_in.hxx +13 -18
  85. data/ext/couchbase/operations/document_prepend.hxx +3 -3
  86. data/ext/couchbase/operations/document_query.hxx +39 -41
  87. data/ext/couchbase/operations/document_remove.hxx +3 -3
  88. data/ext/couchbase/operations/document_replace.hxx +3 -3
  89. data/ext/couchbase/operations/document_search.hxx +56 -61
  90. data/ext/couchbase/operations/document_touch.hxx +3 -3
  91. data/ext/couchbase/operations/document_unlock.hxx +3 -3
  92. data/ext/couchbase/operations/document_upsert.hxx +3 -3
  93. data/ext/couchbase/operations/document_view.hxx +23 -23
  94. data/ext/couchbase/operations/group_drop.hxx +5 -5
  95. data/ext/couchbase/operations/group_get.hxx +7 -7
  96. data/ext/couchbase/operations/group_get_all.hxx +6 -6
  97. data/ext/couchbase/operations/group_upsert.hxx +11 -11
  98. data/ext/couchbase/operations/http_noop.hxx +6 -6
  99. data/ext/couchbase/operations/mcbp_noop.hxx +3 -3
  100. data/ext/couchbase/operations/query_index_build_deferred.hxx +6 -6
  101. data/ext/couchbase/operations/query_index_create.hxx +10 -8
  102. data/ext/couchbase/operations/query_index_drop.hxx +8 -8
  103. data/ext/couchbase/operations/query_index_get_all.hxx +43 -39
  104. data/ext/couchbase/operations/rbac.hxx +40 -63
  105. data/ext/couchbase/operations/role_get_all.hxx +6 -6
  106. data/ext/couchbase/operations/scope_create.hxx +10 -10
  107. data/ext/couchbase/operations/scope_drop.hxx +9 -9
  108. data/ext/couchbase/operations/scope_get_all.hxx +8 -8
  109. data/ext/couchbase/operations/search_get_stats.hxx +5 -3
  110. data/ext/couchbase/operations/search_index.hxx +6 -15
  111. data/ext/couchbase/operations/search_index_analyze_document.hxx +11 -11
  112. data/ext/couchbase/operations/search_index_control_ingest.hxx +9 -9
  113. data/ext/couchbase/operations/search_index_control_plan_freeze.hxx +9 -9
  114. data/ext/couchbase/operations/search_index_control_query.hxx +9 -9
  115. data/ext/couchbase/operations/search_index_drop.hxx +11 -9
  116. data/ext/couchbase/operations/search_index_get.hxx +11 -9
  117. data/ext/couchbase/operations/search_index_get_all.hxx +11 -11
  118. data/ext/couchbase/operations/search_index_get_documents_count.hxx +10 -10
  119. data/ext/couchbase/operations/search_index_get_stats.hxx +10 -8
  120. data/ext/couchbase/operations/search_index_upsert.hxx +12 -10
  121. data/ext/couchbase/operations/user_drop.hxx +5 -5
  122. data/ext/couchbase/operations/user_get.hxx +7 -7
  123. data/ext/couchbase/operations/user_get_all.hxx +6 -6
  124. data/ext/couchbase/operations/user_upsert.hxx +9 -9
  125. data/ext/couchbase/operations/view_index_drop.hxx +10 -10
  126. data/ext/couchbase/operations/view_index_get.hxx +13 -15
  127. data/ext/couchbase/operations/view_index_get_all.hxx +17 -20
  128. data/ext/couchbase/operations/view_index_upsert.hxx +9 -7
  129. data/ext/couchbase/operations.hxx +4 -0
  130. data/ext/couchbase/origin.hxx +14 -10
  131. data/ext/couchbase/platform/backtrace.c +1 -1
  132. data/ext/couchbase/platform/base64.cc +5 -5
  133. data/ext/couchbase/platform/base64.h +2 -5
  134. data/ext/couchbase/protocol/client_opcode.hxx +7 -4
  135. data/ext/couchbase/protocol/client_request.hxx +2 -2
  136. data/ext/couchbase/protocol/client_response.hxx +41 -16
  137. data/ext/couchbase/protocol/cmd_append.hxx +17 -16
  138. data/ext/couchbase/protocol/cmd_cluster_map_change_notification.hxx +4 -4
  139. data/ext/couchbase/protocol/cmd_decrement.hxx +10 -11
  140. data/ext/couchbase/protocol/cmd_exists.hxx +12 -15
  141. data/ext/couchbase/protocol/cmd_get.hxx +11 -14
  142. data/ext/couchbase/protocol/cmd_get_and_lock.hxx +10 -12
  143. data/ext/couchbase/protocol/cmd_get_and_touch.hxx +10 -12
  144. data/ext/couchbase/protocol/cmd_get_cluster_config.hxx +13 -18
  145. data/ext/couchbase/protocol/cmd_get_collection_id.hxx +12 -15
  146. data/ext/couchbase/protocol/cmd_get_collections_manifest.hxx +12 -16
  147. data/ext/couchbase/protocol/cmd_get_error_map.hxx +14 -17
  148. data/ext/couchbase/protocol/cmd_hello.hxx +8 -10
  149. data/ext/couchbase/protocol/cmd_increment.hxx +9 -10
  150. data/ext/couchbase/protocol/cmd_insert.hxx +9 -9
  151. data/ext/couchbase/protocol/cmd_lookup_in.hxx +12 -13
  152. data/ext/couchbase/protocol/cmd_mutate_in.hxx +11 -11
  153. data/ext/couchbase/protocol/cmd_noop.hxx +16 -20
  154. data/ext/couchbase/protocol/cmd_prepend.hxx +9 -10
  155. data/ext/couchbase/protocol/cmd_remove.hxx +10 -13
  156. data/ext/couchbase/protocol/cmd_replace.hxx +7 -7
  157. data/ext/couchbase/protocol/cmd_sasl_auth.hxx +8 -10
  158. data/ext/couchbase/protocol/cmd_sasl_list_mechs.hxx +10 -15
  159. data/ext/couchbase/protocol/cmd_sasl_step.hxx +10 -12
  160. data/ext/couchbase/protocol/cmd_select_bucket.hxx +14 -18
  161. data/ext/couchbase/protocol/cmd_touch.hxx +8 -11
  162. data/ext/couchbase/protocol/cmd_unlock.hxx +10 -14
  163. data/ext/couchbase/protocol/cmd_upsert.hxx +8 -8
  164. data/ext/couchbase/protocol/datatype.hxx +3 -3
  165. data/ext/couchbase/protocol/durability_level.hxx +2 -2
  166. data/ext/couchbase/protocol/frame_info_id.hxx +4 -4
  167. data/ext/couchbase/protocol/hello_feature.hxx +2 -2
  168. data/ext/couchbase/protocol/magic.hxx +2 -2
  169. data/ext/couchbase/protocol/server_opcode.hxx +2 -2
  170. data/ext/couchbase/protocol/server_request.hxx +1 -1
  171. data/ext/couchbase/protocol/status.hxx +4 -7
  172. data/ext/couchbase/protocol/unsigned_leb128.h +5 -20
  173. data/ext/couchbase/service_type.hxx +4 -4
  174. data/ext/couchbase/tracing/constants.hxx +261 -0
  175. data/ext/couchbase/tracing/noop_tracer.hxx +50 -0
  176. data/ext/couchbase/tracing/request_tracer.hxx +77 -0
  177. data/ext/couchbase/tracing/threshold_logging_options.hxx +64 -0
  178. data/ext/couchbase/tracing/threshold_logging_tracer.hxx +366 -0
  179. data/ext/couchbase/utils/byteswap.hxx +1 -1
  180. data/ext/couchbase/utils/connection_string.hxx +21 -1
  181. data/ext/couchbase/utils/name_codec.hxx +41 -0
  182. data/ext/couchbase/utils/url_codec.hxx +236 -0
  183. data/ext/couchbase/version.hxx +1 -1
  184. data/ext/test/CMakeLists.txt +1 -0
  185. data/ext/test/test_native_trivial_query.cxx +60 -0
  186. data/ext/third_party/hdr_histogram_c/CMakeLists.txt +84 -0
  187. data/ext/third_party/hdr_histogram_c/COPYING.txt +121 -0
  188. data/ext/third_party/hdr_histogram_c/LICENSE.txt +41 -0
  189. data/ext/third_party/hdr_histogram_c/config.cmake.in +6 -0
  190. data/ext/third_party/hdr_histogram_c/src/CMakeLists.txt +83 -0
  191. data/ext/third_party/hdr_histogram_c/src/hdr_atomic.h +146 -0
  192. data/ext/third_party/hdr_histogram_c/src/hdr_encoding.c +322 -0
  193. data/ext/third_party/hdr_histogram_c/src/hdr_encoding.h +79 -0
  194. data/ext/third_party/hdr_histogram_c/src/hdr_endian.h +116 -0
  195. data/ext/third_party/hdr_histogram_c/src/hdr_histogram.c +1196 -0
  196. data/ext/third_party/hdr_histogram_c/src/hdr_histogram.h +516 -0
  197. data/ext/third_party/hdr_histogram_c/src/hdr_histogram_log.c +1290 -0
  198. data/ext/third_party/hdr_histogram_c/src/hdr_histogram_log.h +236 -0
  199. data/ext/third_party/hdr_histogram_c/src/hdr_histogram_log_no_op.c +171 -0
  200. data/ext/third_party/hdr_histogram_c/src/hdr_interval_recorder.c +227 -0
  201. data/ext/third_party/hdr_histogram_c/src/hdr_interval_recorder.h +109 -0
  202. data/ext/third_party/hdr_histogram_c/src/hdr_malloc.h +19 -0
  203. data/ext/third_party/hdr_histogram_c/src/hdr_tests.h +22 -0
  204. data/ext/third_party/hdr_histogram_c/src/hdr_thread.c +108 -0
  205. data/ext/third_party/hdr_histogram_c/src/hdr_thread.h +55 -0
  206. data/ext/third_party/hdr_histogram_c/src/hdr_time.c +98 -0
  207. data/ext/third_party/hdr_histogram_c/src/hdr_time.h +49 -0
  208. data/ext/third_party/hdr_histogram_c/src/hdr_writer_reader_phaser.c +143 -0
  209. data/ext/third_party/hdr_histogram_c/src/hdr_writer_reader_phaser.h +51 -0
  210. data/lib/couchbase/cluster.rb +1 -0
  211. data/lib/couchbase/errors.rb +3 -0
  212. data/lib/couchbase/management/analytics_index_manager.rb +920 -226
  213. data/lib/couchbase/management/bucket_manager.rb +207 -69
  214. data/lib/couchbase/management/collection_manager.rb +173 -61
  215. data/lib/couchbase/management/query_index_manager.rb +357 -169
  216. data/lib/couchbase/options.rb +75 -3
  217. data/lib/couchbase/scope.rb +102 -0
  218. data/lib/couchbase/utils/time.rb +4 -0
  219. data/lib/couchbase/version.rb +6 -6
  220. metadata +50 -7
@@ -120,7 +120,7 @@ struct error_map {
120
120
  std::string description;
121
121
  std::set<attribute> attributes;
122
122
 
123
- bool has_retry_attribute()
123
+ bool has_retry_attribute() const
124
124
  {
125
125
  return attributes.find(attribute::retry_now) != attributes.end() || attributes.find(attribute::retry_later) != attributes.end();
126
126
  }
@@ -244,6 +244,9 @@ enum class analytics_errc {
244
244
 
245
245
  /// Raised When 24006
246
246
  link_not_found,
247
+
248
+ /// Raised When 24055
249
+ link_exists,
247
250
  };
248
251
 
249
252
  /// Errors related to Search service (CBFT)
@@ -313,12 +316,12 @@ namespace detail
313
316
  struct common_error_category : std::error_category {
314
317
  [[nodiscard]] const char* name() const noexcept override
315
318
  {
316
- return "common";
319
+ return "couchbase.common";
317
320
  }
318
321
 
319
322
  [[nodiscard]] std::string message(int ev) const noexcept override
320
323
  {
321
- switch (static_cast<common_errc>(ev)) {
324
+ switch (common_errc(ev)) {
322
325
  case common_errc::unambiguous_timeout:
323
326
  return "unambiguous_timeout";
324
327
  case common_errc::ambiguous_timeout:
@@ -372,12 +375,12 @@ get_common_category()
372
375
  struct key_value_error_category : std::error_category {
373
376
  [[nodiscard]] const char* name() const noexcept override
374
377
  {
375
- return "key_value";
378
+ return "couchbase.key_value";
376
379
  }
377
380
 
378
381
  [[nodiscard]] std::string message(int ev) const noexcept override
379
382
  {
380
- switch (static_cast<key_value_errc>(ev)) {
383
+ switch (key_value_errc(ev)) {
381
384
  case key_value_errc::document_not_found:
382
385
  return "document_not_found";
383
386
  case key_value_errc::document_irretrievable:
@@ -442,12 +445,12 @@ get_key_value_category()
442
445
  struct query_error_category : std::error_category {
443
446
  [[nodiscard]] const char* name() const noexcept override
444
447
  {
445
- return "query";
448
+ return "couchbase.query";
446
449
  }
447
450
 
448
451
  [[nodiscard]] std::string message(int ev) const noexcept override
449
452
  {
450
- switch (static_cast<query_errc>(ev)) {
453
+ switch (query_errc(ev)) {
451
454
  case query_errc::planning_failure:
452
455
  return "planning_failure";
453
456
  case query_errc::index_failure:
@@ -469,12 +472,12 @@ get_query_category()
469
472
  struct search_error_category : std::error_category {
470
473
  [[nodiscard]] const char* name() const noexcept override
471
474
  {
472
- return "search";
475
+ return "couchbase.search";
473
476
  }
474
477
 
475
478
  [[nodiscard]] std::string message(int ev) const noexcept override
476
479
  {
477
- switch (static_cast<search_errc>(ev)) {
480
+ switch (search_errc(ev)) {
478
481
  case search_errc::index_not_ready:
479
482
  return "index_not_ready";
480
483
  case search_errc::consistency_mismatch:
@@ -494,12 +497,12 @@ get_search_category()
494
497
  struct view_error_category : std::error_category {
495
498
  [[nodiscard]] const char* name() const noexcept override
496
499
  {
497
- return "view";
500
+ return "couchbase.view";
498
501
  }
499
502
 
500
503
  [[nodiscard]] std::string message(int ev) const noexcept override
501
504
  {
502
- switch (static_cast<view_errc>(ev)) {
505
+ switch (view_errc(ev)) {
503
506
  case view_errc::view_not_found:
504
507
  return "view_not_found";
505
508
  case view_errc::design_document_not_found:
@@ -519,12 +522,12 @@ get_view_category()
519
522
  struct analytics_error_category : std::error_category {
520
523
  [[nodiscard]] const char* name() const noexcept override
521
524
  {
522
- return "analytics";
525
+ return "couchbase.analytics";
523
526
  }
524
527
 
525
528
  [[nodiscard]] std::string message(int ev) const noexcept override
526
529
  {
527
- switch (static_cast<analytics_errc>(ev)) {
530
+ switch (analytics_errc(ev)) {
528
531
  case analytics_errc::compilation_failure:
529
532
  return "compilation_failure";
530
533
  case analytics_errc::job_queue_full:
@@ -539,6 +542,8 @@ struct analytics_error_category : std::error_category {
539
542
  return "dataverse_exists";
540
543
  case analytics_errc::link_not_found:
541
544
  return "link_not_found";
545
+ case analytics_errc::link_exists:
546
+ return "link_exists";
542
547
  }
543
548
  return "FIXME: unknown error code in analytics category (recompile with newer library)";
544
549
  }
@@ -554,12 +559,12 @@ get_analytics_category()
554
559
  struct management_error_category : std::error_category {
555
560
  [[nodiscard]] const char* name() const noexcept override
556
561
  {
557
- return "management";
562
+ return "couchbase.management";
558
563
  }
559
564
 
560
565
  [[nodiscard]] std::string message(int ev) const noexcept override
561
566
  {
562
- switch (static_cast<management_errc>(ev)) {
567
+ switch (management_errc(ev)) {
563
568
  case management_errc::collection_exists:
564
569
  return "collection_exists";
565
570
  case management_errc::scope_exists:
@@ -589,12 +594,12 @@ get_management_category()
589
594
  struct network_error_category : std::error_category {
590
595
  [[nodiscard]] const char* name() const noexcept override
591
596
  {
592
- return "network";
597
+ return "couchbase.network";
593
598
  }
594
599
 
595
600
  [[nodiscard]] std::string message(int ev) const noexcept override
596
601
  {
597
- switch (static_cast<network_errc>(ev)) {
602
+ switch (network_errc(ev)) {
598
603
  case network_errc::resolve_failure:
599
604
  return "resolve_failure";
600
605
  case network_errc::no_endpoints_left:
@@ -654,7 +659,10 @@ struct is_error_code_enum<couchbase::error::management_errc> : true_type {
654
659
  template<>
655
660
  struct is_error_code_enum<couchbase::error::network_errc> : true_type {
656
661
  };
662
+ } // namespace std
657
663
 
664
+ namespace couchbase::error
665
+ {
658
666
  inline std::error_code
659
667
  make_error_code(couchbase::error::common_errc e)
660
668
  {
@@ -703,4 +711,4 @@ make_error_code(couchbase::error::network_errc e)
703
711
  return { static_cast<int>(e), couchbase::error::detail::get_network_category() };
704
712
  }
705
713
 
706
- } // namespace std
714
+ } // namespace couchbase::error
@@ -81,7 +81,7 @@ class dns_client
81
81
  std::size_t /* bytes_transferred */) mutable {
82
82
  if (ec1 == asio::error::operation_aborted) {
83
83
  self->deadline_.cancel();
84
- return handler({ std::make_error_code(error::common_errc::unambiguous_timeout) });
84
+ return handler({ error::common_errc::unambiguous_timeout });
85
85
  }
86
86
  if (ec1) {
87
87
  self->deadline_.cancel();
@@ -148,7 +148,7 @@ class dns_client
148
148
  if (ec2) {
149
149
  self->deadline_.cancel();
150
150
  if (ec2 == asio::error::operation_aborted) {
151
- ec2 = std::make_error_code(error::common_errc::unambiguous_timeout);
151
+ ec2 = error::common_errc::unambiguous_timeout;
152
152
  }
153
153
  return handler({ ec2 });
154
154
  }
@@ -207,7 +207,7 @@ class dns_client
207
207
  template<class Handler>
208
208
  void query_srv(const std::string& name, const std::string& service, Handler&& handler)
209
209
  {
210
- dns_config& config = dns_config::get();
210
+ const dns_config& config = dns_config::get();
211
211
  auto cmd = std::make_shared<dns_srv_command>(ctx_, name, service, config.address(), config.port());
212
212
  cmd->execute(config.timeout(), std::forward<Handler>(handler));
213
213
  }
@@ -65,7 +65,7 @@ class dns_codec
65
65
  std::memcpy(&val, payload.data() + offset, sizeof(std::uint16_t));
66
66
  offset += sizeof(std::uint16_t);
67
67
  val = ntohs(val);
68
- qr.type = static_cast<resource_type>(val);
68
+ qr.type = resource_type(val);
69
69
 
70
70
  std::memcpy(&val, payload.data() + offset, sizeof(std::uint16_t));
71
71
  offset += sizeof(std::uint16_t);
@@ -84,12 +84,12 @@ class dns_codec
84
84
  std::memcpy(&val, payload.data() + offset, sizeof(std::uint16_t));
85
85
  offset += sizeof(std::uint16_t);
86
86
  val = ntohs(val);
87
- ar.type = static_cast<resource_type>(val);
87
+ ar.type = resource_type(val);
88
88
 
89
89
  std::memcpy(&val, payload.data() + offset, sizeof(std::uint16_t));
90
90
  offset += sizeof(std::uint16_t);
91
91
  val = ntohs(val);
92
- ar.klass = static_cast<resource_class>(val);
92
+ ar.klass = resource_class(val);
93
93
 
94
94
  std::memcpy(&ar.ttl, payload.data() + offset, sizeof(std::uint32_t));
95
95
  offset += static_cast<std::uint16_t>(4U);
@@ -196,8 +196,7 @@ class dns_codec
196
196
  save_offset = offset + sizeof(std::uint16_t);
197
197
  offset = ptr;
198
198
  } else {
199
- std::string label(payload.data() + offset + 1, payload.data() + offset + 1 + len);
200
- name.labels.emplace_back(label);
199
+ name.labels.emplace_back(payload.data() + offset + 1, payload.data() + offset + 1 + len);
201
200
  offset += static_cast<std::uint16_t>(1U + len);
202
201
  }
203
202
  }
@@ -19,8 +19,8 @@
19
19
 
20
20
  #include <unistd.h>
21
21
 
22
- #include <string>
23
22
  #include <fstream>
23
+ #include <string>
24
24
 
25
25
  #include <asio/ip/address.hpp>
26
26
 
@@ -31,9 +31,9 @@ namespace couchbase::io::dns
31
31
  class dns_config
32
32
  {
33
33
  public:
34
- static inline constexpr auto default_resolv_conf_path = "/etc/resolv.conf";
35
- static inline constexpr auto default_host = "8.8.8.8";
36
- static inline constexpr std::uint16_t default_port = 53;
34
+ static constexpr auto default_resolv_conf_path = "/etc/resolv.conf";
35
+ static constexpr auto default_host = "8.8.8.8";
36
+ static constexpr std::uint16_t default_port = 53;
37
37
 
38
38
  [[nodiscard]] const asio::ip::address& address() const
39
39
  {
@@ -95,8 +95,7 @@ class dns_config
95
95
  if (space == std::string::npos || space == offset || line.size() < space + 2) {
96
96
  continue;
97
97
  }
98
- std::string keyword = line.substr(offset, space);
99
- if (keyword != "nameserver") {
98
+ if (std::string keyword = line.substr(offset, space); keyword != "nameserver") {
100
99
  continue;
101
100
  }
102
101
  offset = space + 1;
@@ -321,15 +321,15 @@ struct dns_header {
321
321
 
322
322
  void decode(std::uint16_t blob)
323
323
  {
324
- qr = static_cast<message_type>((static_cast<std::uint32_t>(blob) >> 15U) & 1U);
325
- opcode = static_cast<dns::opcode>((static_cast<std::uint32_t>(blob) >> 11U) & 15U);
324
+ qr = message_type((static_cast<std::uint32_t>(blob) >> 15U) & 1U);
325
+ opcode = dns::opcode((static_cast<std::uint32_t>(blob) >> 11U) & 15U);
326
326
 
327
327
  aa = ((static_cast<std::uint32_t>(blob) >> 10U) & 1U) != 0U ? authoritative_answer::yes : authoritative_answer::no;
328
328
  tc = ((static_cast<std::uint32_t>(blob) >> 9U) & 1U) != 0U ? truncation::yes : truncation::no;
329
329
  rd = ((static_cast<std::uint32_t>(blob) >> 8U) & 1U) != 0U ? recursion_desired::yes : recursion_desired::no;
330
330
  ra = ((static_cast<std::uint32_t>(blob) >> 7U) & 1U) != 0U ? recursion_available::yes : recursion_available::no;
331
331
 
332
- rcode = static_cast<response_code>(blob & 15U);
332
+ rcode = response_code(blob & 15U);
333
333
  }
334
334
  };
335
335
 
@@ -19,6 +19,9 @@
19
19
 
20
20
  #include <io/http_session.hxx>
21
21
 
22
+ #include <tracing/request_tracer.hxx>
23
+ #include <metrics/meter.hxx>
24
+
22
25
  namespace couchbase::operations
23
26
  {
24
27
 
@@ -31,22 +34,37 @@ struct http_command : public std::enable_shared_from_this<http_command<Request>>
31
34
  asio::steady_timer retry_backoff;
32
35
  Request request;
33
36
  encoded_request_type encoded;
37
+ tracing::request_tracer* tracer_;
38
+ tracing::request_span* span_{ nullptr };
39
+ metrics::meter* meter_;
34
40
 
35
- http_command(asio::io_context& ctx, Request req)
41
+ http_command(asio::io_context& ctx, Request req, tracing::request_tracer* tracer, metrics::meter* meter)
36
42
  : deadline(ctx)
37
43
  , retry_backoff(ctx)
38
44
  , request(req)
45
+ , tracer_(tracer)
46
+ , meter_(meter)
47
+ {
48
+ }
49
+
50
+ void finish_dispatch(const std::string& remote_address, const std::string& local_address)
39
51
  {
52
+ if (span_ == nullptr) {
53
+ return;
54
+ }
55
+ span_->add_tag(tracing::attributes::remote_socket, remote_address);
56
+ span_->add_tag(tracing::attributes::local_socket, local_address);
57
+ span_->end();
58
+ span_ = nullptr;
40
59
  }
41
60
 
42
61
  template<typename Handler>
43
62
  void send_to(std::shared_ptr<io::http_session> session, Handler&& handler)
44
63
  {
45
64
  encoded.type = request.type;
46
- auto encoding_ec = request.encode_to(encoded, session->http_context());
47
- if (encoding_ec) {
65
+ if (auto ec = request.encode_to(encoded, session->http_context()); ec) {
48
66
  error_context_type ctx{};
49
- ctx.ec = encoding_ec;
67
+ ctx.ec = ec;
50
68
  ctx.client_context_id = request.client_context_id;
51
69
  return handler(make_response(std::move(ctx), request, {}));
52
70
  }
@@ -67,37 +85,54 @@ struct http_command : public std::enable_shared_from_this<http_command<Request>>
67
85
  request.client_context_id,
68
86
  request.timeout.count(),
69
87
  spdlog::to_hex(encoded.body));
70
- session->write_and_subscribe(encoded,
71
- [self = this->shared_from_this(), log_prefix, session, handler = std::forward<Handler>(handler)](
72
- std::error_code ec, io::http_response&& msg) mutable {
73
- self->deadline.cancel();
74
- encoded_response_type resp(msg);
75
- spdlog::trace(R"({} HTTP response: {}, client_context_id="{}", status={})",
76
- log_prefix,
77
- self->request.type,
78
- self->request.client_context_id,
79
- resp.status_code);
80
- SPDLOG_TRACE(R"({} HTTP response: {}, client_context_id="{}", status={}{:a})",
81
- log_prefix,
82
- self->request.type,
83
- self->request.client_context_id,
84
- resp.status_code,
85
- spdlog::to_hex(resp.body));
86
- try {
87
- error_context_type ctx{};
88
- ctx.ec = ec;
89
- ctx.client_context_id = self->request.client_context_id;
90
- ctx.method = self->encoded.method;
91
- ctx.path = self->encoded.path;
92
- ctx.last_dispatched_from = session->local_address();
93
- ctx.last_dispatched_to = session->remote_address();
94
- ctx.http_status = msg.status_code;
95
- ctx.http_body = msg.body;
96
- handler(make_response(std::move(ctx), self->request, std::move(msg)));
97
- } catch (priv::retry_http_request&) {
98
- self->send_to(session, std::forward<Handler>(handler));
99
- }
100
- });
88
+ span_ = tracer_->start_span(tracing::span_name_for_http_service(request.type), nullptr);
89
+ span_->add_tag(tracing::attributes::service, tracing::service_name_for_http_service(request.type));
90
+ span_->add_tag(tracing::attributes::operation_id, request.client_context_id);
91
+ span_->add_tag(tracing::attributes::local_id, session->id());
92
+ session->write_and_subscribe(
93
+ encoded,
94
+ [self = this->shared_from_this(),
95
+ log_prefix,
96
+ session,
97
+ handler = std::forward<Handler>(handler),
98
+ start = std::chrono::steady_clock::now()](std::error_code ec, io::http_response&& msg) mutable {
99
+ static std::string meter_name = "db.couchbase.operations";
100
+ static std::map<std::string, std::string> tags = {
101
+ { "db.couchbase.service", fmt::format("{}", self->request.type) },
102
+ { "db.operation", self->encoded.path },
103
+ };
104
+ self->meter_->get_value_recorder(meter_name, tags)
105
+ ->record_value(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - start).count());
106
+
107
+ self->deadline.cancel();
108
+ self->finish_dispatch(session->remote_address(), session->local_address());
109
+ encoded_response_type resp(msg);
110
+ spdlog::trace(R"({} HTTP response: {}, client_context_id="{}", status={})",
111
+ log_prefix,
112
+ self->request.type,
113
+ self->request.client_context_id,
114
+ resp.status_code);
115
+ SPDLOG_TRACE(R"({} HTTP response: {}, client_context_id="{}", status={}{:a})",
116
+ log_prefix,
117
+ self->request.type,
118
+ self->request.client_context_id,
119
+ resp.status_code,
120
+ spdlog::to_hex(resp.body));
121
+ try {
122
+ error_context_type ctx{};
123
+ ctx.ec = ec;
124
+ ctx.client_context_id = self->request.client_context_id;
125
+ ctx.method = self->encoded.method;
126
+ ctx.path = self->encoded.path;
127
+ ctx.last_dispatched_from = session->local_address();
128
+ ctx.last_dispatched_to = session->remote_address();
129
+ ctx.http_status = msg.status_code;
130
+ ctx.http_body = msg.body;
131
+ handler(make_response(std::move(ctx), self->request, std::move(msg)));
132
+ } catch (const priv::retry_http_request&) {
133
+ self->send_to(session, std::forward<Handler>(handler));
134
+ }
135
+ });
101
136
  deadline.expires_after(request.timeout);
102
137
  deadline.async_wait([session](std::error_code ec) {
103
138
  if (ec == asio::error::operation_aborted) {
@@ -172,7 +172,7 @@ class http_session : public std::enable_shared_from_this<http_session>
172
172
  {
173
173
  std::scoped_lock lock(command_handlers_mutex_);
174
174
  for (auto& handler : command_handlers_) {
175
- handler(std::make_error_code(error::common_errc::ambiguous_timeout), {});
175
+ handler(error::common_errc::ambiguous_timeout, {});
176
176
  }
177
177
  command_handlers_.clear();
178
178
  }
@@ -202,7 +202,7 @@ class http_session : public std::enable_shared_from_this<http_session>
202
202
  output_buffer_.push_back(buf);
203
203
  }
204
204
 
205
- void write(const std::string& buf)
205
+ void write(const std::string_view& buf)
206
206
  {
207
207
  if (stopped_) {
208
208
  return;
@@ -221,7 +221,8 @@ class http_session : public std::enable_shared_from_this<http_session>
221
221
  do_write();
222
222
  }
223
223
 
224
- void write_and_subscribe(io::http_request& request, std::function<void(std::error_code, io::http_response&&)>&& handler)
224
+ template<typename Handler>
225
+ void write_and_subscribe(io::http_request& request, Handler&& handler)
225
226
  {
226
227
  if (stopped_) {
227
228
  return;
@@ -23,6 +23,9 @@
23
23
  #include <operations/http_noop.hxx>
24
24
  #include <io/http_command.hxx>
25
25
 
26
+ #include <tracing/noop_tracer.hxx>
27
+ #include <metrics/meter.hxx>
28
+
26
29
  #include <random>
27
30
 
28
31
  namespace couchbase::io
@@ -38,6 +41,16 @@ class http_session_manager : public std::enable_shared_from_this<http_session_ma
38
41
  {
39
42
  }
40
43
 
44
+ void set_tracer(tracing::request_tracer* tracer)
45
+ {
46
+ tracer_ = tracer;
47
+ }
48
+
49
+ void set_meter(metrics::meter* meter)
50
+ {
51
+ meter_ = meter;
52
+ }
53
+
41
54
  void set_configuration(const configuration& config, const cluster_options& options)
42
55
  {
43
56
  options_ = options;
@@ -74,7 +87,7 @@ class http_session_manager : public std::enable_shared_from_this<http_session_ma
74
87
  template<typename Collector>
75
88
  void ping(std::set<service_type> services, std::shared_ptr<Collector> collector, const couchbase::cluster_credentials& credentials)
76
89
  {
77
- std::array<service_type, 4> known_types{ service_type::query, service_type::analytics, service_type::search, service_type::views };
90
+ std::array<service_type, 4> known_types{ service_type::query, service_type::analytics, service_type::search, service_type::view };
78
91
  for (auto& node : config_.nodes) {
79
92
  for (auto type : known_types) {
80
93
  if (services.find(type) == services.end()) {
@@ -116,7 +129,7 @@ class http_session_manager : public std::enable_shared_from_this<http_session_ma
116
129
  busy_sessions_[type].push_back(session);
117
130
  operations::http_noop_request request{};
118
131
  request.type = type;
119
- auto cmd = std::make_shared<operations::http_command<operations::http_noop_request>>(ctx_, request);
132
+ auto cmd = std::make_shared<operations::http_command<operations::http_noop_request>>(ctx_, request, tracer_, meter_);
120
133
  cmd->send_to(
121
134
  session,
122
135
  [start = std::chrono::steady_clock::now(),
@@ -153,9 +166,7 @@ class http_session_manager : public std::enable_shared_from_this<http_session_ma
153
166
  idle_sessions_[type].remove_if([](const auto& s) -> bool { return !s; });
154
167
  busy_sessions_[type].remove_if([](const auto& s) -> bool { return !s; });
155
168
  if (idle_sessions_[type].empty()) {
156
- std::string hostname;
157
- std::uint16_t port = 0;
158
- std::tie(hostname, port) = next_node(type);
169
+ auto [hostname, port] = next_node(type);
159
170
  if (port == 0) {
160
171
  return nullptr;
161
172
  }
@@ -214,21 +225,17 @@ class http_session_manager : public std::enable_shared_from_this<http_session_ma
214
225
 
215
226
  void close()
216
227
  {
217
- {
218
- for (auto& sessions : idle_sessions_) {
219
- for (auto& s : sessions.second) {
220
- if (s) {
221
- s->reset_idle();
222
- s.reset();
223
- }
228
+ for (auto& sessions : idle_sessions_) {
229
+ for (auto& s : sessions.second) {
230
+ if (s) {
231
+ s->reset_idle();
232
+ s.reset();
224
233
  }
225
234
  }
226
235
  }
227
- {
228
- for (auto& sessions : busy_sessions_) {
229
- for (auto& s : sessions.second) {
230
- s.reset();
231
- }
236
+ for (auto& sessions : busy_sessions_) {
237
+ for (auto& s : sessions.second) {
238
+ s.reset();
232
239
  }
233
240
  }
234
241
  }
@@ -239,7 +246,7 @@ class http_session_manager : public std::enable_shared_from_this<http_session_ma
239
246
  auto candidates = config_.nodes.size();
240
247
  while (candidates > 0) {
241
248
  --candidates;
242
- auto& node = config_.nodes[next_index_];
249
+ const auto& node = config_.nodes[next_index_];
243
250
  next_index_ = (next_index_ + 1) % config_.nodes.size();
244
251
  std::uint16_t port = node.port_or(options_.network, type, options_.enable_tls, 0);
245
252
  if (port != 0) {
@@ -252,7 +259,9 @@ class http_session_manager : public std::enable_shared_from_this<http_session_ma
252
259
  std::string client_id_;
253
260
  asio::io_context& ctx_;
254
261
  asio::ssl::context& tls_;
255
- cluster_options options_;
262
+ tracing::request_tracer* tracer_{ nullptr };
263
+ metrics::meter* meter_{ nullptr };
264
+ cluster_options options_{};
256
265
 
257
266
  configuration config_{};
258
267
  std::map<service_type, std::list<std::shared_ptr<http_session>>> busy_sessions_{};