couchbase 3.0.0.alpha.2-universal-darwin-19 → 3.0.0.alpha.3-universal-darwin-19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.github/workflows/tests-dev-preview.yml +52 -0
 - data/.gitmodules +3 -0
 - data/.idea/vcs.xml +1 -0
 - data/.yardopts +1 -0
 - data/README.md +1 -1
 - data/Rakefile +5 -1
 - data/bin/init-cluster +13 -5
 - data/couchbase.gemspec +2 -1
 - data/examples/managing_query_indexes.rb +1 -1
 - data/examples/managing_search_indexes.rb +62 -0
 - data/examples/search.rb +187 -0
 - data/ext/.clang-tidy +1 -0
 - data/ext/build_version.hxx.in +1 -1
 - data/ext/couchbase/bucket.hxx +0 -40
 - data/ext/couchbase/couchbase.cxx +2578 -1368
 - data/ext/couchbase/io/http_session.hxx +27 -7
 - data/ext/couchbase/io/mcbp_parser.hxx +2 -0
 - data/ext/couchbase/io/mcbp_session.hxx +53 -24
 - data/ext/couchbase/io/session_manager.hxx +6 -1
 - data/ext/couchbase/operations.hxx +13 -0
 - data/ext/couchbase/operations/bucket_create.hxx +1 -0
 - data/ext/couchbase/operations/bucket_drop.hxx +1 -0
 - data/ext/couchbase/operations/bucket_flush.hxx +1 -0
 - data/ext/couchbase/operations/bucket_get.hxx +1 -0
 - data/ext/couchbase/operations/bucket_get_all.hxx +1 -0
 - data/ext/couchbase/operations/bucket_update.hxx +1 -0
 - data/ext/couchbase/operations/cluster_developer_preview_enable.hxx +1 -0
 - data/ext/couchbase/operations/collection_create.hxx +6 -1
 - data/ext/couchbase/operations/collection_drop.hxx +1 -0
 - data/ext/couchbase/operations/command.hxx +86 -11
 - data/ext/couchbase/operations/document_decrement.hxx +1 -0
 - data/ext/couchbase/operations/document_exists.hxx +1 -0
 - data/ext/couchbase/operations/document_get.hxx +1 -0
 - data/ext/couchbase/operations/document_get_and_lock.hxx +1 -0
 - data/ext/couchbase/operations/document_get_and_touch.hxx +1 -0
 - data/ext/couchbase/operations/document_get_projected.hxx +243 -0
 - data/ext/couchbase/operations/document_increment.hxx +4 -1
 - data/ext/couchbase/operations/document_insert.hxx +1 -0
 - data/ext/couchbase/operations/document_lookup_in.hxx +1 -0
 - data/ext/couchbase/operations/document_mutate_in.hxx +1 -0
 - data/ext/couchbase/operations/document_query.hxx +13 -2
 - data/ext/couchbase/operations/document_remove.hxx +1 -0
 - data/ext/couchbase/operations/document_replace.hxx +1 -0
 - data/ext/couchbase/operations/document_search.hxx +337 -0
 - data/ext/couchbase/operations/document_touch.hxx +1 -0
 - data/ext/couchbase/operations/document_unlock.hxx +1 -0
 - data/ext/couchbase/operations/document_upsert.hxx +1 -0
 - data/ext/couchbase/operations/query_index_build_deferred.hxx +1 -0
 - data/ext/couchbase/operations/query_index_create.hxx +1 -0
 - data/ext/couchbase/operations/query_index_drop.hxx +1 -0
 - data/ext/couchbase/operations/query_index_get_all.hxx +1 -0
 - data/ext/couchbase/operations/scope_create.hxx +1 -0
 - data/ext/couchbase/operations/scope_drop.hxx +1 -0
 - data/ext/couchbase/operations/scope_get_all.hxx +2 -0
 - data/ext/couchbase/operations/search_index.hxx +62 -0
 - data/ext/couchbase/operations/search_index_analyze_document.hxx +92 -0
 - data/ext/couchbase/operations/search_index_control_ingest.hxx +78 -0
 - data/ext/couchbase/operations/search_index_control_plan_freeze.hxx +80 -0
 - data/ext/couchbase/operations/search_index_control_query.hxx +80 -0
 - data/ext/couchbase/operations/search_index_drop.hxx +77 -0
 - data/ext/couchbase/operations/search_index_get.hxx +80 -0
 - data/ext/couchbase/operations/search_index_get_all.hxx +82 -0
 - data/ext/couchbase/operations/search_index_get_documents_count.hxx +81 -0
 - data/ext/couchbase/operations/search_index_upsert.hxx +106 -0
 - data/ext/couchbase/protocol/client_opcode.hxx +10 -0
 - data/ext/couchbase/protocol/cmd_get_collection_id.hxx +117 -0
 - data/ext/couchbase/timeout_defaults.hxx +32 -0
 - data/ext/couchbase/version.hxx +1 -1
 - data/ext/test/main.cxx +5 -5
 - data/lib/couchbase/binary_collection.rb +16 -12
 - data/lib/couchbase/binary_collection_options.rb +4 -0
 - data/lib/couchbase/cluster.rb +88 -8
 - data/lib/couchbase/collection.rb +39 -15
 - data/lib/couchbase/collection_options.rb +19 -2
 - data/lib/couchbase/json_transcoder.rb +2 -2
 - data/lib/couchbase/management/bucket_manager.rb +37 -23
 - data/lib/couchbase/management/collection_manager.rb +15 -6
 - data/lib/couchbase/management/query_index_manager.rb +16 -6
 - data/lib/couchbase/management/search_index_manager.rb +61 -14
 - data/lib/couchbase/search_options.rb +1492 -0
 - data/lib/couchbase/version.rb +1 -1
 - metadata +22 -2
 
| 
         @@ -33,6 +33,7 @@ 
     | 
|
| 
       33 
33 
     | 
    
         
             
            #include <io/http_parser.hxx>
         
     | 
| 
       34 
34 
     | 
    
         
             
            #include <io/http_message.hxx>
         
     | 
| 
       35 
35 
     | 
    
         
             
            #include <platform/base64.h>
         
     | 
| 
      
 36 
     | 
    
         
            +
            #include <timeout_defaults.hxx>
         
     | 
| 
       36 
37 
     | 
    
         | 
| 
       37 
38 
     | 
    
         
             
            namespace couchbase::io
         
     | 
| 
       38 
