static PyObject * Bucket__mutinfo(pycbc_Bucket *self) { PyObject *ll = PyList_New(0); size_t ii, vbmax; lcbvb_CONFIG *cfg = NULL; lcb_error_t rc; rc = lcb_cntl(self->instance, LCB_CNTL_GET, LCB_CNTL_VBCONFIG, &cfg); if (rc != LCB_SUCCESS) { PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, rc, "Couldn't get vBucket config"); return NULL; } vbmax = vbucket_config_get_num_vbuckets(cfg); for (ii = 0; ii < vbmax; ++ii) { lcb_KEYBUF kb = { 0 }; const lcb_MUTATION_TOKEN *mt; lcb_error_t rc = LCB_SUCCESS; PyObject *cur; kb.type = LCB_KV_VBID; kb.contig.nbytes = (size_t)ii; mt = lcb_get_mutation_token(self->instance, &kb, &rc); if (mt == NULL) { continue; } cur = Py_BuildValue("HKK", LCB_MUTATION_TOKEN_VB(mt), LCB_MUTATION_TOKEN_ID(mt), LCB_MUTATION_TOKEN_SEQ(mt)); PyList_Append(ll, cur); Py_DECREF(cur); } return ll; }
static void dur_chain2(pycbc_Bucket *conn, pycbc_MultiResult *mres, pycbc_OperationResult *res, int cbtype, const lcb_RESPBASE *resp) { lcb_error_t err; lcb_durability_opts_t dopts = { 0 }; lcb_CMDENDURE cmd = { 0 }; lcb_MULTICMD_CTX *mctx = NULL; int is_delete = cbtype == LCB_CALLBACK_REMOVE; res->rc = resp->rc; if (resp->rc == LCB_SUCCESS) { const lcb_MUTATION_TOKEN *mutinfo = lcb_resp_get_mutation_token(cbtype, resp); Py_XDECREF(res->mutinfo); if (mutinfo && LCB_MUTATION_TOKEN_ISVALID(mutinfo)) { /* Create the mutation token tuple: (vb,uuid,seqno) */ res->mutinfo = Py_BuildValue("HKKO", LCB_MUTATION_TOKEN_VB(mutinfo), LCB_MUTATION_TOKEN_ID(mutinfo), LCB_MUTATION_TOKEN_SEQ(mutinfo), conn->bucket); } else { Py_INCREF(Py_None); res->mutinfo = Py_None; } res->cas = resp->cas; } /** For remove, we check quiet */ maybe_push_operr(mres, (pycbc_Result*)res, resp->rc, is_delete ? 1 : 0); if ((mres->mropts & PYCBC_MRES_F_DURABILITY) == 0 || resp->rc != LCB_SUCCESS) { operation_completed(conn, mres); CB_THR_BEGIN(conn); return; } if (conn->dur_testhook && conn->dur_testhook != Py_None) { invoke_endure_test_notification(conn, (pycbc_Result *)res); } /** Setup global options */ dopts.v.v0.persist_to = mres->dur.persist_to; dopts.v.v0.replicate_to = mres->dur.replicate_to; dopts.v.v0.timeout = conn->dur_timeout; dopts.v.v0.check_delete = is_delete; if (mres->dur.persist_to < 0 || mres->dur.replicate_to < 0) { dopts.v.v0.cap_max = 1; } lcb_sched_enter(conn->instance); mctx = lcb_endure3_ctxnew(conn->instance, &dopts, &err); if (mctx == NULL) { goto GT_DONE; } cmd.cas = resp->cas; LCB_CMD_SET_KEY(&cmd, resp->key, resp->nkey); err = mctx->addcmd(mctx, (lcb_CMDBASE*)&cmd); if (err != LCB_SUCCESS) { goto GT_DONE; } err = mctx->done(mctx, mres); if (err == LCB_SUCCESS) { mctx = NULL; lcb_sched_leave(conn->instance); } GT_DONE: if (mctx) { mctx->fail(mctx); } if (err != LCB_SUCCESS) { res->rc = err; maybe_push_operr(mres, (pycbc_Result*)res, err, 0); operation_completed(conn, mres); } CB_THR_BEGIN(conn); }