couchbase 3.4.3 → 3.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/ext/couchbase/CMakeLists.txt +22 -1
  4. data/ext/couchbase/core/bucket.cxx +183 -152
  5. data/ext/couchbase/core/bucket.hxx +17 -4
  6. data/ext/couchbase/core/cluster.hxx +41 -13
  7. data/ext/couchbase/core/cluster_options.hxx +3 -0
  8. data/ext/couchbase/core/crud_component.cxx +51 -22
  9. data/ext/couchbase/core/error_context/key_value.cxx +2 -1
  10. data/ext/couchbase/core/error_context/key_value.hxx +10 -12
  11. data/ext/couchbase/core/impl/build_deferred_query_indexes.cxx +115 -50
  12. data/ext/couchbase/core/impl/cluster.cxx +6 -0
  13. data/ext/couchbase/core/impl/create_bucket.cxx +158 -0
  14. data/ext/couchbase/core/impl/create_collection.cxx +83 -0
  15. data/ext/couchbase/core/impl/create_query_index.cxx +172 -59
  16. data/ext/couchbase/core/impl/create_scope.cxx +69 -0
  17. data/ext/couchbase/core/impl/dns_srv_tracker.cxx +2 -1
  18. data/ext/couchbase/core/impl/drop_bucket.cxx +66 -0
  19. data/ext/couchbase/core/impl/drop_collection.cxx +76 -0
  20. data/ext/couchbase/core/impl/drop_query_index.cxx +138 -59
  21. data/ext/couchbase/core/impl/drop_scope.cxx +68 -0
  22. data/ext/couchbase/core/impl/flush_bucket.cxx +66 -0
  23. data/ext/couchbase/core/impl/get_all_buckets.cxx +178 -0
  24. data/ext/couchbase/core/impl/get_all_query_indexes.cxx +67 -37
  25. data/ext/couchbase/core/impl/get_all_scopes.cxx +94 -0
  26. data/ext/couchbase/core/impl/get_bucket.cxx +168 -0
  27. data/ext/couchbase/core/impl/internal_manager_error_context.cxx +113 -0
  28. data/ext/couchbase/core/impl/internal_manager_error_context.hxx +60 -0
  29. data/ext/couchbase/core/impl/key_value_error_category.cxx +2 -4
  30. data/ext/couchbase/core/impl/key_value_error_context.cxx +98 -0
  31. data/ext/couchbase/core/impl/lookup_in.cxx +1 -0
  32. data/ext/couchbase/core/impl/lookup_in_all_replicas.cxx +178 -0
  33. data/ext/couchbase/core/impl/lookup_in_all_replicas.hxx +80 -0
  34. data/ext/couchbase/core/impl/lookup_in_any_replica.cxx +169 -0
  35. data/ext/couchbase/core/impl/lookup_in_any_replica.hxx +75 -0
  36. data/ext/couchbase/core/impl/lookup_in_replica.cxx +104 -0
  37. data/ext/couchbase/core/impl/lookup_in_replica.hxx +67 -0
  38. data/ext/couchbase/core/impl/manager_error_context.cxx +100 -0
  39. data/ext/couchbase/core/impl/query.cxx +1 -0
  40. data/ext/couchbase/core/impl/query_error_context.cxx +75 -0
  41. data/ext/couchbase/core/impl/update_bucket.cxx +133 -0
  42. data/ext/couchbase/core/impl/update_collection.cxx +83 -0
  43. data/ext/couchbase/core/impl/watch_query_indexes.cxx +53 -29
  44. data/ext/couchbase/core/io/dns_client.cxx +111 -40
  45. data/ext/couchbase/core/io/dns_config.cxx +5 -4
  46. data/ext/couchbase/core/io/http_session.hxx +24 -1
  47. data/ext/couchbase/core/io/mcbp_command.hxx +9 -2
  48. data/ext/couchbase/core/io/mcbp_session.cxx +80 -43
  49. data/ext/couchbase/core/io/mcbp_session.hxx +4 -3
  50. data/ext/couchbase/core/logger/custom_rotating_file_sink.cxx +1 -1
  51. data/ext/couchbase/core/logger/logger.cxx +80 -20
  52. data/ext/couchbase/core/logger/logger.hxx +31 -0
  53. data/ext/couchbase/core/management/bucket_settings.hxx +8 -5
  54. data/ext/couchbase/core/management/bucket_settings_json.hxx +12 -2
  55. data/ext/couchbase/core/meta/features.hxx +42 -0
  56. data/ext/couchbase/core/operations/document_lookup_in.cxx +8 -1
  57. data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +192 -0
  58. data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +188 -0
  59. data/ext/couchbase/core/operations/document_query.cxx +11 -0
  60. data/ext/couchbase/core/operations/document_query.hxx +1 -0
  61. data/ext/couchbase/core/operations/management/CMakeLists.txt +1 -0
  62. data/ext/couchbase/core/operations/management/bucket_create.cxx +30 -9
  63. data/ext/couchbase/core/operations/management/bucket_update.cxx +27 -6
  64. data/ext/couchbase/core/operations/management/collection_create.cxx +5 -1
  65. data/ext/couchbase/core/operations/management/collection_create.hxx +1 -0
  66. data/ext/couchbase/core/operations/management/collection_update.cxx +87 -0
  67. data/ext/couchbase/core/operations/management/collection_update.hxx +54 -0
  68. data/ext/couchbase/core/operations/management/collections.hxx +1 -0
  69. data/ext/couchbase/core/operations.hxx +2 -0
  70. data/ext/couchbase/core/origin.cxx +270 -0
  71. data/ext/couchbase/core/origin.hxx +2 -0
  72. data/ext/couchbase/core/protocol/client_response.hxx +1 -0
  73. data/ext/couchbase/core/protocol/cmd_hello.hxx +1 -0
  74. data/ext/couchbase/core/protocol/cmd_lookup_in_replica.cxx +107 -0
  75. data/ext/couchbase/core/protocol/cmd_lookup_in_replica.hxx +137 -0
  76. data/ext/couchbase/core/protocol/hello_feature.hxx +6 -0
  77. data/ext/couchbase/core/protocol/hello_feature_fmt.hxx +3 -0
  78. data/ext/couchbase/core/protocol/status.cxx +2 -2
  79. data/ext/couchbase/core/range_scan_options.cxx +3 -27
  80. data/ext/couchbase/core/range_scan_options.hxx +13 -17
  81. data/ext/couchbase/core/range_scan_orchestrator.cxx +388 -170
  82. data/ext/couchbase/core/range_scan_orchestrator.hxx +13 -2
  83. data/ext/couchbase/core/range_scan_orchestrator_options.hxx +5 -3
  84. data/ext/couchbase/core/scan_options.hxx +0 -19
  85. data/ext/couchbase/core/scan_result.cxx +19 -5
  86. data/ext/couchbase/core/scan_result.hxx +5 -2
  87. data/ext/couchbase/core/timeout_defaults.hxx +3 -4
  88. data/ext/couchbase/core/topology/capabilities.hxx +4 -0
  89. data/ext/couchbase/core/topology/capabilities_fmt.hxx +11 -0
  90. data/ext/couchbase/core/topology/collections_manifest.hxx +2 -0
  91. data/ext/couchbase/core/topology/collections_manifest_fmt.hxx +1 -1
  92. data/ext/couchbase/core/topology/collections_manifest_json.hxx +3 -0
  93. data/ext/couchbase/core/topology/configuration.hxx +20 -0
  94. data/ext/couchbase/core/topology/configuration_json.hxx +8 -1
  95. data/ext/couchbase/core/utils/connection_string.cxx +62 -47
  96. data/ext/couchbase/core/utils/connection_string.hxx +1 -0
  97. data/ext/couchbase/couchbase/analytics_error_context.hxx +1 -1
  98. data/ext/couchbase/couchbase/behavior_options.hxx +19 -2
  99. data/ext/couchbase/couchbase/bucket.hxx +14 -0
  100. data/ext/couchbase/couchbase/bucket_manager.hxx +135 -0
  101. data/ext/couchbase/couchbase/build_query_index_options.hxx +0 -30
  102. data/ext/couchbase/couchbase/cluster.hxx +14 -0
  103. data/ext/couchbase/couchbase/collection.hxx +111 -0
  104. data/ext/couchbase/couchbase/collection_manager.hxx +160 -0
  105. data/ext/couchbase/couchbase/collection_query_index_manager.hxx +7 -48
  106. data/ext/couchbase/couchbase/create_bucket_options.hxx +41 -0
  107. data/ext/couchbase/couchbase/create_collection_options.hxx +44 -0
  108. data/ext/couchbase/couchbase/create_primary_query_index_options.hxx +0 -29
  109. data/ext/couchbase/couchbase/create_query_index_options.hxx +0 -33
  110. data/ext/couchbase/couchbase/create_scope_options.hxx +41 -0
  111. data/ext/couchbase/couchbase/drop_bucket_options.hxx +41 -0
  112. data/ext/couchbase/couchbase/drop_collection_options.hxx +41 -0
  113. data/ext/couchbase/couchbase/drop_primary_query_index_options.hxx +0 -30
  114. data/ext/couchbase/couchbase/drop_query_index_options.hxx +0 -31
  115. data/ext/couchbase/couchbase/drop_scope_options.hxx +41 -0
  116. data/ext/couchbase/couchbase/error_codes.hxx +1 -2
  117. data/ext/couchbase/couchbase/error_context.hxx +10 -2
  118. data/ext/couchbase/couchbase/flush_bucket_options.hxx +41 -0
  119. data/ext/couchbase/{core/topology/error_map_fmt.hxx → couchbase/fmt/key_value_error_map_attribute.hxx} +21 -21
  120. data/ext/couchbase/couchbase/get_all_buckets_options.hxx +44 -0
  121. data/ext/couchbase/couchbase/get_all_query_indexes_options.hxx +0 -30
  122. data/ext/couchbase/couchbase/get_all_scopes_options.hxx +44 -0
  123. data/ext/couchbase/couchbase/get_and_lock_options.hxx +2 -2
  124. data/ext/couchbase/couchbase/get_and_touch_options.hxx +2 -2
  125. data/ext/couchbase/couchbase/get_bucket_options.hxx +43 -0
  126. data/ext/couchbase/couchbase/get_options.hxx +2 -2
  127. data/ext/couchbase/couchbase/insert_options.hxx +3 -3
  128. data/ext/couchbase/couchbase/key_value_error_context.hxx +7 -2
  129. data/ext/couchbase/couchbase/lookup_in_all_replicas_options.hxx +109 -0
  130. data/ext/couchbase/couchbase/lookup_in_any_replica_options.hxx +101 -0
  131. data/ext/couchbase/couchbase/lookup_in_options.hxx +2 -2
  132. data/ext/couchbase/couchbase/lookup_in_replica_result.hxx +74 -0
  133. data/ext/couchbase/couchbase/lookup_in_result.hxx +26 -0
  134. data/ext/couchbase/couchbase/management/bucket_settings.hxx +119 -0
  135. data/ext/couchbase/couchbase/management/collection_spec.hxx +29 -0
  136. data/ext/couchbase/couchbase/management/scope_spec.hxx +29 -0
  137. data/ext/couchbase/couchbase/manager_error_context.hxx +29 -53
  138. data/ext/couchbase/couchbase/mutate_in_options.hxx +2 -2
  139. data/ext/couchbase/couchbase/query_error_context.hxx +3 -1
  140. data/ext/couchbase/couchbase/query_index_manager.hxx +16 -83
  141. data/ext/couchbase/couchbase/query_options.hxx +18 -0
  142. data/ext/couchbase/couchbase/remove_options.hxx +2 -2
  143. data/ext/couchbase/couchbase/replace_options.hxx +3 -3
  144. data/ext/couchbase/couchbase/security_options.hxx +15 -0
  145. data/ext/couchbase/couchbase/subdocument_error_context.hxx +4 -2
  146. data/ext/couchbase/couchbase/touch_options.hxx +2 -2
  147. data/ext/couchbase/couchbase/unlock_options.hxx +2 -2
  148. data/ext/couchbase/couchbase/update_bucket_options.hxx +41 -0
  149. data/ext/couchbase/couchbase/update_collection_options.hxx +44 -0
  150. data/ext/couchbase/couchbase/upsert_options.hxx +3 -3
  151. data/ext/couchbase/couchbase/watch_query_indexes_options.hxx +0 -31
  152. data/ext/couchbase/test/CMakeLists.txt +1 -0
  153. data/ext/couchbase/test/test_integration_collections.cxx +6 -0
  154. data/ext/couchbase/test/test_integration_crud.cxx +5 -0
  155. data/ext/couchbase/test/test_integration_examples.cxx +137 -1
  156. data/ext/couchbase/test/test_integration_management.cxx +1009 -309
  157. data/ext/couchbase/test/test_integration_query.cxx +19 -7
  158. data/ext/couchbase/test/test_integration_range_scan.cxx +351 -112
  159. data/ext/couchbase/test/test_integration_search.cxx +10 -1
  160. data/ext/couchbase/test/test_integration_subdoc.cxx +721 -7
  161. data/ext/couchbase/test/test_transaction_public_async_api.cxx +13 -12
  162. data/ext/couchbase/test/test_transaction_public_blocking_api.cxx +27 -21
  163. data/ext/couchbase/test/test_unit_connection_string.cxx +29 -0
  164. data/ext/couchbase/test/test_unit_query.cxx +75 -0
  165. data/ext/couchbase.cxx +735 -60
  166. data/ext/revisions.rb +3 -3
  167. data/lib/couchbase/cluster.rb +1 -1
  168. data/lib/couchbase/collection.rb +108 -0
  169. data/lib/couchbase/collection_options.rb +100 -1
  170. data/lib/couchbase/errors.rb +5 -0
  171. data/lib/couchbase/key_value_scan.rb +125 -0
  172. data/lib/couchbase/management/bucket_manager.rb +22 -15
  173. data/lib/couchbase/management/collection_manager.rb +158 -9
  174. data/lib/couchbase/options.rb +151 -0
  175. data/lib/couchbase/scope.rb +1 -1
  176. data/lib/couchbase/utils/time.rb +14 -1
  177. data/lib/couchbase/version.rb +1 -1
  178. metadata +59 -8
  179. data/ext/couchbase/core/impl/collection_query_index_manager.cxx +0 -93