39 
     | 
    
         
             
            {
         
     | 
| 
         @@ -73,9 +74,14 @@ class http_session : public std::enable_shared_from_this<http_session> 
     | 
|
| 
       73 
74 
     | 
    
         
             
                    stop();
         
     | 
| 
       74 
75 
     | 
    
         
             
                }
         
     | 
| 
       75 
76 
     | 
    
         | 
| 
       76 
     | 
    
         
            -
                [[nodiscard]]  
     | 
| 
      
 77 
     | 
    
         
            +
                [[nodiscard]] uuid::uuid_t id()
         
     | 
| 
       77 
78 
     | 
    
         
             
                {
         
     | 
| 
       78 
     | 
    
         
            -
                    return  
     | 
| 
      
 79 
     | 
    
         
            +
                    return id_;
         
     | 
| 
      
 80 
     | 
    
         
            +
                }
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                void on_stop(std::function<void()> handler)
         
     | 
| 
      
 83 
     | 
    
         
            +
                {
         
     | 
| 
      
 84 
     | 
    
         
            +
                    on_stop_handler_ = std::move(handler);
         
     | 
| 
       79 
85 
     | 
    
         
             
                }
         
     | 
| 
       80 
86 
     | 
    
         | 
| 
       81 
87 
     | 
    
         
             
                void stop()
         
     | 
| 
         @@ -85,6 +91,16 @@ class http_session : public std::enable_shared_from_this<http_session> 
     | 
|
| 
       85 
91 
     | 
    
         
             
                        socket_.close();
         
     | 
| 
       86 
92 
     | 
    
         
             
                    }
         
     | 
| 
       87 
93 
     | 
    
         
             
                    deadline_timer_.cancel();
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                    for (auto& handler : command_handlers_) {
         
     | 
| 
      
 96 
     | 
    
         
            +
                        handler(std::make_error_code(error::common_errc::ambiguous_timeout), {});
         
     | 
| 
      
 97 
     | 
    
         
            +
                    }
         
     | 
| 
      
 98 
     | 
    
         
            +
                    command_handlers_.clear();
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                    if (on_stop_handler_) {
         
     | 
| 
      
 101 
     | 
    
         
            +
                        on_stop_handler_();
         
     | 
| 
      
 102 
     | 
    
         
            +
                        on_stop_handler_ = nullptr;
         
     | 
| 
      
 103 
     | 
    
         
            +
                    }
         
     | 
| 
       88 
104 
     | 
    
         
             
                }
         
     | 
| 
       89 
105 
     | 
    
         | 
| 
       90 
106 
     | 
    
         
             
                bool is_stopped()
         
     | 
| 
         @@ -105,7 +121,7 @@ class http_session : public std::enable_shared_from_this<http_session> 
     | 
|
| 
       105 
121 
     | 
    
         
             
                    if (stopped_) {
         
     | 
| 
       106 
122 
     | 
    
         
             
                        return;
         
     | 
| 
       107 
123 
     | 
    
         
             
                    }
         
     | 
| 
       108 
     | 
    
         
            -
                    output_buffer_.emplace_back(buf.begin(), buf.end());
         
     | 
| 
      
 124 
     | 
    
         
            +
                    output_buffer_.emplace_back(std::vector<uint8_t>{ buf.begin(), buf.end() });
         
     | 
| 
       109 
125 
     | 
    
         
             
                }
         
     | 
| 
       110 
126 
     | 
    
         | 
| 
       111 
127 
     | 
    
         
             
                void flush()
         
     | 
| 
         @@ -155,7 +171,7 @@ class http_session : public std::enable_shared_from_this<http_session> 
     | 
|
| 
       155 
