couchbase 4.2.11-rc.1 → 4.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. package/deps/couchbase-cxx-cache/mozilla-ca-bundle.crt +49 -2
  2. package/deps/couchbase-cxx-cache/mozilla-ca-bundle.sha256 +1 -1
  3. package/deps/couchbase-cxx-client/CMakeLists.txt +1 -0
  4. package/deps/couchbase-cxx-client/cmake/ThirdPartyDependencies.cmake +2 -0
  5. package/deps/couchbase-cxx-client/core/bucket.cxx +2 -2
  6. package/deps/couchbase-cxx-client/core/impl/cluster.cxx +51 -5
  7. package/deps/couchbase-cxx-client/core/impl/collection.cxx +224 -209
  8. package/deps/couchbase-cxx-client/core/impl/query_error_context.cxx +2 -2
  9. package/deps/couchbase-cxx-client/core/impl/query_index_manager.cxx +1 -0
  10. package/deps/couchbase-cxx-client/core/io/dns_client.cxx +4 -0
  11. package/deps/couchbase-cxx-client/core/io/dns_config.cxx +15 -4
  12. package/deps/couchbase-cxx-client/core/io/dns_config.hxx +1 -1
  13. package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +95 -53
  14. package/deps/couchbase-cxx-client/core/io/mcbp_session.hxx +1 -0
  15. package/deps/couchbase-cxx-client/core/mcbp/operation_queue.cxx +1 -0
  16. package/deps/couchbase-cxx-client/core/meta/features.hxx +5 -0
  17. package/deps/couchbase-cxx-client/core/operations/document_lookup_in_all_replicas.hxx +116 -105
  18. package/deps/couchbase-cxx-client/core/operations/document_lookup_in_any_replica.hxx +116 -108
  19. package/deps/couchbase-cxx-client/core/operations/document_search.cxx +97 -81
  20. package/deps/couchbase-cxx-client/core/operations/document_search.hxx +5 -0
  21. package/deps/couchbase-cxx-client/core/range_scan_load_balancer.cxx +141 -0
  22. package/deps/couchbase-cxx-client/core/range_scan_load_balancer.hxx +64 -0
  23. package/deps/couchbase-cxx-client/core/range_scan_orchestrator.cxx +224 -336
  24. package/deps/couchbase-cxx-client/core/range_scan_orchestrator.hxx +5 -6
  25. package/deps/couchbase-cxx-client/core/range_scan_orchestrator_options.hxx +8 -5
  26. package/deps/couchbase-cxx-client/core/scan_result.hxx +1 -11
  27. package/deps/couchbase-cxx-client/core/transactions/atr_cleanup_entry.cxx +16 -7
  28. package/deps/couchbase-cxx-client/core/transactions/attempt_context_impl.cxx +578 -483
  29. package/deps/couchbase-cxx-client/core/transactions/attempt_context_testing_hooks.cxx +51 -50
  30. package/deps/couchbase-cxx-client/core/transactions/attempt_context_testing_hooks.hxx +4 -2
  31. package/deps/couchbase-cxx-client/core/transactions/cleanup_testing_hooks.cxx +6 -6
  32. package/deps/couchbase-cxx-client/core/transactions/cleanup_testing_hooks.hxx +3 -2
  33. package/deps/couchbase-cxx-client/core/transactions/internal/transactions_cleanup.hxx +2 -0
  34. package/deps/couchbase-cxx-client/core/transactions/internal/utils.hxx +5 -1
  35. package/deps/couchbase-cxx-client/core/transactions/staged_mutation.cxx +222 -179
  36. package/deps/couchbase-cxx-client/core/transactions/staged_mutation.hxx +23 -12
  37. package/deps/couchbase-cxx-client/core/transactions/transactions.cxx +61 -24
  38. package/deps/couchbase-cxx-client/core/transactions/transactions_cleanup.cxx +36 -16
  39. package/deps/couchbase-cxx-client/core/transactions/utils.cxx +9 -0
  40. package/deps/couchbase-cxx-client/core/transactions.hxx +40 -7
  41. package/deps/couchbase-cxx-client/couchbase/bucket.hxx +2 -2
  42. package/deps/couchbase-cxx-client/couchbase/cluster.hxx +20 -1
  43. package/deps/couchbase-cxx-client/couchbase/collection.hxx +1 -0
  44. package/deps/couchbase-cxx-client/couchbase/collection_query_index_manager.hxx +1 -1
  45. package/deps/couchbase-cxx-client/couchbase/error_context.hxx +1 -0
  46. package/deps/couchbase-cxx-client/couchbase/fork_event.hxx +39 -0
  47. package/deps/couchbase-cxx-client/couchbase/get_links_analytics_options.hxx +2 -2
  48. package/deps/couchbase-cxx-client/couchbase/scope.hxx +1 -1
  49. package/deps/couchbase-cxx-client/couchbase/search_options.hxx +2 -2
  50. package/deps/couchbase-cxx-client/couchbase/search_result.hxx +1 -1
  51. package/deps/couchbase-cxx-client/couchbase/subdocument_error_context.hxx +1 -0
  52. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_options.hxx +1 -1
  53. package/deps/couchbase-cxx-client/couchbase-sdk-cxx-black-duck-manifest.yaml +1 -0
  54. package/dist/binding.d.ts +8 -0
  55. package/dist/bindingutilities.d.ts +6 -1
  56. package/dist/bindingutilities.js +15 -1
  57. package/dist/bucketmanager.d.ts +0 -12
  58. package/dist/cluster.d.ts +0 -2
  59. package/dist/cluster.js +0 -2
  60. package/dist/collection.d.ts +3 -3
  61. package/dist/collection.js +3 -1
  62. package/dist/querytypes.d.ts +0 -2
  63. package/dist/rangeScan.d.ts +0 -8
  64. package/dist/rangeScan.js +0 -8
  65. package/dist/scope.d.ts +0 -5
  66. package/dist/scope.js +0 -5
  67. package/dist/scopesearchindexmanager.d.ts +0 -2
  68. package/dist/scopesearchindexmanager.js +0 -2
  69. package/dist/searchexecutor.js +3 -1
  70. package/dist/searchtypes.d.ts +16 -6
  71. package/dist/searchtypes.js +2 -6
  72. package/dist/transactions.d.ts +23 -0
  73. package/dist/transactions.js +16 -10
  74. package/dist/vectorsearch.d.ts +8 -8
  75. package/dist/vectorsearch.js +7 -7
  76. package/package.json +7 -7
  77. package/src/instance.cpp +11 -1
  78. package/src/instance.hpp +1 -0
  79. package/src/jstocbpp_autogen.hpp +8 -1
  80. package/src/jstocbpp_transactions.hpp +40 -3
  81. package/src/transactions.cpp +12 -1
  82. package/tools/gen-bindings-json.py +0 -1
  83. package/deps/couchbase-cxx-client/core/scan_options.hxx +0 -44
