Issue Description We are encountering an unhandled memcached error (0x8 - NO_BUCKET) when attempting to retrieve a document from Couchbase. The issue appears intermittently, and resetting Couchbase connections does not resolve it.
INFO - Reusing server server-node-cb-5.xxxxx:11210 (0x7ff46400b0e0). OldIndex=6. NewIndex=6
ERROR - Got unhandled memcached error 0x8
WARN - \<server-node-cb-5.xxxxx:11210\> (CTX=0x7ff464001480,memcached,SRV=0x7ff46403fc10,IX=2)
Received server error NO_BUCKET (0x8) on packet: OP=0xbb, RC=0x8, SEQ=2
ERROR - Error in getting data from Couchbase:
"A generic / unknown error happened: {"collection":"\_default","status":8,
"key":"ACT_TT_6522221a-8098-4a04-97df-fxxxf398b46a1","opaque":2,
"bucket":"cb_bucket","scope":"\_default",
"remote":"server-node-cb-5.xxxxx:11210"}"
INFO - Resetting Couchbase connections
INFO - Version=3.0.3, Changeset=0xdeadbeef
INFO - Requested network configuration: heuristic
INFO - Requesting connection to node server-node-cb-5.xxxxx:11210 for CCCP configuration \
I am currently using the couchbase rust 1.0.0-alpha.4 sdk client which internally uses libcouchbase here and couchbase server version is 7.6.2
I have tried resetting the couchbase connection which doesn't help and also tried adding operation timeouts
Also if I face any error (besides cas missmatch or document not found error) , I reset both the cluster and bucket connections before retrying and also there's a very small timeout of 10-20ms.
This is the relevant code here
lazy_static! {
static ref CB_CONNECTION: RwLock<Arc<Cluster>> = RwLock::new(create_cluster_connection());
static ref BUCKET_CONNECTIONS: RwLock<HashMap<String, Arc<Collection>>> =
RwLock::new(HashMap::new());
static ref OPERATION_TIMEOUT: Duration = Duration::from_secs(120);
}
//create and store cluster and bucket connection globally using rwlock and lazystatic
pub fn create_cluster_connection() -> Arc<Cluster> {
//example conn string - "couchbase://host-1,host-2,host-3?operation_timeout=120"
let mut connection_url = std::env::var("CB_SERVER").expect("CB_SERVER must be set");
connection_url.push_str("?operation_timeout=120");
let username = std::env::var("CB_USER").expect("CB_USER must be set");
let password = std::env::var("CB_PASSWORD").expect("CB_PASSWORD must be set");
let cluster = Cluster::connect(connection_url, username, password);
Arc::new(cluster)
}
async fn reset_connections() {
log::info!("Resetting Couchbase connections");
let new_cluster = create_cluster_connection();
let mut cluster = CB_CONNECTION.write().await;
*cluster = new_cluster;
let mut buckets = BUCKET_CONNECTIONS.write().await;
buckets.clear();
}
pub async fn get_bucket_connection(bucket_name: String) -> Result<Arc<Collection>, String> {
// Try to get the connection from the map
if let Some(collection) = BUCKET_CONNECTIONS.read().await.get(&bucket_name) {
// Connection already exists, so reuse it
return Ok(Arc::clone(collection));
}
// If the connection doesn't exist, acquire a write lock to add it
log::info!("Creating new connection for bucket: {}", bucket_name);
let bucket = CB_CONNECTION.read().await.bucket(&bucket_name);
let collection = Arc::new(bucket.default_collection());
// Insert the new connection into the map, ensuring only one write operation is done
BUCKET_CONNECTIONS
.write()
.await
.insert(bucket_name, Arc::clone(&collection));
Ok(collection)
}