171 
     | 
    
         
             
                {
         
     | 
| 
       156 
172 
     | 
    
         
             
                    if (it != endpoints_.end()) {
         
     | 
| 
       157 
173 
     | 
    
         
             
                        spdlog::trace("connecting to {}:{}", it->endpoint().address().to_string(), it->endpoint().port());
         
     | 
| 
       158 
     | 
    
         
            -
                        deadline_timer_.expires_after( 
     | 
| 
      
 174 
     | 
    
         
            +
                        deadline_timer_.expires_after(timeout_defaults::connect_timeout);
         
     | 
| 
       159 
175 
     | 
    
         
             
                        socket_.async_connect(it->endpoint(), std::bind(&http_session::on_connect, this, std::placeholders::_1, it));
         
     | 
| 
       160 
176 
     | 
    
         
             
                    } else {
         
     | 
| 
       161 
177 
     | 
    
         
             
                        spdlog::error("no more endpoints left to connect");
         
     | 
| 
         @@ -213,9 +229,11 @@ class http_session : public std::enable_shared_from_this<http_session> 
     | 
|
| 
       213 
229 
     | 
    
         
             
                          switch (self->parser_.feed(reinterpret_cast<const char*>(self->input_buffer_.data()), bytes_transferred)) {
         
     | 
| 
       214 
230 
     | 
    
         
             
                              case http_parser::status::ok:
         
     | 
| 
       215 
231 
     | 
    
         
             
                                  if (self->parser_.complete) {
         
     | 
| 
       216 
     | 
    
         
            -
                                       
     | 
| 
       217 
     | 
    
         
            -
             
     | 
| 
       218 
     | 
    
         
            -
             
     | 
| 
      
 232 
     | 
    
         
            +
                                      if (!self->command_handlers_.empty()) {
         
     | 
| 
      
 233 
     | 
    
         
            +
                                          auto handler = self->command_handlers_.front();
         
     | 
| 
      
 234 
     | 
    
         
            +
                                          self->command_handlers_.pop_front();
         
     | 
| 
      
 235 
     | 
    
         
            +
                                          handler({}, std::move(self->parser_.response));
         
     | 
| 
      
 236 
     | 
    
         
            +
                                      }
         
     | 
| 
       219 
237 
     | 
    
         
             
                                      self->parser_.reset();
         
     | 
| 
       220 
238 
     | 
    
         
             
                                      return;
         
     | 
| 
       221 
239 
     | 
    
         
             
                                  }
         
     | 
| 
         @@ -273,6 +291,8 @@ class http_session : public std::enable_shared_from_this<http_session> 
     | 
|
| 
       273 
291 
     | 
    
         
             
                bool stopped_{ false };
         
     | 
| 
       274 
292 
     | 
    
         
             
                bool connected_{ false };
         
     | 
| 
       275 
293 
     | 
    
         | 
| 
      
 294 
     | 
    
         
            +
                std::function<void()> on_stop_handler_{ nullptr };
         
     | 
| 
      
 295 
     | 
    
         
            +
             
     | 
| 
       276 
296 
     | 
    
         
             
                std::list<std::function<void(std::error_code, io::http_response&&)>> command_handlers_{};
         
     | 
| 
       277 
297 
     | 
    
         
             
                http_parser parser_{};
         
     | 
| 
       278 
298 
     | 
    
         
             
                std::array<std::uint8_t, 16384> input_buffer_{};
         
     | 
| 
         @@ -73,6 +73,8 @@ struct mcbp_parser { 
     | 
|
| 
       73 
73 
     | 
    
         
             
                        if (success) {
         
     | 
| 
       74 
74 
     | 
    
         
             
                            std::copy(uncompressed.begin(), uncompressed.end(), std::back_inserter(msg.body));
         
     | 
| 
       75 
75 
     | 
    
         
             
                            use_raw_value = false;
         
     | 
| 
      
 76 
     | 
    
         
            +
                            // patch header with new body size
         
     | 
| 
      
 77 
     | 
    
         
            +
                            msg.header.bodylen = htonl(static_cast<std::uint32_t>(prefix_size + uncompressed.size()));
         
     | 
| 
       76 
78 
     | 
    
         
             
                        }
         
     | 
| 
       77 
79 
     | 
    
         
             
                    }
         
     | 
| 
       78 
80 
     | 
    
         
             
                    if (use_raw_value) {
         
     | 
| 
         @@ -28,6 +28,8 @@ 
     | 
|
| 
       28 
28 
     | 
    
         
             
            #include <io/mcbp_message.hxx>
         
     | 
| 
       29 
29 
     | 
    
         
             
            #include <io/mcbp_parser.hxx>
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
      
 31 
     | 
    
         
            +
            #include <timeout_defaults.hxx>
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
       31 
33 
     | 
    
         
             
            #include <protocol/hello_feature.hxx>
         
     | 
| 
       32 
34 
     | 
    
         
             
            #include <protocol/client_request.hxx>
         
     | 
| 
       33 
35 
     | 
    
         
             
            #include <protocol/client_response.hxx>
         
     | 
| 
         @@ -39,7 +41,6 @@ 
     | 
|
| 
       39 
41 
     | 
    
         
             
            #include <protocol/cmd_select_bucket.hxx>
         
     | 
| 
       40 
42 
     | 
    
         
             
            #include <protocol/cmd_get_cluster_config.hxx>
         
     | 
| 
       41 
43 
     | 
    
         
             
            #include <protocol/cmd_get_error_map.hxx>
         
     | 
| 
       42 
     | 
    
         
            -
            #include <protocol/cmd_get_collections_manifest.hxx>
         
     | 
| 
       43 
44 
     | 
    
         
             
            #include <protocol/cmd_get.hxx>
         
     | 
| 
       44 
45 
     | 
    
         
             
            #include <protocol/cmd_cluster_map_change_notification.hxx>
         
     | 
| 
       45 
46 
     | 
    
         | 
| 
         @@ -55,6 +56,35 @@ namespace couchbase::io 
     | 
|
| 
       55 
56 
     | 
    
         | 
| 
       56 
57 
     | 
    
         
             
            class mcbp_session : public std::enable_shared_from_this<mcbp_session>
         
     | 
| 
       57 
58 
     | 
    
         
             
            {
         
     | 
| 
      
 59 
     | 
    
         
            +
                class collection_cache
         
     | 
| 
      
 60 
     | 
    
         
            +
                {
         
     | 
| 
      
 61 
     | 
    
         
            +
                  private:
         
     | 
| 
      
 62 
     | 
    
         
            +
                    std::map<std::string, std::uint32_t> cid_map_{ { "_default._default", 0 } };
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                  public:
         
     | 
| 
      
 65 
     | 
    
         
            +
                    [[nodiscard]] std::optional<std::uint32_t> get(const std::string& path)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    {
         
     | 
| 
      
 67 
     | 
    
         
            +
                        Expects(!path.empty());
         
     | 
| 
      
 68 
     | 
    
         
            +
                        auto ptr = cid_map_.find(path);
         
     | 
| 
      
 69 
     | 
    
         
            +
                        if (ptr != cid_map_.end()) {
         
     | 
| 
      
 70 
     | 
    
         
            +
                            return ptr->second;
         
     | 
| 
      
 71 
     | 
    
         
            +
                        }
         
     | 
| 
      
 72 
     | 
    
         
            +
                        return {};
         
     | 
| 
      
 73 
     | 
    
         
            +
                    }
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                    void update(const std::string& path, std::uint32_t id)
         
     | 
| 
      
 76 
     | 
    
         
            +
                    {
         
     | 
| 
      
 77 
     | 
    
         
            +
                        Expects(!path.empty());
         
     | 
| 
      
 78 
     | 
    
         
            +
                        cid_map_[path] = id;
         
     | 
| 
      
 79 
     | 
    
         
            +
                    }
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                    void reset()
         
     | 
| 
      
 82 
     | 
    
         
            +
                    {
         
     | 
| 
      
 83 
     | 
    
         
            +
                        cid_map_.clear();
         
     | 
| 
      
 84 
     | 
    
         
            +
                        cid_map_["_default._default"] = 0;
         
     | 
| 
      
 85 
     | 
    
         
            +
                    }
         
     | 
| 
      
 86 
     | 
    
         
            +
                };
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
       58 
88 
     | 
    
         
             
                class message_handler
         
     | 
| 
       59 
89 
     | 
    
         
             
                {
         
     | 
| 
       60 
90 
     | 
    
         
             
                  public:
         
     | 
| 
         @@ -138,10 +168,6 @@ class mcbp_session : public std::enable_shared_from_this<mcbp_session> 
     | 
|
| 
       138 
168 
     | 
    
         
             
                            sb_req.opaque(session_->next_opaque());
         
     | 
| 
       139 
169 
     | 
    
         
             
                            sb_req.body().bucket_name(session_->bucket_name_.value());
         
     | 
| 
       140 
170 
     | 
    
         
             
                            session_->write(sb_req.data());
         
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
                            protocol::client_request<protocol::get_collections_manifest_request_body> gcm_req;
         
     | 
| 
       143 
     | 
    
         
            -
                            gcm_req.opaque(session_->next_opaque());
         
     | 
| 
       144 
     | 
    
         
            -
                            session_->write(gcm_req.data());
         
     | 
| 
       145 
171 
     | 
    
         
             
                        }
         
     | 
| 
       146 
172 
     | 
    
         
             
                        protocol::client_request<protocol::get_cluster_config_request_body> cfg_req;
         
     | 
| 
       147 
173 
     | 
    
         
             
                        cfg_req.opaque(session_->next_opaque());
         
     | 
| 
         @@ -216,21 +242,6 @@ class mcbp_session : public std::enable_shared_from_this<mcbp_session> 
     | 
|
| 
       216 
242 
     | 
    
         
             
                                    return complete(std::make_error_code(error::network_errc::protocol_error));
         
     | 
| 
       217 
243 
     | 
    
         
             
                                }
         
     | 
| 
       218 
244 
     | 
    
         
             
                            } break;
         
     | 
| 
       219 
     | 
    
         
            -
                            case protocol::client_opcode::get_collections_manifest: {
         
     | 
| 
       220 
     | 
    
         
            -
                                protocol::client_response<protocol::get_collections_manifest_response_body> resp(msg);
         
     | 
| 
       221 
     | 
    
         
            -
                                if (resp.status() == protocol::status::success) {
         
     | 
| 
       222 
     | 
    
         
            -
                                    session_->manifest_.emplace(resp.body().manifest());
         
     | 
| 
       223 
     | 
    
         
            -
                                    spdlog::trace(
         
     | 
| 
       224 
     | 
    
         
            -
                                      "collections manifest for bucket \"{}\": {}", session_->bucket_name_.value_or(""), *session_->manifest_);
         
     | 
| 
       225 
     | 
    
         
            -
                                } else if (resp.status() == protocol::status::no_collections_manifest) {
         
     | 
| 
       226 
     | 
    
         
            -
                                    spdlog::trace("collection manifest is not available for bucket \"{}\": {}",
         
     | 
| 
       227 
     | 
    
         
            -
                                                  session_->bucket_name_.value_or(""),
         
     | 
| 
       228 
     | 
    
         
            -
                                                  resp.error_message());
         
     | 
| 
       229 
     | 
    
         
            -
                                } else {
         
     | 
| 
       230 
     | 
    
         
            -
                                    spdlog::warn("unexpected message status during bootstrap: {} (opcode={})", resp.error_message(), opcode);
         
     | 
| 
       231 
     | 
    
         
            -
                                    return complete(std::make_error_code(error::network_errc::protocol_error));
         
     | 
| 
       232 
     | 
    
         
            -
                                }
         
     | 
| 
       233 
     | 
    
         
            -
                            } break;
         
     | 
| 
       234 
245 
     | 
    
         
             
                            case protocol::client_opcode::select_bucket: {
         
     | 
| 
       235 
246 
     | 
    
         
             
                                protocol::client_response<protocol::select_bucket_response_body> resp(msg);
         
     | 
| 
       236 
247 
     | 
    
         
             
                                if (resp.status() == protocol::status::success) {
         
     | 
| 
         @@ -320,6 +331,7 @@ class mcbp_session : public std::enable_shared_from_this<mcbp_session> 
     | 
|
| 
       320 
331 
     | 
    
         
             
                                            spdlog::warn("unexpected message status: {}", resp.error_message());
         
     | 
| 
       321 
332 
     | 
    
         
             
                                        }
         
     | 
| 
       322 
333 
     | 
    
         
             
                                    } break;
         
     | 
| 
      
 334 
     | 
    
         
            +
                                    case protocol::client_opcode::get_collection_id:
         
     | 
| 
       323 
335 
     | 
    
         
             
                                    case protocol::client_opcode::get:
         
     | 
| 
       324 
336 
     | 
    
         
             
                                    case protocol::client_opcode::get_and_lock:
         
     | 
| 
       325 
337 
     | 
    
         
             
                                    case protocol::client_opcode::get_and_touch:
         
     | 
| 
         @@ -481,9 +493,16 @@ class mcbp_session : public std::enable_shared_from_this<mcbp_session> 
     | 
|
| 
       481 
493 
     | 
    
         
             
                    }
         
     | 
| 
       482 
494 
     | 
    
         
             
                }
         
     | 
| 
       483 
495 
     | 
    
         | 
| 
       484 
     | 
    
         
            -
                 
     | 
| 
      
 496 
     | 
    
         
            +
                void cancel(uint32_t opaque, std::error_code ec)
         
     | 
| 
       485 
497 
     | 
    
         
             
                {
         
     | 
| 
       486 
     | 
    
         
            -
                     
     | 
| 
      
 498 
     | 
    
         
            +
                    if (stopped_) {
         
     | 
| 
      
 499 
     | 
    
         
            +
                        return;
         
     | 
| 
      
 500 
     | 
    
         
            +
                    }
         
     | 
| 
      
 501 
     | 
    
         
            +
                    auto handler = command_handlers_.find(opaque);
         
     | 
| 
      
 502 
     | 
    
         
            +
                    if (handler != command_handlers_.end()) {
         
     | 
| 
      
 503 
     | 
    
         
            +
                        handler->second(ec, {});
         
     | 
| 
      
 504 
     | 
    
         
            +
                        command_handlers_.erase(handler);
         
     | 
| 
      
 505 
     | 
    
         
            +
                    }
         
     | 
| 
       487 
506 
     | 
    
         
             
                }
         
     | 
| 
       488 
507 
     | 
    
         | 
| 
       489 
508 
     | 
    
         
             
                bool supports_feature(protocol::hello_feature feature)
         
     | 
| 
         @@ -663,6 +682,16 @@ class mcbp_session : public std::enable_shared_from_this<mcbp_session> 
     | 
|
| 
       663 
682 
     | 
    
         
             
                    }
         
     | 
| 
       664 
683 
     | 
    
         
             
                }
         
     | 
