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); }
static void compat_default_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *r3base) { const uRESP *r3 = (uRESP *)r3base; const void *cookie = r3base->cookie; lcb_error_t err = r3base->rc; #define FILL_KVC(dst) \ (dst)->v.v0.key = r3base->key; \ (dst)->v.v0.nkey = r3base->nkey; \ (dst)->v.v0.cas = r3base->cas; switch (cbtype) { case LCB_CALLBACK_GET: case LCB_CALLBACK_GETREPLICA: { lcb_get_resp_t r2 = { 0 }; FILL_KVC(&r2) r2.v.v0.bytes = r3->get.value; r2.v.v0.nbytes = r3->get.nvalue; r2.v.v0.flags = r3->get.itmflags; r2.v.v0.datatype = r3->get.datatype; instance->callbacks.get(instance, cookie, err, &r2); break; } case LCB_CALLBACK_STORE: { lcb_store_resp_t r2 = { 0 }; FILL_KVC(&r2) r2.v.v0.mutation_token = lcb_resp_get_mutation_token(cbtype, r3base); instance->callbacks.store(instance, cookie, r3->store.op, err, &r2); break; } case LCB_CALLBACK_COUNTER: { lcb_arithmetic_resp_t r2 = { 0 }; FILL_KVC(&r2); r2.v.v0.value = r3->arith.value; r2.v.v0.mutation_token = lcb_resp_get_mutation_token(cbtype, r3base); instance->callbacks.arithmetic(instance, cookie, err, &r2); break; } case LCB_CALLBACK_REMOVE: { lcb_remove_resp_t r2 = { 0 }; FILL_KVC(&r2) r2.v.v0.mutation_token = lcb_resp_get_mutation_token(cbtype, r3base); instance->callbacks.remove(instance, cookie, err, &r2); break; } case LCB_CALLBACK_TOUCH: { lcb_touch_resp_t r2 = { 0 }; FILL_KVC(&r2) instance->callbacks.touch(instance, cookie, err, &r2); break; } case LCB_CALLBACK_UNLOCK: { lcb_unlock_resp_t r2 = { 0 }; r2.v.v0.key = r3->unl.key; r2.v.v0.nkey = r3->unl.nkey; instance->callbacks.unlock(instance, cookie, err, &r2); break; } case LCB_CALLBACK_FLUSH: { lcb_flush_resp_t r2 = { 0 }; r2.v.v0.server_endpoint = r3->flush.server; instance->callbacks.flush(instance, cookie, err, &r2); break; } case LCB_CALLBACK_VERSIONS: { lcb_server_version_resp_t r2 = { 0 }; r2.v.v0.server_endpoint = r3->mcversion.server; r2.v.v0.vstring = r3->mcversion.mcversion; r2.v.v0.nvstring = r3->mcversion.nversion; instance->callbacks.version(instance, cookie, err, &r2); break; } case LCB_CALLBACK_VERBOSITY: { lcb_verbosity_resp_t r2 = { 0 }; r2.v.v0.server_endpoint = r3->verbosity.server; instance->callbacks.verbosity(instance, cookie, err, &r2); break; } case LCB_CALLBACK_STATS: { lcb_server_stat_resp_t r2 = { 0 }; r2.v.v0.key = r3->stats.key; r2.v.v0.nkey = r3->stats.nkey; r2.v.v0.bytes = r3->stats.value; r2.v.v0.nbytes = r3->stats.nvalue; r2.v.v0.server_endpoint = r3->stats.server; instance->callbacks.stat(instance, cookie, err, &r2); break; } case LCB_CALLBACK_OBSERVE: { lcb_observe_resp_t r2 = { 0 }; FILL_KVC(&r2); r2.v.v0.status = r3->observe.status; r2.v.v0.from_master = r3->observe.ismaster; r2.v.v0.ttp = r3->observe.ttp; r2.v.v0.ttr = r3->observe.ttr; instance->callbacks.observe(instance, cookie, err, &r2); break; } case LCB_CALLBACK_ENDURE: { lcb_durability_resp_t r2 = { 0 }; FILL_KVC(&r2); r2.v.v0.err = r3->endure.rc; r2.v.v0.exists_master = r3->endure.exists_master; r2.v.v0.persisted_master = r3->endure.persisted_master; r2.v.v0.npersisted = r3->endure.npersisted; r2.v.v0.nreplicated = r3->endure.nreplicated; r2.v.v0.nresponses = r3->endure.nresponses; if (err == LCB_SUCCESS) { err = r3->endure.rc; } instance->callbacks.durability(instance, cookie, err, &r2); break; } case LCB_CALLBACK_HTTP: { lcb_http_res_callback target; lcb_http_resp_t r2 = { 0 }; r2.v.v0.path = r3->http.key; r2.v.v0.npath = r3->http.nkey; r2.v.v0.bytes = r3->http.body; r2.v.v0.nbytes = r3->http.nbody; r2.v.v0.status = r3->http.htstatus; r2.v.v0.headers = r3->http.headers; if (!(r3base->rflags & LCB_RESP_F_FINAL)) { target = instance->callbacks.http_data; } else { target = instance->callbacks.http_complete; } target(r3->http._htreq, instance, cookie, err, &r2); break; } default: break; } }