@@ -475,120 +475,129 @@ class collection_impl : public std::enable_shared_from_this<collection_impl>
475
475
  {
476
476
  auto request = std::make_shared<couchbase::core::impl::lookup_in_all_replicas_request>(
477
477
  bucket_name_, scope_name_, name_, std::move(document_key), specs, options.timeout);
478
- core_.with_bucket_configuration(
478
+ core_.open_bucket(
479
479
  bucket_name_,
480
- [core = core_, r = std::move(request), h = std::move(handler)](std::error_code ec,
481
- const core::topology::configuration& config) mutable {
482
- if (!config.capabilities.supports_subdoc_read_replica()) {
483
- ec = errc::common::feature_not_available;
484
- }
485
-
480
+ [core = core_, bucket_name = bucket_name_, r = std::move(request), h = std::move(handler)](std::error_code ec) mutable {
486
481
  if (ec) {
487
- return h(core::make_subdocument_error_context(make_key_value_error_context(ec, r->id()), ec, {}, {}, false),
488
- lookup_in_all_replicas_result{});
482
+ h(core::make_subdocument_error_context(make_key_value_error_context(ec, r->id()), ec, {}, {}, false),
483
+ lookup_in_all_replicas_result{});
484
+ return;
489
485
  }
490
- struct replica_context {
491
- replica_context(core::impl::movable_lookup_in_all_replicas_handler handler, std::uint32_t expected_responses)
492
- : handler_(std::move(handler))
493
- , expected_responses_(expected_responses)
494
- {
495
- }
496
486
 
497
- core::impl::movable_lookup_in_all_replicas_handler handler_;
498
- std::uint32_t expected_responses_;
499
- bool done_{ false };
500
- std::mutex mutex_{};
501
- lookup_in_all_replicas_result result_{};
502
- };
503
- auto ctx = std::make_shared<replica_context>(std::move(h), config.num_replicas.value_or(0U) + 1U);
487
+ return core.with_bucket_configuration(
488
+ bucket_name,
489
+ [core = core, r = std::move(r), h = std::move(h)](std::error_code ec, const core::topology::configuration& config) mutable {
490
+ if (!config.capabilities.supports_subdoc_read_replica()) {
491
+ ec = errc::common::feature_not_available;
492
+ }
504
493
 
505
- for (std::size_t idx = 1U; idx <= config.num_replicas.value_or(0U); ++idx) {
506
- core::document_id replica_id{ r->id() };
507
- replica_id.node_index(idx);
508
- core.execute(core::impl::lookup_in_replica_request{ std::move(replica_id), r->specs(), r->timeout() },
509
- [ctx](core::impl::lookup_in_replica_response&& resp) {
510
- core::impl::movable_lookup_in_all_replicas_handler local_handler{};
511
- {
512
- const std::scoped_lock lock(ctx->mutex_);
513
- if (ctx->done_) {
514
- return;
515
- }
516
- --ctx->expected_responses_;
517
- if (resp.ctx.ec()) {
518
- if (ctx->expected_responses_ > 0) {
519
- // just ignore the response
520
- return;
521
- }
522
- } else {
523
- std::vector<lookup_in_replica_result::entry> entries{};
524
- for (const auto& field : resp.fields) {
525
- lookup_in_replica_result::entry lookup_in_entry{};
526
- lookup_in_entry.path = field.path;
527
- lookup_in_entry.value = field.value;
528
- lookup_in_entry.exists = field.exists;
529
- lookup_in_entry.original_index = field.original_index;
530
- lookup_in_entry.ec = field.ec;
531
- entries.emplace_back(lookup_in_entry);
532
- }
533
- ctx->result_.emplace_back(resp.cas, entries, resp.deleted, true /* replica */);
534
- }
535
- if (ctx->expected_responses_ == 0) {
536
- ctx->done_ = true;
537
- std::swap(local_handler, ctx->handler_);
538
- }
539
- }
540
- if (local_handler) {
541
- if (!ctx->result_.empty()) {
542
- resp.ctx.override_ec({});
543
- }
544
- return local_handler(std::move(resp.ctx), std::move(ctx->result_));
545
- }
546
- });
547
- }
494
+ if (ec) {
495
+ return h(core::make_subdocument_error_context(make_key_value_error_context(ec, r->id()), ec, {}, {}, false),
496
+ lookup_in_all_replicas_result{});
497
+ }
498
+ struct replica_context {
499
+ replica_context(core::impl::movable_lookup_in_all_replicas_handler handler, std::uint32_t expected_responses)
500
+ : handler_(std::move(handler))
501
+ , expected_responses_(expected_responses)
502
+ {
503
+ }
504
+
505
+ core::impl::movable_lookup_in_all_replicas_handler handler_;
506
+ std::uint32_t expected_responses_;
507
+ bool done_{ false };
508
+ std::mutex mutex_{};
509
+ lookup_in_all_replicas_result result_{};
510
+ };
511
+ auto ctx = std::make_shared<replica_context>(std::move(h), config.num_replicas.value_or(0U) + 1U);
512
+
513
+ for (std::size_t idx = 1U; idx <= config.num_replicas.value_or(0U); ++idx) {
514
+ core::document_id replica_id{ r->id() };
515
+ replica_id.node_index(idx);
516
+ core.execute(core::impl::lookup_in_replica_request{ std::move(replica_id), r->specs(), r->timeout() },
517
+ [ctx](core::impl::lookup_in_replica_response&& resp) {
518
+ core::impl::movable_lookup_in_all_replicas_handler local_handler{};
519
+ {
520
+ const std::scoped_lock lock(ctx->mutex_);
521
+ if (ctx->done_) {
522
+ return;
523
+ }
524
+ --ctx->expected_responses_;
525
+ if (resp.ctx.ec()) {
526
+ if (ctx->expected_responses_ > 0) {
527
+ // just ignore the response
528
+ return;
529
+ }
530
+ } else {
531
+ std::vector<lookup_in_replica_result::entry> entries{};
532
+ for (const auto& field : resp.fields) {
533
+ lookup_in_replica_result::entry lookup_in_entry{};
534
+ lookup_in_entry.path = field.path;
535
+ lookup_in_entry.value = field.value;
536
+ lookup_in_entry.exists = field.exists;
537
+ lookup_in_entry.original_index = field.original_index;
538
+ lookup_in_entry.ec = field.ec;
539
+ entries.emplace_back(lookup_in_entry);
540
+ }
541
+ ctx->result_.emplace_back(resp.cas, entries, resp.deleted, true /* replica */);
542
+ }
543
+ if (ctx->expected_responses_ == 0) {
544
+ ctx->done_ = true;
545
+ std::swap(local_handler, ctx->handler_);
546
+ }
547
+ }
548
+ if (local_handler) {
549
+ if (!ctx->result_.empty()) {
550
+ resp.ctx.override_ec({});
551
+ }
552
+ return local_handler(std::move(resp.ctx), std::move(ctx->result_));
553
+ }
554
+ });
555
+ }
548
556
 
549
- core::operations::lookup_in_request active{ core::document_id{ r->id() } };
550
- active.specs = r->specs();
551
- active.timeout = r->timeout();
552
- core.execute(active, [ctx](core::operations::lookup_in_response&& resp) {
553
- core::impl::movable_lookup_in_all_replicas_handler local_handler{};
554
- {
555
- const std::scoped_lock lock(ctx->mutex_);
556
- if (ctx->done_) {
557
- return;
558
- }
559
- --ctx->expected_responses_;
560
- if (resp.ctx.ec()) {
561
- if (ctx->expected_responses_ > 0) {
562
- // just ignore the response
563
- return;
564
- }
565
- } else {
566
- std::vector<lookup_in_replica_result::entry> entries{};
567
- for (const auto& field : resp.fields) {
568
- lookup_in_replica_result::entry lookup_in_entry{};
569
- lookup_in_entry.path = field.path;
570
- lookup_in_entry.value = field.value;
571
- lookup_in_entry.exists = field.exists;
572
- lookup_in_entry.original_index = field.original_index;
573
- lookup_in_entry.ec = field.ec;
574
- entries.emplace_back(lookup_in_entry);
575
- }
576
- ctx->result_.emplace_back(resp.cas, entries, resp.deleted, false /* active */);
577
- }
578
- if (ctx->expected_responses_ == 0) {
579
- ctx->done_ = true;
580
- std::swap(local_handler, ctx->handler_);
581
- }
582
- }
583
- if (local_handler) {
584
- if (!ctx->result_.empty()) {
585
- resp.ctx.override_ec({});
586
- }
587
- return local_handler(std::move(resp.ctx), std::move(ctx->result_));
588
- }
589
- });
557
+ core::operations::lookup_in_request active{ core::document_id{ r->id() } };
558
+ active.specs = r->specs();
559
+ active.timeout = r->timeout();
560
+ core.execute(active, [ctx](core::operations::lookup_in_response&& resp) {
561
+ core::impl::movable_lookup_in_all_replicas_handler local_handler{};
562
+ {
563
+ const std::scoped_lock lock(ctx->mutex_);
564
+ if (ctx->done_) {
565
+ return;
566
+ }
567
+ --ctx->expected_responses_;
568
+ if (resp.ctx.ec()) {
569
+ if (ctx->expected_responses_ > 0) {
570
+ // just ignore the response
571
+ return;
572
+ }
573
+ } else {
574
+ std::vector<lookup_in_replica_result::entry> entries{};
575
+ for (const auto& field : resp.fields) {
576
+ lookup_in_replica_result::entry lookup_in_entry{};
577
+ lookup_in_entry.path = field.path;
578
+ lookup_in_entry.value = field.value;
579
+ lookup_in_entry.exists = field.exists;
580
+ lookup_in_entry.original_index = field.original_index;
581
+ lookup_in_entry.ec = field.ec;
582
+ entries.emplace_back(lookup_in_entry);
583
+ }
584
+ ctx->result_.emplace_back(resp.cas, entries, resp.deleted, false /* active */);
585
+ }
586
+ if (ctx->expected_responses_ == 0) {
587
+ ctx->done_ = true;
588
+ std::swap(local_handler, ctx->handler_);
589
+ }
590
+ }
591
+ if (local_handler) {
592
+ if (!ctx->result_.empty()) {
593
+ resp.ctx.override_ec({});
594
+ }
595
+ return local_handler(std::move(resp.ctx), std::move(ctx->result_));
596
+ }
597
+ });
598
+ });
590
599
  });
591
- }
600
+ };
592
601
 
593
602
  void lookup_in_any_replica(std::string document_key,
594
603
  const std::vector<core::impl::subdoc::command>& specs,
@@ -597,114 +606,120 @@ class collection_impl : public std::enable_shared_from_this<collection_impl>
597
606
  {
598
607
  auto request = std::make_shared<couchbase::core::impl::lookup_in_any_replica_request>(
599
608
  bucket_name_, scope_name_, name_, std::move(document_key), specs, options.timeout);
600
- core_.with_bucket_configuration(
609
+ core_.open_bucket(
601
610
  bucket_name_,
602
- [core = core_, r = std::move(request), h = std::move(handler)](std::error_code ec,
603
- const core::topology::configuration& config) mutable {
604
- if (!config.capabilities.supports_subdoc_read_replica()) {
605
- ec = errc::common::feature_not_available;
606
- }
607
- if (r->specs().size() > 16) {
608
- ec = errc::common::invalid_argument;
609
- }
611
+ [core = core_, bucket_name = bucket_name_, r = std::move(request), h = std::move(handler)](std::error_code ec) mutable {
610
612
  if (ec) {
611
- return h(core::make_subdocument_error_context(make_key_value_error_context(ec, r->id()), ec, {}, {}, false),
612
- lookup_in_replica_result{});
613
+ h(core::make_subdocument_error_context(make_key_value_error_context(ec, r->id()), ec, {}, {}, false),
614
+ lookup_in_replica_result{});
615
+ return;
613
616
  }
614
- struct replica_context {
615
- replica_context(core::impl::movable_lookup_in_any_replica_handler handler, std::uint32_t expected_responses)
616
- : handler_(std::move(handler))
617
- , expected_responses_(expected_responses)
618
- {
619
- }
620
617
 
621
- core::impl::movable_lookup_in_any_replica_handler handler_;
622
- std::uint32_t expected_responses_;
623
- bool done_{ false };
624
- std::mutex mutex_{};
625
- };
626
- auto ctx = std::make_shared<replica_context>(std::move(h), config.num_replicas.value_or(0U) + 1U);
627
-
628
- for (std::size_t idx = 1U; idx <= config.num_replicas.value_or(0U); ++idx) {
629
- core::document_id replica_id{ r->id() };
630
- replica_id.node_index(idx);
631
- core.execute(core::impl::lookup_in_replica_request{ std::move(replica_id), r->specs(), r->timeout() },
632
- [ctx](core::impl::lookup_in_replica_response&& resp) {
633
- core::impl::movable_lookup_in_any_replica_handler local_handler;
634
- {
635
- const std::scoped_lock lock(ctx->mutex_);
636
- if (ctx->done_) {
637
- return;
638
- }
639
- --ctx->expected_responses_;
640
- if (resp.ctx.ec()) {
641
- if (ctx->expected_responses_ > 0) {
642
- // just ignore the response
643
- return;
644
- }
645
- // consider document irretrievable and give up
646
- resp.ctx.override_ec(errc::key_value::document_irretrievable);
647
- }
648
- ctx->done_ = true;
649
- std::swap(local_handler, ctx->handler_);
650
- }
651
- if (local_handler) {
652
- std::vector<lookup_in_replica_result::entry> entries;
653
- for (const auto& field : resp.fields) {
654
- lookup_in_replica_result::entry entry{};
655
- entry.path = field.path;
656
- entry.original_index = field.original_index;
657
- entry.exists = field.exists;
658
- entry.value = field.value;
659
- entry.ec = field.ec;
660
- entries.emplace_back(entry);
661
- }
662
- return local_handler(
663
- std::move(resp.ctx),
664
- lookup_in_replica_result{ resp.cas, entries, resp.deleted, true /* replica */ });
665
- }
666
- });
667
- }
618
+ return core.with_bucket_configuration(
619
+ bucket_name,
620
+ [core = core, r = std::move(r), h = std::move(h)](std::error_code ec, const core::topology::configuration& config) mutable {
621
+ if (!config.capabilities.supports_subdoc_read_replica()) {
622
+ ec = errc::common::feature_not_available;
623
+ }
624
+ if (ec) {
625
+ return h(core::make_subdocument_error_context(make_key_value_error_context(ec, r->id()), ec, {}, {}, false),
626
+ lookup_in_replica_result{});
627
+ }
628
+ struct replica_context {
629
+ replica_context(core::impl::movable_lookup_in_any_replica_handler handler, std::uint32_t expected_responses)
630
+ : handler_(std::move(handler))
631
+ , expected_responses_(expected_responses)
632
+ {
633
+ }
634
+
635
+ core::impl::movable_lookup_in_any_replica_handler handler_;
636
+ std::uint32_t expected_responses_;
637
+ bool done_{ false };
638
+ std::mutex mutex_{};
639
+ };
640
+ auto ctx = std::make_shared<replica_context>(std::move(h), config.num_replicas.value_or(0U) + 1U);
641
+
642
+ for (std::size_t idx = 1U; idx <= config.num_replicas.value_or(0U); ++idx) {
643
+ core::document_id replica_id{ r->id() };
644
+ replica_id.node_index(idx);
645
+ core.execute(core::impl::lookup_in_replica_request{ std::move(replica_id), r->specs(), r->timeout() },
646
+ [ctx](core::impl::lookup_in_replica_response&& resp) {
647
+ core::impl::movable_lookup_in_any_replica_handler local_handler;
648
+ {
649
+ const std::scoped_lock lock(ctx->mutex_);
650
+ if (ctx->done_) {
651
+ return;
652
+ }
653
+ --ctx->expected_responses_;
654
+ if (resp.ctx.ec()) {
655
+ if (ctx->expected_responses_ > 0) {
656
+ // just ignore the response
657
+ return;
658
+ }
659
+ // consider document irretrievable and give up
660
+ resp.ctx.override_ec(errc::key_value::document_irretrievable);
661
+ }
662
+ ctx->done_ = true;
663
+ std::swap(local_handler, ctx->handler_);
664
+ }
665
+ if (local_handler) {
666
+ std::vector<lookup_in_replica_result::entry> entries;
667
+ for (const auto& field : resp.fields) {
668
+ lookup_in_replica_result::entry entry{};
669
+ entry.path = field.path;
670
+ entry.original_index = field.original_index;
671
+ entry.exists = field.exists;
672
+ entry.value = field.value;
673
+ entry.ec = field.ec;
674
+ entries.emplace_back(entry);
675
+ }
676
+ return local_handler(
677
+ std::move(resp.ctx),
678
+ lookup_in_replica_result{ resp.cas, entries, resp.deleted, true /* replica */ });
679
+ }
680
+ });
681
+ }
668
682
 
669
- core::operations::lookup_in_request active{ core::document_id{ r->id() } };
670
- active.specs = r->specs();
671
- active.timeout = r->timeout();
672
- core.execute(active, [ctx](core::operations::lookup_in_response&& resp) {
673
- core::impl::movable_lookup_in_any_replica_handler local_handler{};
674
- {
675
- const std::scoped_lock lock(ctx->mutex_);
676
- if (ctx->done_) {
677
- return;
678
- }
679
- --ctx->expected_responses_;
680
- if (resp.ctx.ec()) {
681
- if (ctx->expected_responses_ > 0) {
682
- // just ignore the response
683
- return;
684
- }
685
- // consider document irretrievable and give up
686
- resp.ctx.override_ec(errc::key_value::document_irretrievable);
687
- }
688
- ctx->done_ = true;
689
- std::swap(local_handler, ctx->handler_);
690
- }
691
- if (local_handler) {
692
- std::vector<lookup_in_replica_result::entry> entries;
693
- for (const auto& field : resp.fields) {
694
- lookup_in_replica_result::entry entry{};
695
- entry.path = field.path;
696
- entry.original_index = field.original_index;
697
- entry.exists = field.exists;
698
- entry.value = field.value;
699
- entry.ec = field.ec;
700
- entries.emplace_back(entry);
701
- }
702
- return local_handler(std::move(resp.ctx),
703
- lookup_in_replica_result{ resp.cas, entries, resp.deleted, false /* active */ });
704
- }
705
- });
683
+ core::operations::lookup_in_request active{ core::document_id{ r->id() } };
684
+ active.specs = r->specs();
685
+ active.timeout = r->timeout();
686
+ core.execute(active, [ctx](core::operations::lookup_in_response&& resp) {
687
+ core::impl::movable_lookup_in_any_replica_handler local_handler{};
688
+ {
689
+ const std::scoped_lock lock(ctx->mutex_);
690
+ if (ctx->done_) {
691
+ return;
692
+ }
693
+ --ctx->expected_responses_;
694
+ if (resp.ctx.ec()) {
695
+ if (ctx->expected_responses_ > 0) {
696
+ // just ignore the response
697
+ return;
698
+ }
699
+ // consider document irretrievable and give up
700
+ resp.ctx.override_ec(errc::key_value::document_irretrievable);
701
+ }
702
+ ctx->done_ = true;
703
+ std::swap(local_handler, ctx->handler_);
704
+ }
705
+ if (local_handler) {
706
+ std::vector<lookup_in_replica_result::entry> entries;
707
+ for (const auto& field : resp.fields) {
708
+ lookup_in_replica_result::entry entry{};
709
+ entry.path = field.path;
710
+ entry.original_index = field.original_index;
711
+ entry.exists = field.exists;
712
+ entry.value = field.value;
713
+ entry.ec = field.ec;
714
+ entries.emplace_back(entry);
715
+ }
716
+ return local_handler(std::move(resp.ctx),
717
+ lookup_in_replica_result{ resp.cas, entries, resp.deleted, false /* active */ });
718
+ }
719
+ });
720
+ });
706
721
  });
707
- }
722
+ };
708
723
 
709
724
  void mutate_in(std::string document_key,
710
725
  const std::vector<core::impl::subdoc::command>& specs,
@@ -38,8 +38,8 @@ query_error_context::to_json() const -> std::string
38
38
  { "retry_attempts", retry_attempts() },
39
39
  { "client_context_id", client_context_id_ },
40
40
  { "statement", statement_ },
41
- { "method", statement_ },
42
- { "path", statement_ },
41
+ { "method", method_ },
42
+ { "path", path_ },
43
43
  { "http_status", http_status_ },
44
44
  { "http_body", http_body_ },
45
45
  { "hostname", hostname_ },
@@ -30,6 +30,7 @@
30
30
 
31
31
  #include <asio/steady_timer.hpp>
32
32
 
33
+ #include <algorithm>
33
34
  #include <utility>
34
35
 
35
36
  namespace couchbase
@@ -285,6 +285,10 @@ dns_client::query_srv(const std::string& name,
285
285
  const dns_config& config,
286
286
  utils::movable_function<void(dns_srv_response&&)>&& handler)
287
287
  {
288
+ if (config.nameserver().empty()) {
289
+ return handler({ {} });
290
+ }
291
+
288
292
  std::error_code ec;
289
293
  auto address = asio::ip::make_address(config.nameserver(), ec);
290
294
  if (ec) {
@@ -53,6 +53,7 @@ load_resolv_conf()
53
53
  fixed_info = (FIXED_INFO*)malloc(sizeof(FIXED_INFO));
54
54
  if (fixed_info == NULL) {
55
55
  CB_LOG_WARNING("Error allocating memory needed to call GetNetworkParams");
56
+ return {};
56
57
  }
57
58
  buf = sizeof(FIXED_INFO);
58
59
 
@@ -63,6 +64,7 @@ load_resolv_conf()
63
64
  fixed_info = (FIXED_INFO*)malloc(buf);
64
65
  if (fixed_info == NULL) {
65
66
  CB_LOG_WARNING("Error allocating memory needed to call GetNetworkParams");
67
+ return {};
66
68
  }
67
69
  }
68
70
 
@@ -86,10 +88,12 @@ load_resolv_conf()
86
88
  }
87
89
  } else {
88
90
  CB_LOG_WARNING("GetNetworkParams failed with error: {}", ret);
91
+ return {};
89
92
  }
90
93
 
91
- if (fixed_info)
94
+ if (fixed_info) {
92
95
  free(fixed_info);
96
+ }
93
97
 
94
98
  if (dns_servers.size() > 0) {
95
99
  CB_LOG_DEBUG(
@@ -153,10 +157,17 @@ dns_config::system_config()
153
157
  std::error_code ec;
154
158
  asio::ip::make_address(nameserver, ec);
155
159
  if (ec) {
156
- CB_LOG_DEBUG("Unable to parse \"{}\" as a network address, fall back to \"{}\"", nameserver, default_nameserver);
157
- nameserver = default_nameserver;
160
+ std::string extra_info{};
161
+ #ifndef _WIN32
162
+ extra_info = fmt::format(" in \"{}\"", default_resolv_conf_path);
163
+ #endif
164
+ CB_LOG_WARNING("System DNS detection failed: unable to parse \"{}\" as a network address{}. DNS-SRV will not work "
165
+ "unless nameserver is specified explicitly in the options.",
166
+ nameserver,
167
+ extra_info);
168
+ } else {
169
+ instance.nameserver_ = nameserver;
158
170
  }
159
- instance.nameserver_ = nameserver;
160
171
  });
161
172
 
162
173
  return instance;
@@ -40,7 +40,7 @@ class dns_config
40
40
  [[nodiscard]] std::chrono::milliseconds timeout() const;
41
41
 
42
42
  private:
43
- std::string nameserver_{ default_nameserver };
43
+ std::string nameserver_{};
44
44
  std::uint16_t port_{ default_port };
45
45
  std::chrono::milliseconds timeout_{ timeout_defaults::dns_srv_timeout };
46
46
  };