| 
       665 
684 
     | 
    
         | 
| 
      
 685 
     | 
    
         
            +
                std::optional<std::uint32_t> get_collection_uid(const std::string& collection_path)
         
     | 
| 
      
 686 
     | 
    
         
            +
                {
         
     | 
| 
      
 687 
     | 
    
         
            +
                    return collection_cache_.get(collection_path);
         
     | 
| 
      
 688 
     | 
    
         
            +
                }
         
     | 
| 
      
 689 
     | 
    
         
            +
             
     | 
| 
      
 690 
     | 
    
         
            +
                void update_collection_uid(const std::string& path, std::uint32_t uid)
         
     | 
| 
      
 691 
     | 
    
         
            +
                {
         
     | 
| 
      
 692 
     | 
    
         
            +
                    collection_cache_.update(path, uid);
         
     | 
| 
      
 693 
     | 
    
         
            +
                }
         
     | 
| 
      
 694 
     | 
    
         
            +
             
     | 
| 
       666 
695 
     | 
    
         
             
              private:
         
     | 
| 
       667 
696 
     | 
    
         
             
                void invoke_bootstrap_handler(std::error_code ec)
         
     | 
| 
       668 
697 
     | 
    
         
             
                {
         
     | 
| 
         @@ -704,7 +733,7 @@ class mcbp_session : public std::enable_shared_from_this<mcbp_session> 
     | 
|
| 
       704 
733 
     | 
    
         
             
                    }
         
     | 