@@ -28,6 +28,10 @@
28
28
  #include <asio/read.hpp>
29
29
  #include <asio/write.hpp>
30
30
 
31
+ #include <fmt/chrono.h>
32
+
33
+ #include <spdlog/fmt/bin_to_hex.h>
34
+
31
35
  #include <memory>
32
36
  #include <sstream>
33
37
 
@@ -68,22 +72,50 @@ class dns_srv_command : public std::enable_shared_from_this<dns_srv_command>
68
72
 
69
73
  void execute(std::chrono::milliseconds total_timeout, std::chrono::milliseconds udp_timeout)
70
74
  {
75
+ CB_LOG_TRACE("Query DNS-SRV (UDP) address=\"{}:{}\", udp_timeout={}, total_timeout={}",
76
+ address_.to_string(),
77
+ port_,
78
+ udp_timeout,
79
+ total_timeout);
71
80
  asio::ip::udp::endpoint endpoint(address_, port_);
72
81
  udp_.open(endpoint.protocol());
82
+ CB_LOG_PROTOCOL("[DNS, UDP, OUT] host=\"{}\", port={}, buffer_size={}{:a}",
83
+ address_.to_string(),
84
+ port_,
85
+ send_buf_.size(),
86
+ spdlog::to_hex(send_buf_));
73
87
  udp_.async_send_to(
74
- asio::buffer(send_buf_), endpoint, [self = shared_from_this()](std::error_code ec1, std::size_t /* bytes_transferred */) mutable {
88
+ asio::buffer(send_buf_), endpoint, [self = shared_from_this()](std::error_code ec1, std::size_t bytes_transferred1) mutable {
89
+ CB_LOG_PROTOCOL("[DNS, UDP, OUT] host=\"{}\", port={}, rc={}, bytes_sent={}",
90
+ self->address_.to_string(),
91
+ self->port_,
92
+ ec1 ? ec1.message() : "ok",
93
+ bytes_transferred1);
75
94
  if (ec1) {
76
95
  self->udp_deadline_.cancel();
77
- CB_LOG_DEBUG("DNS UDP write operation has got error {}, retrying with TCP", ec1.message());
96
+ CB_LOG_DEBUG("DNS UDP write operation has got error, retrying with TCP, address=\"{}:{}\", ec={}",
97
+ self->address_.to_string(),
98
+ self->port_,
99
+ ec1.message());
78
100
  return self->retry_with_tcp();
79
101
  }
80
102
 
81
103
  self->recv_buf_.resize(512);
82
104
  self->udp_.async_receive_from(
83
105
  asio::buffer(self->recv_buf_), self->udp_sender_, [self](std::error_code ec2, std::size_t bytes_transferred) mutable {
106
+ CB_LOG_PROTOCOL("[DNS, UDP, IN] host=\"{}\", port={}, rc={}, bytes_received={}{:a}",
107
+ self->address_.to_string(),
108
+ self->port_,
109
+ ec2 ? ec2.message() : "ok",
110
+ bytes_transferred,
111
+ spdlog::to_hex(self->recv_buf_.data(), self->recv_buf_.data() + bytes_transferred));
112
+
84
113
  self->udp_deadline_.cancel();
85
114
  if (ec2) {
86
- CB_LOG_DEBUG("DNS UDP read operation has got error {}, retrying with TCP", ec2.message());
115
+ CB_LOG_DEBUG("DNS UDP read operation has got error, retrying with TCP, address=\"{}:{}\", ec={}",
116
+ self->address_.to_string(),
117
+ self->port_,
118
+ ec2.message());
87
119
  return self->retry_with_tcp();
88
120
  }
89
121
  self->recv_buf_.resize(bytes_transferred);
@@ -104,11 +136,13 @@ class dns_srv_command : public std::enable_shared_from_this<dns_srv_command>
104
136
  });
105
137
  });
106
138
  udp_deadline_.expires_after(udp_timeout);
107
- deadline_.async_wait([self = shared_from_this()](std::error_code ec) {
139
+ udp_deadline_.async_wait([self = shared_from_this()](std::error_code ec) {
108
140
  if (ec == asio::error::operation_aborted) {
109
141
  return;
110
142
  }
111
- CB_LOG_DEBUG("DNS UDP deadline has been reached, cancelling UDP operation and fall back to TCP");
143
+ CB_LOG_DEBUG("DNS UDP deadline has been reached, cancelling UDP operation and fall back to TCP, address=\"{}:{}\"",
144
+ self->address_.to_string(),
145
+ self->port_);
112
146
  self->udp_.cancel();
113
147
  return self->retry_with_tcp();
114
148
  });
@@ -118,7 +152,10 @@ class dns_srv_command : public std::enable_shared_from_this<dns_srv_command>
118
152
  if (ec == asio::error::operation_aborted) {
119
153
  return;
120
154
  }
121
- CB_LOG_DEBUG("DNS deadline has been reached, cancelling in-flight operations (tcp.is_open={})", self->tcp_.is_open());
155
+ CB_LOG_DEBUG("DNS deadline has been reached, cancelling in-flight operations (tcp.is_open={}, address=\"{}:{}\")",
156
+ self->tcp_.is_open(),
157
+ self->address_.to_string(),
158
+ self->port_);
122
159
  self->udp_.cancel();
123
160
  if (self->tcp_.is_open()) {
124
161
  self->tcp_.cancel();
@@ -140,53 +177,87 @@ class dns_srv_command : public std::enable_shared_from_this<dns_srv_command>
140
177
  tcp_.async_connect(endpoint, [self = shared_from_this()](std::error_code ec1) mutable {
141
178
  if (ec1) {
142
179
  self->deadline_.cancel();
143
- CB_LOG_DEBUG("DNS TCP connection has been aborted, {}", ec1.message());
180
+ CB_LOG_DEBUG(
181
+ "DNS TCP connection has been aborted, address=\"{}:{}\", ec={}", self->address_.to_string(), self->port_, ec1.message());
144
182
  return self->handler_({ ec1 });
145
183
  }
146
184
  auto send_size = static_cast<std::uint16_t>(self->send_buf_.size());
147
185
  self->send_buf_.insert(self->send_buf_.begin(), static_cast<std::uint8_t>(send_size & 0xffU));
148
186
  self->send_buf_.insert(self->send_buf_.begin(), static_cast<std::uint8_t>(send_size >> 8U));
187
+ CB_LOG_PROTOCOL("[DNS, TCP, OUT] host=\"{}\", port={}, buffer_size={}{:a}",
188
+ self->address_.to_string(),
189
+ self->port_,
190
+ self->send_buf_.size(),
191
+ spdlog::to_hex(self->send_buf_));
149
192
  asio::async_write(
150
- self->tcp_, asio::buffer(self->send_buf_), [self](std::error_code ec2, std::size_t /* bytes_transferred */) mutable {
193
+ self->tcp_, asio::buffer(self->send_buf_), [self](std::error_code ec2, std::size_t bytes_transferred2) mutable {
194
+ CB_LOG_PROTOCOL("[DNS, TCP, OUT] host=\"{}\", port={}, rc={}, bytes_sent={}",
195
+ self->address_.to_string(),
196
+ self->port_,
197
+ ec2 ? ec2.message() : "ok",
198
+ bytes_transferred2);
151
199
  if (ec2) {
152
- CB_LOG_DEBUG("DNS TCP write operation has been aborted, {}", ec2.message());
200
+ CB_LOG_DEBUG("DNS TCP write operation has been aborted, address=\"{}:{}\", ec={}",
201
+ self->address_.to_string(),
202
+ self->port_,
203
+ ec2.message());
153
204
  self->deadline_.cancel();
154
205
  if (ec2 == asio::error::operation_aborted) {
155
206
  ec2 = errc::common::unambiguous_timeout;
156
207
  }
157
208
  return self->handler_({ ec2 });
158
209
  }
159
- asio::async_read(self->tcp_,
160
- asio::buffer(&self->recv_buf_size_, sizeof(std::uint16_t)),
161
- [self](std::error_code ec3, std::size_t /* bytes_transferred */) mutable {
162
- if (ec3) {
163
- CB_LOG_DEBUG("DNS TCP buf size read operation has been aborted, {}", ec3.message());
164
- self->deadline_.cancel();
165
- return self->handler_({ ec3 });
166
- }
167
- self->recv_buf_size_ = utils::byte_swap(self->recv_buf_size_);
168
- self->recv_buf_.resize(self->recv_buf_size_);
169
- CB_LOG_DEBUG("DNS TCP schedule read of {} bytes", self->recv_buf_size_);
170
- asio::async_read(self->tcp_,
171
- asio::buffer(self->recv_buf_),
172
- [self](std::error_code ec4, std::size_t bytes_transferred) mutable {
173
- self->deadline_.cancel();
174
- if (ec4) {
175
- CB_LOG_DEBUG("DNS TCP read operation has been aborted, {}", ec4.message());
176
- return self->handler_({ ec4 });
177
- }
178
- self->recv_buf_.resize(bytes_transferred);
179
- const dns_message message = dns_codec::decode(self->recv_buf_);
180
- dns_srv_response resp{ ec4 };
181
- resp.targets.reserve(message.answers.size());
182
- for (const auto& answer : message.answers) {
183
- resp.targets.emplace_back(dns_srv_response::address{
184
- utils::join_strings(answer.target.labels, "."), answer.port });
185
- }
186
- CB_LOG_DEBUG("DNS TCP returned {} records", resp.targets.size());
187
- return self->handler_(std::move(resp));
188
- });
189
- });
210
+ asio::async_read(
211
+ self->tcp_,
212
+ asio::buffer(&self->recv_buf_size_, sizeof(std::uint16_t)),
213
+ [self](std::error_code ec3, std::size_t bytes_transferred3) mutable {
214
+ CB_LOG_PROTOCOL("[DNS, TCP, IN] host=\"{}\", port={}, rc={}, bytes_received={}{:a}",
215
+ self->address_.to_string(),
216
+ self->port_,
217
+ ec3 ? ec3.message() : "ok",
218
+ bytes_transferred3,
219
+ spdlog::to_hex(reinterpret_cast<std::uint8_t*>(&self->recv_buf_size_),
220
+ reinterpret_cast<std::uint8_t*>(&self->recv_buf_size_) + bytes_transferred3));
221
+ if (ec3) {
222
+ CB_LOG_DEBUG("DNS TCP buf size read operation has been aborted, address=\"{}:{}\", ec={}",
223
+ self->address_.to_string(),
224
+ self->port_,
225
+ ec3.message());
226
+ self->deadline_.cancel();
227
+ return self->handler_({ ec3 });
228
+ }
229
+ self->recv_buf_size_ = utils::byte_swap(self->recv_buf_size_);
230
+ self->recv_buf_.resize(self->recv_buf_size_);
231
+ CB_LOG_DEBUG("DNS TCP schedule read of {} bytes", self->recv_buf_size_);
232
+ asio::async_read(
233
+ self->tcp_, asio::buffer(self->recv_buf_), [self](std::error_code ec4, std::size_t bytes_transferred4) mutable {
234
+ self->deadline_.cancel();
235
+ CB_LOG_PROTOCOL("[DNS, TCP, IN] host=\"{}\", port={}, rc={}, bytes_received={}{:a}",
236
+ self->address_.to_string(),
237
+ self->port_,
238
+ ec4 ? ec4.message() : "ok",
239
+ bytes_transferred4,
240
+ spdlog::to_hex(self->recv_buf_.data(), self->recv_buf_.data() + bytes_transferred4));
241
+
242
+ if (ec4) {
243
+ CB_LOG_DEBUG("DNS TCP read operation has been aborted, address=\"{}:{}\", ec={}",
244
+ self->address_.to_string(),
245
+ self->port_,
246
+ ec4.message());
247
+ return self->handler_({ ec4 });
248
+ }
249
+ self->recv_buf_.resize(bytes_transferred4);
250
+ const dns_message message = dns_codec::decode(self->recv_buf_);
251
+ dns_srv_response resp{ ec4 };
252
+ resp.targets.reserve(message.answers.size());
253
+ for (const auto& answer : message.answers) {
254
+ resp.targets.emplace_back(
255
+ dns_srv_response::address{ utils::join_strings(answer.target.labels, "."), answer.port });
256
+ }
257
+ CB_LOG_DEBUG("DNS TCP returned {} records", resp.targets.size());
258
+ return self->handler_(std::move(resp));
259
+ });
260
+ });
190
261
  });
191
262
  });
192
263
  }
@@ -87,7 +87,7 @@ load_resolv_conf()
87
87
 
88
88
  if (dns_servers.size() > 0) {
89
89
  CB_LOG_DEBUG(
90
- "Found DNS Servers: [{}], using nameserver: {}", couchbase::core::utils::join_strings(dns_servers, ", "), dns_servers[0]);
90
+ "Found DNS Servers: [{}], selected nameserver: \"{}\"", couchbase::core::utils::join_strings(dns_servers, ", "), dns_servers[0]);
91
91
  return dns_servers[0];
92
92
  }
93
93
  CB_LOG_WARNING("Unable to find DNS nameserver");
@@ -118,13 +118,13 @@ load_resolv_conf(const char* conf_path)
118
118
  if (space == std::string::npos || space == offset || line.size() < space + 2) {
119
119
  continue;
120
120
  }
121
- if (std::string keyword = line.substr(offset, space); keyword != "nameserver") {
121
+ if (const auto keyword = line.substr(offset, space); keyword != "nameserver") {
122
122
  continue;
123
123
  }
124
124
  offset = space + 1;
125
125
  space = line.find(' ', offset);
126
- auto nameserver = line.substr(offset, space);
127
- CB_LOG_DEBUG("Using nameserver: {}", nameserver);
126
+ auto nameserver = (space == std::string::npos) ? line.substr(offset) : line.substr(offset, space - offset);
127
+ CB_LOG_DEBUG("Selected nameserver: \"{}\" from \"{}\"", nameserver, conf_path);
128
128
  return nameserver;
129
129
  }
130
130
  }
@@ -147,6 +147,7 @@ dns_config::system_config()
147
147
  std::error_code ec;
148
148
  asio::ip::address::from_string(nameserver, ec);
149
149
  if (ec) {
150
+ CB_LOG_DEBUG("Unable to parse \"{}\" as a network address, fall back to \"{}\"", nameserver, default_nameserver);
150
151
  nameserver = default_nameserver;
151
152
  }
152
153
  instance.nameserver_ = nameserver;
@@ -31,7 +31,10 @@
31
31
 
32
32
  #include <couchbase/error_codes.hxx>
33
33
 
34
+ #include <spdlog/fmt/bin_to_hex.h>
35
+
34
36
  #include <asio.hpp>
37
+
35
38
  #include <list>
36
39
  #include <memory>
37
40
  #include <utility>
@@ -448,7 +451,20 @@ class http_session : public std::enable_shared_from_this<http_session>
448
451
  stream_->async_read_some(
449
452
  asio::buffer(input_buffer_), [self = shared_from_this()](std::error_code ec, std::size_t bytes_transferred) {
450
453
  if (ec == asio::error::operation_aborted || self->stopped_) {
454
+ CB_LOG_PROTOCOL("[HTTP, IN] type={}, host=\"{}\", rc={}, bytes_received={}",
455
+ self->type_,
456
+ self->info_.remote_address(),
457
+ ec ? ec.message() : "ok",
458
+ bytes_transferred);
451
459
  return;
460
+ } else {
461
+ CB_LOG_PROTOCOL("[HTTP, IN] type={}, host=\"{}\", rc={}, bytes_received={}{:a}",
462
+ self->type_,
463
+ self->info_.remote_address(),
464
+ ec ? ec.message() : "ok",
465
+ bytes_transferred,
466
+ spdlog::to_hex(self->input_buffer_.data(),
467
+ self->input_buffer_.data() + static_cast<std::ptrdiff_t>(bytes_transferred)));
452
468
  }
453
469
  self->last_active_ = std::chrono::steady_clock::now();
454
470
  if (ec) {
@@ -495,9 +511,16 @@ class http_session : public std::enable_shared_from_this<http_session>
495
511
  std::vector<asio::const_buffer> buffers;
496
512
  buffers.reserve(writing_buffer_.size());
497
513
  for (auto& buf : writing_buffer_) {
514
+ CB_LOG_PROTOCOL(
515
+ "[HTTP, OUT] type={}, host=\"{}\", buffer_size={}{:a}", type_, info_.remote_address(), buf.size(), spdlog::to_hex(buf));
498
516
  buffers.emplace_back(asio::buffer(buf));
499
517
  }
500
- stream_->async_write(buffers, [self = shared_from_this()](std::error_code ec, std::size_t /* bytes_transferred */) {
518
+ stream_->async_write(buffers, [self = shared_from_this()](std::error_code ec, std::size_t bytes_transferred) {
519
+ CB_LOG_PROTOCOL("[HTTP, OUT] type={}, host=\"{}\", rc={}, bytes_sent={}",
520
+ self->type_,
521
+ self->info_.remote_address(),
522
+ ec ? ec.message() : "ok",
523
+ bytes_transferred);
501
524
  if (ec == asio::error::operation_aborted || self->stopped_) {
502
525
  return;
503
526
  }
@@ -59,9 +59,13 @@ struct mcbp_command : public std::enable_shared_from_this<mcbp_command<Manager,
59
59
  mcbp_command_handler handler_{};
60
60
  std::shared_ptr<Manager> manager_{};
61
61
  std::chrono::milliseconds timeout_{};
62
- std::string id_{ uuid::to_string(uuid::random()) };
62
+ std::string id_{
63
+ fmt::format("{:02x}/{}", static_cast<std::uint8_t>(encoded_request_type::body_type::opcode), uuid::to_string(uuid::random()))
64
+ };
63
65
  std::shared_ptr<couchbase::tracing::request_span> span_{ nullptr };
64
66
  std::shared_ptr<couchbase::tracing::request_span> parent_span{ nullptr };
67
+ std::optional<std::string> last_dispatched_from_{};
68
+ std::optional<std::string> last_dispatched_to_{};
65
69
 
66
70
  mcbp_command(asio::io_context& ctx, std::shared_ptr<Manager> manager, Request req, std::chrono::milliseconds default_timeout)
67
71
  : deadline(ctx)
@@ -109,7 +113,10 @@ struct mcbp_command : public std::enable_shared_from_this<mcbp_command<Manager,
109
113
  handler_ = nullptr;
110
114
  }
111
115
  }
112
- invoke_handler(request.retries.idempotent() ? errc::common::unambiguous_timeout : errc::common::ambiguous_timeout);
116
+ invoke_handler(request.retries.idempotent() || !opaque_.has_value()
117
+ ? errc::common::unambiguous_timeout // safe to retry or has not been sent to the server
118
+ : errc::common::ambiguous_timeout // non-idempotent and has been sent to the server
119
+ );
113
120
  }
114
121
 
115
122
  void invoke_handler(std::error_code ec, std::optional<io::mcbp_message>&& msg = {})
@@ -379,7 +379,7 @@ class mcbp_session_impl
379
379
  Expects(protocol::is_valid_server_request_opcode(msg.header.opcode));
380
380
  switch (static_cast<protocol::server_opcode>(msg.header.opcode)) {
381
381
  case protocol::server_opcode::cluster_map_change_notification: {
382
- protocol::cmd_info info{ session_->endpoint_address_, session_->endpoint_.port() };
382
+ protocol::cmd_info info{ session_->bootstrap_hostname_, session_->bootstrap_port_number_ };
383
383
  if (session_->origin_.options().dump_configuration) {
384
384
  std::string_view config_text{ reinterpret_cast<const char*>(msg.body.data()), msg.body.size() };
385
385
  CB_LOG_TRACE(
@@ -404,7 +404,7 @@ class mcbp_session_impl
404
404
  CB_LOG_WARNING("{} unexpected server request: opcode={:x}, opaque={}{:a}{:a}",
405
405
  session_->log_prefix_,
406
406
  msg.header.opcode,
407
- msg.header.opaque,
407
+ utils::byte_swap(msg.header.opaque),
408
408
  spdlog::to_hex(msg.header_data()),
409
409
  spdlog::to_hex(msg.body));
410
410
  }
@@ -416,7 +416,7 @@ class mcbp_session_impl
416
416
  session_->log_prefix_,
417
417
  magic,
418
418
  msg.header.opcode,
419
- msg.header.opaque,
419
+ utils::byte_swap(msg.header.opaque),
420
420
  spdlog::to_hex(msg.header_data()),
421
421
  spdlog::to_hex(msg.body));
422
422
  break;
@@ -473,7 +473,7 @@ class mcbp_session_impl
473
473
  Expects(protocol::is_valid_client_opcode(msg.header.opcode));
474
474
  switch (auto opcode = static_cast<protocol::client_opcode>(msg.header.opcode)) {
475
475
  case protocol::client_opcode::get_cluster_config: {
476
- protocol::cmd_info info{ session_->endpoint_address_, session_->endpoint_.port() };
476
+ protocol::cmd_info info{ session_->bootstrap_hostname_, session_->bootstrap_port_number_ };
477
477
  if (session_->origin_.options().dump_configuration) {
478
478
  std::string_view config_text{ reinterpret_cast<const char*>(msg.body.data()), msg.body.size() };
479
479
  CB_LOG_TRACE("{} configuration from get_cluster_config response (size={}, endpoint=\"{}:{}\"), {}",
@@ -781,13 +781,10 @@ class mcbp_session_impl
781
781
  return;
782
782
  }
783
783
  std::tie(bootstrap_hostname_, bootstrap_port_) = origin_.next_address();
784
- log_prefix_ = fmt::format("[{}/{}/{}/{}] <{}:{}>",
785
- client_id_,
786
- id_,
787
- stream_->log_prefix(),
788
- bucket_name_.value_or("-"),
789
- bootstrap_hostname_,
790
- bootstrap_port_);
784
+ bootstrap_port_number_ = gsl::narrow_cast<std::uint16_t>(std::stoul(bootstrap_port_, nullptr, 10));
785
+ bootstrap_address_ = fmt::format("{}:{}", bootstrap_hostname_, bootstrap_port_);
786
+ log_prefix_ =
787
+ fmt::format("[{}/{}/{}/{}] <{}>", client_id_, id_, stream_->log_prefix(), bucket_name_.value_or("-"), bootstrap_address_);
791
788
  CB_LOG_DEBUG("{} attempt to establish MCBP connection", log_prefix_);
792
789
 
793
790
  async_resolve(origin_.options().use_ip_protocol,
@@ -807,7 +804,7 @@ class mcbp_session_impl
807
804
  return stopped_;
808
805
  }
809
806
 
810
- void on_stop(utils::movable_function<void(retry_reason)> handler)
807
+ void on_stop(utils::movable_function<void()> handler)
811
808
  {
812
809
  on_stop_handler_ = std::move(handler);
813
810
  }
@@ -863,7 +860,7 @@ class mcbp_session_impl
863
860
  config_listeners_.clear();
864
861
  state_ = diag::endpoint_state::disconnected;
865
862
  if (auto on_stop = std::move(on_stop_handler_); on_stop) {
866
- on_stop(reason);
863
+ on_stop();
867
864
  }
868
865
  }
869
866
 
@@ -874,7 +871,7 @@ class mcbp_session_impl
874
871
  }
875
872
  std::uint32_t opaque{ 0 };
876
873
  std::memcpy(&opaque, buf.data() + 12, sizeof(opaque));
877
- CB_LOG_TRACE("{} MCBP send, opaque={}, {:n}", log_prefix_, opaque, spdlog::to_hex(buf.begin(), buf.begin() + 24));
874
+ CB_LOG_TRACE("{} MCBP send, opaque={}, {:n}", log_prefix_, utils::byte_swap(opaque), spdlog::to_hex(buf.begin(), buf.begin() + 24));
878
875
  std::scoped_lock lock(output_buffer_mutex_);
879
876
  output_buffer_.emplace_back(std::move(buf));
880
877
  }
@@ -1058,6 +1055,11 @@ class mcbp_session_impl
1058
1055
  return config_->index_for_this_node();
1059
1056
  }
1060
1057
 
1058
+ [[nodiscard]] const std::string& bootstrap_address() const
1059
+ {
1060
+ return bootstrap_address_;
1061
+ }
1062
+
1061
1063
  [[nodiscard]] const std::string& bootstrap_hostname() const
1062
1064
  {
1063
1065
  return bootstrap_hostname_;
@@ -1068,6 +1070,11 @@ class mcbp_session_impl
1068
1070
  return bootstrap_port_;
1069
1071
  }
1070
1072
 
1073
+ [[nodiscard]] std::uint16_t bootstrap_port_number() const
1074
+ {
1075
+ return bootstrap_port_number_;
1076
+ }
1077
+
1071
1078
  [[nodiscard]] std::uint32_t next_opaque()
1072
1079
  {
1073
1080
  return ++opaque_;
@@ -1161,15 +1168,15 @@ class mcbp_session_impl
1161
1168
  CB_LOG_TRACE("{} configuration from not_my_vbucket response (size={}, endpoint=\"{}:{}\"), {}",
1162
1169
  log_prefix_,
1163
1170
  config_text.size(),
1164
- endpoint_address_,
1165
- endpoint_.port(),
1171
+ bootstrap_hostname_,
1172
+ bootstrap_port_number_,
1166
1173
  config_text);
1167
1174
  }
1168
- auto config = protocol::parse_config(config_text, endpoint_address_, endpoint_.port());
1175
+ auto config = protocol::parse_config(config_text, bootstrap_hostname_, bootstrap_port_number_);
1169
1176
  CB_LOG_DEBUG("{} received not_my_vbucket status for {}, opaque={} with config rev={} in the payload",
1170
1177
  log_prefix_,
1171
1178
  protocol::client_opcode(msg.header.opcode),
1172
- msg.header.opaque,
1179
+ utils::byte_swap(msg.header.opaque),
1173
1180
  config.rev_str());
1174
1181
  update_configuration(std::move(config));
1175
1182
  }
@@ -1204,6 +1211,12 @@ class mcbp_session_impl
1204
1211
  CB_LOG_DEBUG(R"({} server returned {} ({}), it must be transient condition, retrying)", log_prefix_, ec.value(), ec.message());
1205
1212
  return initiate_bootstrap();
1206
1213
  }
1214
+ if (!origin_.exhausted() && ec == errc::common::authentication_failure) {
1215
+ CB_LOG_DEBUG(
1216
+ R"({} server returned authentication_failure, but the bootstrap list is not exhausted yet. It must be transient condition, retrying)",
1217
+ log_prefix_);
1218
+ return initiate_bootstrap();
1219
+ }
1207
1220
 
1208
1221
  if (!bootstrapped_ && bootstrap_callback_) {
1209
1222
  bootstrap_deadline_.cancel();
@@ -1266,16 +1279,15 @@ class mcbp_session_impl
1266
1279
  }
1267
1280
  last_active_ = std::chrono::steady_clock::now();
1268
1281
  if (it != endpoints_.end()) {
1269
- CB_LOG_DEBUG("{} connecting to {}:{}, timeout={}ms",
1270
- log_prefix_,
1271
- it->endpoint().address().to_string(),
1272
- it->endpoint().port(),
1273
- origin_.options().connect_timeout.count());
1282
+ auto hostname = it->endpoint().address().to_string();
1283
+ auto port = it->endpoint().port();
1284
+ CB_LOG_DEBUG("{} connecting to {}:{}, timeout={}ms", log_prefix_, hostname, port, origin_.options().connect_timeout.count());
1274
1285
  connection_deadline_.expires_after(origin_.options().connect_timeout);
1275
- connection_deadline_.async_wait([self = shared_from_this()](const auto timer_ec) {
1286
+ connection_deadline_.async_wait([self = shared_from_this(), hostname, port](const auto timer_ec) {
1276
1287
  if (timer_ec == asio::error::operation_aborted || self->stopped_) {
1277
1288
  return;
1278
1289
  }
1290
+ CB_LOG_DEBUG("{} unable to connect to {}:{} in time, reconnecting", self->log_prefix_, hostname, port);
1279
1291
  return self->stream_->close([self](std::error_code) { self->initiate_bootstrap(); });
1280
1292
  });
1281
1293
  stream_->async_connect(it->endpoint(),
@@ -1353,7 +1365,20 @@ class mcbp_session_impl
1353
1365
  asio::buffer(input_buffer_),
1354
1366
  [self = shared_from_this(), stream_id = stream_->id()](std::error_code ec, std::size_t bytes_transferred) {
1355
1367
  if (ec == asio::error::operation_aborted || self->stopped_) {
1368
+ CB_LOG_PROTOCOL("[MCBP, IN] host=\"{}\", port={}, rc={}, bytes_received={}",
1369
+ self->endpoint_address_,
1370
+ self->endpoint_.port(),
1371
+ ec ? ec.message() : "ok",
1372
+ bytes_transferred);
1356
1373
  return;
1374
+ } else {
1375
+ CB_LOG_PROTOCOL("[MCBP, IN] host=\"{}\", port={}, rc={}, bytes_received={}{:a}",
1376
+ self->endpoint_address_,
1377
+ self->endpoint_.port(),
1378
+ ec ? ec.message() : "ok",
1379
+ bytes_transferred,
1380
+ spdlog::to_hex(self->input_buffer_.data(),
1381
+ self->input_buffer_.data() + static_cast<std::ptrdiff_t>(bytes_transferred)));
1357
1382
  }
1358
1383
  self->last_active_ = std::chrono::steady_clock::now();
1359
1384
  if (ec) {
@@ -1382,8 +1407,10 @@ class mcbp_session_impl
1382
1407
  if (self->stopped_) {
1383
1408
  return;
1384
1409
  }
1385
- CB_LOG_TRACE(
1386
- "{} MCBP recv, opaque={}, {:n}", self->log_prefix_, msg.header.opaque, spdlog::to_hex(msg.header_data()));
1410
+ CB_LOG_TRACE("{} MCBP recv, opaque={}, {:n}",
1411
+ self->log_prefix_,
1412
+ utils::byte_swap(msg.header.opaque),
1413
+ spdlog::to_hex(msg.header_data()));
1387
1414
  if (self->bootstrapped_) {
1388
1415
  self->handler_->handle(std::move(msg));
1389
1416
  } else {
@@ -1419,13 +1446,21 @@ class mcbp_session_impl
1419
1446
  std::vector<asio::const_buffer> buffers;
1420
1447
  buffers.reserve(writing_buffer_.size());
1421
1448
  for (auto& buf : writing_buffer_) {
1449
+ CB_LOG_PROTOCOL(
1450
+ "[MCBP, OUT] host=\"{}\", port={}, buffer_size={}{:a}", endpoint_address_, endpoint_.port(), buf.size(), spdlog::to_hex(buf));
1422
1451
  buffers.emplace_back(asio::buffer(buf));
1423
1452
  }
1424
- stream_->async_write(buffers, [self = shared_from_this()](std::error_code ec, std::size_t /*unused*/) {
1453
+ stream_->async_write(buffers, [self = shared_from_this()](std::error_code ec, std::size_t bytes_transferred) {
1454
+ CB_LOG_PROTOCOL("[MCBP, OUT] host=\"{}\", port={}, rc={}, bytes_sent={}",
1455
+ self->endpoint_address_,
1456
+ self->endpoint_.port(),
1457
+ ec ? ec.message() : "ok",
1458
+ bytes_transferred);
1425
1459
  if (ec == asio::error::operation_aborted || self->stopped_) {
1426
1460
  return;
1427
1461
  }
1428
1462
  self->last_active_ = std::chrono::steady_clock::now();
1463
+
1429
1464
  if (ec) {
1430
1465
  CB_LOG_ERROR(R"({} IO error while writing to the socket("{}"): {} ({}))",
1431
1466
  self->log_prefix_,
@@ -1462,7 +1497,7 @@ class mcbp_session_impl
1462
1497
  std::mutex command_handlers_mutex_{};
1463
1498
  std::map<std::uint32_t, command_handler> command_handlers_{};
1464
1499
  std::vector<std::shared_ptr<config_listener>> config_listeners_{};
1465
- utils::movable_function<void(retry_reason)> on_stop_handler_{};
1500
+ utils::movable_function<void()> on_stop_handler_{};
1466
1501
 
1467
1502
  std::atomic_bool bootstrapped_{ false };
1468
1503
  std::atomic_bool stopped_{ false };
@@ -1482,6 +1517,8 @@ class mcbp_session_impl
1482
1517
  std::mutex writing_buffer_mutex_{};
1483
1518
  std::string bootstrap_hostname_{};
1484
1519
  std::string bootstrap_port_{};
1520
+ std::string bootstrap_address_{};
1521
+ std::uint16_t bootstrap_port_number_{};
1485
1522
  asio::ip::tcp::endpoint endpoint_{}; // connected endpoint
1486
1523
  std::string endpoint_address_{}; // cached string with endpoint address
1487
1524
  asio::ip::tcp::endpoint local_endpoint_{};
@@ -1582,22 +1619,16 @@ mcbp_session::supports_feature(protocol::hello_feature feature)
1582
1619
  return impl_->supports_feature(feature);
1583
1620
  }
1584
1621
 
1585
- // const std::string&
1586
- // mcbp_session::id() const
1587
- // {
1588
- // return impl_->id();
1589
- // }
1590
- std::string
1622
+ const std::string&
1591
1623
  mcbp_session::id() const
1592
1624
  {
1593
- if (impl_) {
1594
- return fmt::format("{}, {}, {}, refcnt={}",
1595
- reinterpret_cast<const void*>(this),
1596
- reinterpret_cast<const void*>(impl_.get()),
1597
- impl_->id(),
1598
- impl_.use_count());
1599
- }
1600
- return fmt::format("{}, nullptr", reinterpret_cast<const void*>(this));
1625
+ return impl_->id();
1626
+ }
1627
+
1628
+ const std::string&
1629
+ mcbp_session::bootstrap_address() const
1630
+ {
1631
+ return impl_->bootstrap_address();
1601
1632
  }
1602
1633
 
1603
1634
  std::string
@@ -1624,6 +1655,12 @@ mcbp_session::bootstrap_port() const
1624
1655
  return impl_->bootstrap_port();
1625
1656
  }
1626
1657
 
1658
+ std::uint16_t
1659
+ mcbp_session::bootstrap_port_number() const
1660
+ {
1661
+ return impl_->bootstrap_port_number();
1662
+ }
1663
+
1627
1664
  void
1628
1665
  mcbp_session::write_and_subscribe(std::uint32_t opaque, std::vector<std::byte>&& data, command_handler&& handler)
1629
1666
  {
@@ -1637,7 +1674,7 @@ mcbp_session::bootstrap(utils::movable_function<void(std::error_code, topology::
1637
1674
  }
1638
1675
 
1639
1676
  void
1640
- mcbp_session::on_stop(utils::movable_function<void(retry_reason)> handler)
1677
+ mcbp_session::on_stop(utils::movable_function<void()> handler)
1641
1678
  {
1642
1679
  return impl_->on_stop(std::move(handler));
1643
1680
  }
@@ -101,17 +101,18 @@ class mcbp_session
101
101
  [[nodiscard]] mcbp_context context() const;
102
102
  [[nodiscard]] bool supports_feature(protocol::hello_feature feature);
103
103
  [[nodiscard]] std::vector<protocol::hello_feature> supported_features() const;
104
- //[[nodiscard]] const std::string& id() const;
105
- [[nodiscard]] std::string id() const;
104
+ [[nodiscard]] const std::string& id() const;
106
105
  [[nodiscard]] std::string remote_address() const;
107
106
  [[nodiscard]] std::string local_address() const;
107
+ [[nodiscard]] const std::string& bootstrap_address() const;
108
108
  [[nodiscard]] const std::string& bootstrap_hostname() const;
109
109
  [[nodiscard]] const std::string& bootstrap_port() const;
110
+ [[nodiscard]] std::uint16_t bootstrap_port_number() const;
110
111
  void write_and_subscribe(std::shared_ptr<mcbp::queue_request>, std::shared_ptr<response_handler> handler);
111
112
  void write_and_subscribe(std::uint32_t opaque, std::vector<std::byte>&& data, command_handler&& handler);
112
113
  void bootstrap(utils::movable_function<void(std::error_code, topology::configuration)>&& handler,
113
114
  bool retry_on_bucket_not_found = false);
114
- void on_stop(utils::movable_function<void(retry_reason)> handler);
115
+ void on_stop(utils::movable_function<void()> handler);
115
116
  void stop(retry_reason reason);
116
117
  [[nodiscard]] std::size_t index() const;
117
118
  [[nodiscard]] bool has_config() const;
@@ -127,7 +127,7 @@ custom_rotating_file_sink<Mutex>::add_hook(const std::string& hook)
127
127
 
128
128
  // Payload shouldn't contain anything yet, overwrite it
129
129
  Expects(msg.payload.size() == 0);
130
- msg.payload = hook;
130
+ msg.payload = hookToAdd;
131
131
 
132
132
  spdlog::memory_buf_t formatted;
133
133
  formatter->format(msg, formatted);