| 
       705 
734 
     | 
    
         
             
                    if (it != endpoints_.end()) {
         
     | 
| 
       706 
735 
     | 
    
         
             
                        spdlog::trace("connecting to {}:{}", it->endpoint().address().to_string(), it->endpoint().port());
         
     | 
| 
       707 
     | 
    
         
            -
                        deadline_timer_.expires_after( 
     | 
| 
      
 736 
     | 
    
         
            +
                        deadline_timer_.expires_after(timeout_defaults::connect_timeout);
         
     | 
| 
       708 
737 
     | 
    
         
             
                        socket_.async_connect(it->endpoint(), std::bind(&mcbp_session::on_connect, this, std::placeholders::_1, it));
         
     | 
| 
       709 
738 
     | 
    
         
             
                    } else {
         
     | 
| 
       710 
739 
     | 
    
         
             
                        spdlog::error("no more endpoints left to connect");
         
     | 
| 
         @@ -852,7 +881,7 @@ class mcbp_session : public std::enable_shared_from_this<mcbp_session> 
     | 
|
| 
       852 
881 
     | 
    
         
             
                std::vector<protocol::hello_feature> supported_features_;
         
     | 
| 
       853 
882 
     | 
    
         
             
                std::optional<configuration> config_;
         
     | 
| 
       854 
883 
     | 
    
         
             
                std::optional<error_map> errmap_;
         
     | 
| 
       855 
     | 
    
         
            -
                 
     | 
| 
      
 884 
     | 
    
         
            +
                collection_cache collection_cache_;
         
     | 
| 
       856 
885 
     | 
    
         | 
| 
       857 
886 
     | 
    
         
             
                std::atomic_bool reading_{ false };
         
     | 
| 
       858 
887 
     | 
    
         
             
            };
         
     | 
| 
         @@ -25,7 +25,7 @@ 
     | 
|
| 
       25 
25 
     | 
    
         
             
            namespace couchbase::io
         
     | 
| 
       26 
26 
     | 
    
         
             
            {
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
            class session_manager
         
     | 
| 
      
 28 
     | 
    
         
            +
            class session_manager : public std::enable_shared_from_this<session_manager>
         
     | 
| 
       29 
29 
     | 
    
         
             
            {
         
     | 
| 
       30 
30 
     | 
    
         
             
              public:
         
     | 
| 
       31 
31 
     | 
    
         
             
                session_manager(uuid::uuid_t client_id, asio::io_context& ctx)
         
     | 
| 
         @@ -57,11 +57,16 @@ class session_manager 
     | 
|
| 
       57 
57 
     | 
    
         
             
                        }
         
     | 
| 
       58 
58 
     | 
    
         
             
                        config_.nodes.size();
         
     | 
| 
       59 
59 
     | 
    
         
             
                        auto session = std::make_shared<http_session>(client_id_, ctx_, username, password, hostname, std::to_string(port));
         
     | 
| 
      
 60 
     | 
    
         
            +
                        session->on_stop([type, id = session->id(), self = this->shared_from_this()]() {
         
     | 
| 
      
 61 
     | 
    
         
            +
                            self->busy_sessions_[type].remove_if([id](const auto& s) -> bool { return s->id() == id; });
         
     | 
| 
      
 62 
     | 
    
         
            +
                            self->idle_sessions_[type].remove_if([id](const auto& s) -> bool { return s->id() == id; });
         
     | 
| 
      
 63 
     | 
    
         
            +
                        });
         
     | 
| 
       60 
64 
     | 
    
         
             
                        busy_sessions_[type].push_back(session);
         
     | 
| 
       61 
65 
     | 
    
         
             
                        return session;
         
     | 
| 
       62 
66 
     | 
    
         
             
                    }
         
     | 
| 
       63 
67 
     | 
    
         
             
                    auto session = idle_sessions_[type].front();
         
     | 
| 
       64 
68 
     | 
    
         
             
                    idle_sessions_[type].pop_front();
         
     | 
| 
      
 69 
     | 
    
         
            +
                    busy_sessions_[type].push_back(session);
         
     | 
| 
       65 
70 
     | 
    
         
             
                    return session;
         
     | 
| 
       66 
71 
     | 
    
         
             
                }
         
     | 
| 
       67 
72 
     | 
    
         | 
| 
         @@ -18,6 +18,7 @@ 
     | 
|
| 
       18 
18 
     | 
    
         
             
            #pragma once
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
            #include <document_id.hxx>
         
     | 
| 
      
 21 
     | 
    
         
            +
            #include <timeout_defaults.hxx>
         
     | 
| 
       21 
22 
     | 
    
         | 
| 
       22 
23 
     | 
    
         
             
            #include <operations/document_get.hxx>
         
     | 
| 
       23 
24 
     | 
    
         
             
            #include <operations/document_get_and_lock.hxx>
         
     | 
| 
         @@ -33,8 +34,10 @@ 
     | 
|
| 
       33 
34 
     | 
    
         
             
            #include <operations/document_unlock.hxx>
         
     | 
| 
       34 
35 
     | 
    
         
             
            #include <operations/document_increment.hxx>
         
     | 
| 
       35 
36 
     | 
    
         
             
            #include <operations/document_decrement.hxx>
         
     | 
| 
      
 37 
     | 
    
         
            +
            #include <operations/document_get_projected.hxx>
         
     | 
| 
       36 
38 
     | 
    
         | 
| 
       37 
39 
     | 
    
         
             
            #include <operations/document_query.hxx>
         
     | 
| 
      
 40 
     | 
    
         
            +
            #include <operations/document_search.hxx>
         
     | 
| 
       38 
41 
     | 
    
         | 
| 
       39 
42 
     | 
    
         
             
            #include <operations/bucket_get_all.hxx>
         
     | 
| 
       40 
43 
     | 
    
         
             
            #include <operations/bucket_get.hxx>
         
     | 
| 
         @@ -56,4 +59,14 @@ 
     | 
|
| 
       56 
59 
     | 
    
         
             
            #include <operations/query_index_create.hxx>
         
     | 
| 
       57 
60 
     | 
    
         
             
            #include <operations/query_index_build_deferred.hxx>
         
     | 
| 
       58 
61 
     | 
    
         | 
| 
      
 62 
     | 
    
         
            +
            #include <operations/search_index_get_all.hxx>
         
     | 
| 
      
 63 
     | 
    
         
            +
            #include <operations/search_index_get.hxx>
         
     | 
| 
      
 64 
     | 
    
         
            +
            #include <operations/search_index_get_documents_count.hxx>
         
     | 
| 
      
 65 
     | 
    
         
            +
            #include <operations/search_index_upsert.hxx>
         
     | 
| 
      
 66 
     | 
    
         
            +
            #include <operations/search_index_drop.hxx>
         
     | 
| 
      
 67 
     | 
    
         
            +
            #include <operations/search_index_control_ingest.hxx>
         
     | 
| 
      
 68 
     | 
    
         
            +
            #include <operations/search_index_control_query.hxx>
         
     | 
| 
      
 69 
     | 
    
         
            +
            #include <operations/search_index_control_plan_freeze.hxx>
         
     | 
| 
      
 70 
     | 
    
         
            +
            #include <operations/search_index_analyze_document.hxx>
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
       59 
72 
     | 
    
         
             
            #include <operations/command.hxx>
         
     | 
| 
         @@ -39,6 +39,7 @@ struct bucket_create_request { 
     | 
|
| 
       39 
39 
     | 
    
         
             
                static const inline service_type type = service_type::management;
         
     | 
| 
       40 
40 
     | 
    
         | 
| 
       41 
41 
     | 
    
         
             
                bucket_settings bucket{};
         
     | 
| 
      
 42 
     | 
    
         
            +
                std::chrono::milliseconds timeout{ timeout_defaults::management_timeout };
         
     | 
| 
       42 
43 
     | 
    
         | 
| 
       43 
44 
     | 
    
         
             
                void encode_to(encoded_request_type& encoded)
         
     | 
| 
       44 
45 
     | 
    
         
             
                {
         
     | 
| 
         @@ -36,6 +36,7 @@ struct bucket_get_all_request { 
     | 
|
| 
       36 
36 
     | 
    
         
             
                using encoded_response_type = io::http_response;
         
     | 
| 
       37 
37 
     | 
    
         | 
| 
       38 
38 
     | 
    
         
             
                static const inline service_type type = service_type::management;
         
     | 
| 
      
 39 
     | 
    
         
            +
                std::chrono::milliseconds timeout{ timeout_defaults::management_timeout };
         
     | 
| 
       39 
40 
     | 
    
         | 
| 
       40 
41 
     | 
    
         
             
                void encode_to(encoded_request_type& encoded)
         
     | 
| 
       41 
42 
     | 
    
         
             
                {
         
     | 
| 
         @@ -38,6 +38,7 @@ struct bucket_update_request { 
     | 
|
| 
       38 
38 
     | 
    
         
             
                using encoded_response_type = io::http_response;
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
40 
     | 
    
         
             
                static const inline service_type type = service_type::management;
         
     | 
| 
      
 41 
     | 
    
         
            +
                std::chrono::milliseconds timeout{ timeout_defaults::management_timeout };
         
     | 
| 
       41 
42 
     | 
    
         | 
| 
       42 
43 
     | 
    
         
             
                bucket_settings bucket{};
         
     | 
| 
       43 
44 
     | 
    
         | 
| 
         @@ -35,6 +35,7 @@ struct cluster_developer_preview_enable_request { 
     | 
|
| 
       35 
35 
     | 
    
         
             
                using encoded_response_type = io::http_response;
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
                static const inline service_type type = service_type::management;
         
     | 
| 
      
 38 
     | 
    
         
            +
                std::chrono::milliseconds timeout{ timeout_defaults::management_timeout };
         
     | 
| 
       38 
39 
     | 
    
         | 
| 
       39 
40 
     | 
    
         
             
                void encode_to(encoded_request_type& encoded)
         
     | 
| 
       40 
41 
     | 
    
         
             
                {
         
     | 
| 
         @@ -42,6 +42,7 @@ struct collection_create_request { 
     | 
|
| 
       42 
42 
     | 
    
         
             
                std::string scope_name;
         
     | 
| 
       43 
43 
     | 
    
         
             
                std::string collection_name;
         
     | 
| 
       44 
44 
     | 
    
         
             
                std::uint32_t max_expiry{ 0 };
         
     | 
| 
      
 45 
     | 
    
         
            +
                std::chrono::milliseconds timeout{ timeout_defaults::management_timeout };
         
     | 
| 
       45 
46 
     | 
    
         | 
| 
       46 
47 
     | 
    
         
             
                void encode_to(encoded_request_type& encoded)
         
     | 
| 
       47 
48 
     | 
    
         
             
                {
         
     | 
| 
         @@ -62,7 +63,11 @@ make_response(std::error_code ec, collection_create_request&, collection_create_ 
     | 
|
| 
       62 
63 
     | 
    
         
             
                if (!ec) {
         
     | 
| 
       63 
64 
     | 
    
         
             
                    switch (encoded.status_code) {
         
     | 
| 
       64 
65 
     | 
    
         
             
                        case 400:
         
     | 
| 
       65 
     | 
    
         
            -
                             
     | 
| 
      
 66 
     | 
    
         
            +
                            if (encoded.body.find("Collection with this name already exists") != std::string::npos) {
         
     | 
| 
      
 67 
     | 
    
         
            +
                                response.ec = std::make_error_code(error::management_errc::collection_exists);
         
     | 
| 
      
 68 
     | 
    
         
            +
                            } else {
         
     | 
| 
      
 69 
     | 
    
         
            +
                                response.ec = std::make_error_code(error::common_errc::invalid_argument);
         
     | 
| 
      
 70 
     | 
    
         
            +
                            }
         
     | 
| 
       66 
71 
     | 
    
         
             
                            break;
         
     | 
| 
       67 
72 
     | 
    
         
             
                        case 404:
         
     | 
| 
       68 
73 
     | 
    
         
             
                            if (encoded.body.find("Scope with this name is not found") != std::string::npos) {
         
     | 
| 
         @@ -19,6 +19,7 @@ 
     | 
|
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
            #include <io/mcbp_session.hxx>
         
     | 
| 
       21 
21 
     | 
    
         
             
            #include <io/http_session.hxx>
         
     | 
| 
      
 22 
     | 
    
         
            +
            #include <protocol/cmd_get_collection_id.hxx>
         
     | 
| 
       22 
23 
     | 
    
         | 
| 
       23 
24 
     | 
    
         
             
            namespace couchbase::operations
         
     | 
| 
       24 
25 
     | 
    
         
             
            {
         
     | 
| 
         @@ -28,30 +29,103 @@ struct command : public std::enable_shared_from_this<command<Request>> { 
     | 
|
| 
       28 
29 
     | 
    
         
             
                using encoded_request_type = typename Request::encoded_request_type;
         
     | 
| 
       29 
30 
     | 
    
         
             
                using encoded_response_type = typename Request::encoded_response_type;
         
     | 
| 
       30 
31 
     | 
    
         
             
                asio::steady_timer deadline;
         
     | 
| 
      
 32 
     | 
    
         
            +
                asio::steady_timer retry_backoff;
         
     | 
| 
       31 
33 
     | 
    
         
             
                Request request;
         
     | 
| 
       32 
34 
     | 
    
         
             
                encoded_request_type encoded;
         
     | 
| 
       33 
35 
     | 
    
         | 
| 
       34 
36 
     | 
    
         
             
                command(asio::io_context& ctx, Request&& req)
         
     | 
| 
       35 
37 
     | 
    
         
             
                  : deadline(ctx)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  , retry_backoff(ctx)
         
     | 
| 
       36 
39 
     | 
    
         
             
                  , request(req)
         
     | 
| 
       37 
40 
     | 
    
         
             
                {
         
     | 
| 
       38 
41 
     | 
    
         
             
                }
         
     | 
| 
       39 
42 
     | 
    
         | 
| 
      
 43 
     | 
    
         
            +
                template<typename Handler>
         
     | 
| 
      
 44 
     | 
    
         
            +
                void request_collection_id(std::shared_ptr<io::mcbp_session> session, Handler&& handler)
         
     | 
| 
      
 45 
     | 
    
         
            +
                {
         
     | 
| 
      
 46 
     | 
    
         
            +
                    protocol::client_request<protocol::get_collection_id_request_body> req;
         
     | 
| 
      
 47 
     | 
    
         
            +
                    req.opaque(session->next_opaque());
         
     | 
| 
      
 48 
     | 
    
         
            +
                    req.body().collection_path(request.id.collection);
         
     | 
| 
      
 49 
     | 
    
         
            +
                    session->write_and_subscribe(req.opaque(),
         
     | 
| 
      
 50 
     | 
    
         
            +
                                                 req.data(session->supports_feature(protocol::hello_feature::snappy)),
         
     | 
| 
      
 51 
     | 
    
         
            +
                                                 [self = this->shared_from_this(), session, handler = std::forward<Handler>(handler)](
         
     | 
| 
      
 52 
     | 
    
         
            +
                                                   std::error_code ec, io::mcbp_message&& msg) mutable {
         
     | 
| 
      
 53 
     | 
    
         
            +
                                                     if (ec == std::make_error_code(error::common_errc::collection_not_found)) {
         
     | 
| 
      
 54 
     | 
    
         
            +
                                                         if (self->request.id.collection_uid) {
         
     | 
| 
      
 55 
     | 
    
         
            +
                                                             return self->handle_unknown_collection(session, std::forward<Handler>(handler));
         
     | 
| 
      
 56 
     | 
    
         
            +
                                                         }
         
     | 
| 
      
 57 
     | 
    
         
            +
                                                         return handler(make_response(ec, self->request, {}));
         
     | 
| 
      
 58 
     | 
    
         
            +
                                                     }
         
     | 
| 
      
 59 
     | 
    
         
            +
                                                     if (ec) {
         
     | 
| 
      
 60 
     | 
    
         
            +
                                                         return handler(make_response(ec, self->request, {}));
         
     | 
| 
      
 61 
     | 
    
         
            +
                                                     }
         
     | 
| 
      
 62 
     | 
    
         
            +
                                                     protocol::client_response<protocol::get_collection_id_response_body> resp(msg);
         
     | 
| 
      
 63 
     | 
    
         
            +
                                                     session->update_collection_uid(self->request.id.collection, resp.body().collection_uid());
         
     | 
| 
      
 64 
     | 
    
         
            +
                                                     self->request.id.collection_uid = resp.body().collection_uid();
         
     | 
| 
      
 65 
     | 
    
         
            +
                                                     return self->send_to(session, std::forward<Handler>(handler));
         
     | 
| 
      
 66 
     | 
    
         
            +
                                                 });
         
     | 
| 
      
 67 
     | 
    
         
            +
                }
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                template<typename Handler>
         
     | 
| 
      
 70 
     | 
    
         
            +
                void handle_unknown_collection(std::shared_ptr<io::mcbp_session> session, Handler&& handler)
         
     | 
| 
      
 71 
     | 
    
         
            +
                {
         
     | 
| 
      
 72 
     | 
    
         
            +
                    auto backoff = std::chrono::milliseconds(500);
         
     | 
| 
      
 73 
     | 
    
         
            +
                    if (std::chrono::steady_clock::now() + backoff > deadline.expiry()) {
         
     | 
| 
      
 74 
     | 
    
         
            +
                        return handler(make_response(std::make_error_code(error::common_errc::ambiguous_timeout), request, {}));
         
     | 
| 
      
 75 
     | 
    
         
            +
                    }
         
     | 
| 
      
 76 
     | 
    
         
            +
                    retry_backoff.expires_after(backoff);
         
     | 
| 
      
 77 
     | 
    
         
            +
                    retry_backoff.async_wait(
         
     | 
| 
      
 78 
     | 
    
         
            +
                      [self = this->shared_from_this(), session, handler = std::forward<Handler>(handler)](std::error_code ec) mutable {
         
     | 
| 
      
 79 
     | 
    
         
            +
                          if (ec == asio::error::operation_aborted) {
         
     | 
| 
      
 80 
     | 
    
         
            +
                              return handler(make_response(std::make_error_code(error::common_errc::ambiguous_timeout), self->request, {}));
         
     | 
| 
      
 81 
     | 
    
         
            +
                          }
         
     | 
| 
      
 82 
     | 
    
         
            +
                          self->request_collection_id(session, std::forward<Handler>(handler));
         
     | 
| 
      
 83 
     | 
    
         
            +
                      });
         
     | 
| 
      
 84 
     | 
    
         
            +
                }
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
       40 
86 
     | 
    
         
             
                template<typename Handler>
         
     | 
| 
       41 
87 
     | 
    
         
             
                void send_to(std::shared_ptr<io::mcbp_session> session, Handler&& handler)
         
     | 
| 
       42 
88 
     | 
    
         
             
                {
         
     | 
| 
       43 
     | 
    
         
            -
                     
     | 
| 
      
 89 
     | 
    
         
            +
                    auto opaque = session->next_opaque();
         
     | 
| 
      
 90 
     | 
    
         
            +
                    request.opaque = opaque;
         
     | 
| 
      
 91 
     | 
    
         
            +
                    if (!request.id.collection_uid) {
         
     | 
| 
      
 92 
     | 
    
         
            +
                        if (session->supports_feature(protocol::hello_feature::collections)) {
         
     | 
| 
      
 93 
     | 
    
         
            +
                            auto collection_id = session->get_collection_uid(request.id.collection);
         
     | 
| 
      
 94 
     | 
    
         
            +
                            if (collection_id) {
         
     | 
| 
      
 95 
     | 
    
         
            +
                                request.id.collection_uid = *collection_id;
         
     | 
| 
      
 96 
     | 
    
         
            +
                            } else {
         
     | 
| 
      
 97 
     | 
    
         
            +
                                return request_collection_id(session, std::forward<Handler>(handler));
         
     | 
| 
      
 98 
     | 
    
         
            +
                            }
         
     | 
| 
      
 99 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 100 
     | 
    
         
            +
                            if (!request.id.collection.empty() && request.id.collection != "_default._default") {
         
     | 
| 
      
 101 
     | 
    
         
            +
                                return handler(make_response(std::make_error_code(error::common_errc::unsupported_operation), request, {}));
         
     | 
| 
      
 102 
     | 
    
         
            +
                            }
         
     | 
| 
      
 103 
     | 
    
         
            +
                        }
         
     | 
| 
      
 104 
     | 
    
         
            +
                    }
         
     | 
| 
       44 
105 
     | 
    
         
             
                    request.encode_to(encoded);
         
     | 
| 
       45 
106 
     | 
    
         
             
                    session->write_and_subscribe(
         
     | 
| 
       46 
107 
     | 
    
         
             
                      request.opaque,
         
     | 
| 
       47 
108 
     | 
    
         
             
                      encoded.data(session->supports_feature(protocol::hello_feature::snappy)),
         
     | 
| 
       48 
     | 
    
         
            -
                      [self = this->shared_from_this(), handler = std::forward<Handler>(handler)](std::error_code ec, 
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
      
 109 
     | 
    
         
            +
                      [self = this->shared_from_this(), session, handler = std::forward<Handler>(handler)](std::error_code ec,
         
     | 
| 
      
 110 
     | 
    
         
            +
                                                                                                           io::mcbp_message&& msg) mutable {
         
     | 
| 
      
 111 
     | 
    
         
            +
                          if (ec == asio::error::operation_aborted) {
         
     | 
| 
      
 112 
     | 
    
         
            +
                              return handler(make_response(std::make_error_code(error::common_errc::ambiguous_timeout), self->request, {}));
         
     | 
| 
      
 113 
     | 
    
         
            +
                          }
         
     | 
| 
       50 
114 
     | 
    
         
             
                          self->deadline.cancel();
         
     | 
| 
      
 115 
     | 
    
         
            +
                          self->retry_backoff.cancel();
         
     | 
| 
      
 116 
     | 
    
         
            +
                          encoded_response_type resp(msg);
         
     | 
| 
      
 117 
     | 
    
         
            +
                          if (resp.status() == protocol::status::unknown_collection) {
         
     | 
| 
      
 118 
     | 
    
         
            +
                              return self->handle_unknown_collection(session, std::forward<Handler>(handler));
         
     | 
| 
      
 119 
     | 
    
         
            +
                          }
         
     | 
| 
       51 
120 
     | 
    
         
             
                          handler(make_response(ec, self->request, resp));
         
     | 
| 
       52 
121 
     | 
    
         
             
                      });
         
     | 
| 
       53 
     | 
    
         
            -
                    deadline.expires_after( 
     | 
| 
       54 
     | 
    
         
            -
                    deadline.async_wait(std:: 
     | 
| 
      
 122 
     | 
    
         
            +
                    deadline.expires_after(request.timeout);
         
     | 
| 
      
 123 
     | 
    
         
            +
                    deadline.async_wait([session, opaque](std::error_code ec) {
         
     | 
| 
      
 124 
     | 
    
         
            +
                        if (ec == asio::error::operation_aborted) {
         
     | 
| 
      
 125 
     | 
    
         
            +
                            return;
         
     | 
| 
      
 126 
     | 
    
         
            +
                        }
         
     | 
| 
      
 127 
     | 
    
         
            +
                        session->cancel(opaque, asio::error::operation_aborted);
         
     | 
| 
      
 128 
     | 
    
         
            +
                    });
         
     | 
| 
       55 
129 
     | 
    
         
             
                }
         
     | 
| 
       56 
130 
     | 
    
         | 
| 
       57 
131 
     | 
    
         
             
                template<typename Handler>
         
     | 
| 
         @@ -65,12 +139,13 @@ struct command : public std::enable_shared_from_this<command<Request>> { 
     | 
|
| 
       65 
139 
     | 
    
         
             
                          self->deadline.cancel();
         
     | 
| 
       66 
140 
     | 
    
         
             
                          handler(make_response(ec, self->request, resp));
         
     | 
| 
       67 
141 
     | 
    
         
             
                      });
         
     | 
| 
       68 
     | 
    
         
            -
                    deadline.expires_after( 
     | 
| 
       69 
     | 
    
         
            -
                    deadline.async_wait(std:: 
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
      
 142 
     | 
    
         
            +
                    deadline.expires_after(request.timeout);
         
     | 
| 
      
 143 
     | 
    
         
            +
                    deadline.async_wait([session](std::error_code ec) {
         
     | 
| 
      
 144 
     | 
    
         
            +
                        if (ec == asio::error::operation_aborted) {
         
     | 
| 
      
 145 
     | 
    
         
            +
                            return;
         
     | 
| 
      
 146 
     | 
    
         
            +
                        }
         
     | 
| 
      
 147 
     | 
    
         
            +
                        session->stop();
         
     | 
| 
      
 148 
     | 
    
         
            +
                    });
         
     | 
| 
       74 
149 
     | 
    
         
             
                }
         
     | 
| 
       75 
150 
     | 
    
         
             
            };
         
     | 
| 
       76 
151 
     | 
    
         |