void observe_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_observe_resp_t *resp) { struct context_st *ctx = (struct context_st *)cookie; struct bucket_st *bucket = ctx->bucket; VALUE key, res, *rv = ctx->rv; if (resp->v.v0.key) { key = STR_NEW((const char*)resp->v.v0.key, resp->v.v0.nkey); ctx->exception = cb_check_error(error, "failed to execute observe request", key); if (ctx->exception) { cb_gc_protect(bucket, ctx->exception); } res = rb_class_new_instance(0, NULL, cResult); rb_ivar_set(res, id_iv_completed, Qfalse); rb_ivar_set(res, id_iv_error, ctx->exception); rb_ivar_set(res, id_iv_operation, sym_observe); rb_ivar_set(res, id_iv_key, key); rb_ivar_set(res, id_iv_cas, ULL2NUM(resp->v.v0.cas)); rb_ivar_set(res, id_iv_from_master, resp->v.v0.from_master ? Qtrue : Qfalse); rb_ivar_set(res, id_iv_time_to_persist, ULONG2NUM(resp->v.v0.ttp)); rb_ivar_set(res, id_iv_time_to_replicate, ULONG2NUM(resp->v.v0.ttr)); switch (resp->v.v0.status) { case LCB_OBSERVE_FOUND: rb_ivar_set(res, id_iv_status, sym_found); break; case LCB_OBSERVE_PERSISTED: rb_ivar_set(res, id_iv_status, sym_persisted); break; case LCB_OBSERVE_NOT_FOUND: rb_ivar_set(res, id_iv_status, sym_not_found); break; default: rb_ivar_set(res, id_iv_status, Qnil); } if (bucket->async) { /* asynchronous */ if (ctx->proc != Qnil) { cb_proc_call(ctx->proc, 1, res); } } else { /* synchronous */ if (NIL_P(ctx->exception)) { VALUE stats = rb_hash_aref(*rv, key); if (NIL_P(stats)) { stats = rb_ary_new(); rb_hash_aset(*rv, key, stats); } rb_ary_push(stats, res); } } } else { if (bucket->async && ctx->proc != Qnil) { res = rb_class_new_instance(0, NULL, cResult); rb_ivar_set(res, id_iv_completed, Qtrue); cb_proc_call(ctx->proc, 1, res); } ctx->nqueries--; cb_gc_unprotect(bucket, ctx->proc); } (void)handle; }
void arithmetic_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_arithmetic_resp_t *resp) { struct context_st *ctx = (struct context_st *)cookie; struct bucket_st *bucket = ctx->bucket; VALUE cas, key, val, *rv = ctx->rv, exc, res; ID o; ctx->nqueries--; key = STR_NEW((const char*)resp->v.v0.key, resp->v.v0.nkey); strip_key_prefix(bucket, key); cas = resp->v.v0.cas > 0 ? ULL2NUM(resp->v.v0.cas) : Qnil; o = ctx->arith > 0 ? sym_increment : sym_decrement; exc = cb_check_error(error, "failed to perform arithmetic operation", key); if (exc != Qnil) { rb_ivar_set(exc, id_iv_cas, cas); rb_ivar_set(exc, id_iv_operation, o); if (bucket->async) { if (bucket->on_error_proc != Qnil) { cb_proc_call(bucket->on_error_proc, 3, o, key, exc); } else { if (NIL_P(bucket->exception)) { bucket->exception = exc; } } } if (NIL_P(ctx->exception)) { ctx->exception = cb_gc_protect(bucket, exc); } } val = ULL2NUM(resp->v.v0.value); if (bucket->async) { /* asynchronous */ if (ctx->proc != Qnil) { res = rb_class_new_instance(0, NULL, cResult); rb_ivar_set(res, id_iv_error, exc); rb_ivar_set(res, id_iv_operation, o); rb_ivar_set(res, id_iv_key, key); rb_ivar_set(res, id_iv_value, val); rb_ivar_set(res, id_iv_cas, cas); cb_proc_call(ctx->proc, 1, res); } } else { /* synchronous */ if (NIL_P(exc)) { if (ctx->extended) { rb_hash_aset(*rv, key, rb_ary_new3(2, val, cas)); } else { rb_hash_aset(*rv, key, val); } } } if (ctx->nqueries == 0) { cb_gc_unprotect(bucket, ctx->proc); } (void)handle; }
void cb_http_complete_callback(lcb_http_request_t request, lcb_t handle, const void *cookie, lcb_error_t error, const lcb_http_resp_t *resp) { struct cb_context_st *ctx = (struct cb_context_st *)cookie; struct cb_bucket_st *bucket = ctx->bucket; VALUE key, val, res, exc; lcb_http_status_t status; ctx->request->completed = 1; if (bucket->destroying) { cb_context_free(ctx); return; } key = STR_NEW((const char*)resp->v.v0.path, resp->v.v0.npath); val = resp->v.v0.nbytes ? STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes) : Qnil; exc = ctx->exception; if (!RTEST(exc)) { exc = cb_check_error_with_status(error, "failed to execute HTTP request", key, resp->v.v0.status); if (exc != Qnil && val != Qnil) { rb_ivar_set(exc, cb_id_iv_body, val); } } if (RTEST(exc)) { if (rb_obj_is_kind_of(exc, cb_eHTTPError)) { rb_funcall(exc, cb_id_parse_body_bang, 0); } ctx->exception = exc; } status = resp->v.v0.status; if (resp->v.v0.headers) { cb_build_headers(ctx, resp->v.v0.headers); ctx->headers_val = Qnil; } if (ctx->extended) { res = rb_class_new_instance(0, NULL, cb_cResult); rb_ivar_set(res, cb_id_iv_error, ctx->exception); rb_ivar_set(res, cb_id_iv_status, status ? INT2FIX(status) : Qnil); rb_ivar_set(res, cb_id_iv_operation, cb_sym_http_request); rb_ivar_set(res, cb_id_iv_key, key); rb_ivar_set(res, cb_id_iv_value, val); rb_ivar_set(res, cb_id_iv_completed, Qtrue); rb_ivar_set(res, cb_id_iv_headers, ctx->headers_val); } else { res = val; } if (ctx->proc != Qnil) { cb_proc_call(bucket, ctx->proc, 1, res); ctx->proc = Qnil; } if (!bucket->async && ctx->exception == Qnil) { ctx->rv = res; } if (bucket->async) { cb_context_free(ctx); } (void)handle; (void)request; }
void http_data_callback(lcb_http_request_t request, lcb_t handle, const void *cookie, lcb_error_t error, const lcb_http_resp_t *resp) { struct context_st *ctx = (struct context_st *)cookie; struct bucket_st *bucket = ctx->bucket; VALUE key, val, res; key = STR_NEW((const char*)resp->v.v0.path, resp->v.v0.npath); ctx->exception = cb_check_error_with_status(error, "failed to execute HTTP request", key, resp->v.v0.status); val = resp->v.v0.nbytes ? STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes) : Qnil; if (ctx->exception != Qnil) { cb_gc_protect(bucket, ctx->exception); lcb_cancel_http_request(bucket->handle, request); } if (resp->v.v0.headers) { cb_build_headers(ctx, resp->v.v0.headers); } if (ctx->proc != Qnil) { if (ctx->extended) { res = rb_class_new_instance(0, NULL, cResult); rb_ivar_set(res, id_iv_error, ctx->exception); rb_ivar_set(res, id_iv_operation, sym_http_request); rb_ivar_set(res, id_iv_key, key); rb_ivar_set(res, id_iv_value, val); rb_ivar_set(res, id_iv_completed, Qfalse); rb_ivar_set(res, id_iv_headers, ctx->headers_val); } else { res = val; } cb_proc_call(ctx->proc, 1, res); } (void)handle; }
void cb_storage_callback(lcb_t handle, const void *cookie, lcb_storage_t operation, lcb_error_t error, const lcb_store_resp_t *resp) { struct cb_context_st *ctx = (struct cb_context_st *)cookie; struct cb_bucket_st *bucket = ctx->bucket; VALUE key, cas, exc, res; key = STR_NEW((const char*)resp->v.v0.key, resp->v.v0.nkey); cb_strip_key_prefix(bucket, key); cas = resp->v.v0.cas > 0 ? ULL2NUM(resp->v.v0.cas) : Qnil; ctx->operation = storage_opcode_to_sym(operation); exc = cb_check_error(error, "failed to store value", key); if (exc != Qnil) { rb_ivar_set(exc, cb_id_iv_cas, cas); rb_ivar_set(exc, cb_id_iv_operation, ctx->operation); ctx->exception = exc; } if (bucket->async) { /* asynchronous */ if (RTEST(ctx->observe_options)) { VALUE args[2]; /* it's ok to pass pointer to stack struct here */ args[0] = rb_hash_new(); rb_hash_aset(args[0], key, cas); args[1] = ctx->observe_options; rb_block_call(bucket->self, cb_id_observe_and_wait, 2, args, storage_observe_callback, (VALUE)ctx); ctx->observe_options = Qnil; } else if (ctx->proc != Qnil) { res = rb_class_new_instance(0, NULL, cb_cResult); rb_ivar_set(res, cb_id_iv_error, exc); rb_ivar_set(res, cb_id_iv_key, key); rb_ivar_set(res, cb_id_iv_operation, ctx->operation); rb_ivar_set(res, cb_id_iv_cas, cas); cb_proc_call(bucket, ctx->proc, 1, res); } } else { /* synchronous */ rb_hash_aset(ctx->rv, key, cas); } if (!RTEST(ctx->observe_options)) { ctx->nqueries--; if (ctx->nqueries == 0) { ctx->proc = Qnil; if (bucket->async) { cb_context_free(ctx); } } } (void)handle; }
void cb_http_data_callback(lcb_http_request_t request, lcb_t handle, const void *cookie, lcb_error_t error, const lcb_http_resp_t *resp) { struct cb_context_st *ctx = (struct cb_context_st *)cookie; struct cb_bucket_st *bucket = ctx->bucket; VALUE key, val, res; lcb_http_status_t status; key = STR_NEW((const char*)resp->v.v0.path, resp->v.v0.npath); val = resp->v.v0.nbytes ? STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes) : Qnil; status = resp->v.v0.status; if (NIL_P(ctx->exception)) { ctx->exception = cb_check_error_with_status(error, "failed to execute HTTP request", key, resp->v.v0.status); if (ctx->exception != Qnil) { VALUE body_str = rb_ivar_get(ctx->exception, cb_id_iv_body); if (NIL_P(body_str)) { rb_ivar_set(ctx->exception, cb_id_iv_body, val); } else { rb_str_concat(body_str, val); } return; } } if (resp->v.v0.headers) { cb_build_headers(ctx, resp->v.v0.headers); } if (ctx->proc != Qnil) { if (ctx->extended) { res = rb_class_new_instance(0, NULL, cb_cResult); rb_ivar_set(res, cb_id_iv_error, Qnil); rb_ivar_set(res, cb_id_iv_status, status ? INT2FIX(status) : Qnil); rb_ivar_set(res, cb_id_iv_operation, cb_sym_http_request); rb_ivar_set(res, cb_id_iv_key, key); rb_ivar_set(res, cb_id_iv_value, val); rb_ivar_set(res, cb_id_iv_completed, Qfalse); rb_ivar_set(res, cb_id_iv_headers, ctx->headers_val); } else { res = val; } cb_proc_call(bucket, ctx->proc, 1, res); } (void)handle; }
void cb_version_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_server_version_resp_t *resp) { struct cb_context_st *ctx = (struct cb_context_st *)cookie; struct cb_bucket_st *bucket = ctx->bucket; VALUE node, val, exc, res; node = resp->v.v0.server_endpoint ? STR_NEW_CSTR(resp->v.v0.server_endpoint) : Qnil; exc = cb_check_error(error, "failed to get version", node); if (exc != Qnil) { rb_ivar_set(exc, cb_id_iv_operation, cb_sym_version); ctx->exception = exc; } if (node != Qnil) { val = STR_NEW((const char*)resp->v.v0.vstring, resp->v.v0.nvstring); if (bucket->async) { /* asynchronous */ if (ctx->proc != Qnil) { res = rb_class_new_instance(0, NULL, cb_cResult); rb_ivar_set(res, cb_id_iv_error, exc); rb_ivar_set(res, cb_id_iv_operation, cb_sym_version); rb_ivar_set(res, cb_id_iv_node, node); rb_ivar_set(res, cb_id_iv_value, val); cb_proc_call(bucket, ctx->proc, 1, res); } } else { /* synchronous */ if (NIL_P(exc)) { rb_hash_aset(ctx->rv, node, val); } } } else { ctx->nqueries--; ctx->proc = Qnil; if (bucket->async) { cb_context_free(ctx); } } (void)handle; }
static VALUE storage_observe_callback(VALUE args, VALUE cookie) { struct cb_context_st *ctx = (struct cb_context_st *)cookie; struct cb_bucket_st *bucket = ctx->bucket; VALUE res = rb_ary_shift(args); if (ctx->proc != Qnil) { rb_ivar_set(res, cb_id_iv_operation, ctx->operation); cb_proc_call(bucket, ctx->proc, 1, res); } if (!RTEST(ctx->observe_options)) { ctx->nqueries--; if (ctx->nqueries == 0) { ctx->proc = Qnil; if (bucket->async) { cb_context_free(ctx); } } } return Qnil; }
void cb_unlock_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_unlock_resp_t *resp) { struct cb_context_st *ctx = (struct cb_context_st *)cookie; struct cb_bucket_st *bucket = ctx->bucket; VALUE key, exc = Qnil, res; ctx->nqueries--; key = STR_NEW((const char*)resp->v.v0.key, resp->v.v0.nkey); cb_strip_key_prefix(bucket, key); if (error != LCB_KEY_ENOENT || !ctx->quiet) { exc = cb_check_error(error, "failed to unlock value", key); if (exc != Qnil) { rb_ivar_set(exc, cb_id_iv_operation, cb_sym_unlock); ctx->exception = exc; } } if (bucket->async) { /* asynchronous */ if (ctx->proc != Qnil) { res = rb_class_new_instance(0, NULL, cb_cResult); rb_ivar_set(res, cb_id_iv_error, exc); rb_ivar_set(res, cb_id_iv_operation, cb_sym_unlock); rb_ivar_set(res, cb_id_iv_key, key); cb_proc_call(bucket, ctx->proc, 1, res); } } else { /* synchronous */ rb_hash_aset(ctx->rv, key, (error == LCB_SUCCESS) ? Qtrue : Qfalse); } if (ctx->nqueries == 0) { ctx->proc = Qnil; if (bucket->async) { cb_context_free(ctx); } } (void)handle; }
void cb_get_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_get_resp_t *resp) { struct cb_context_st *ctx = (struct cb_context_st *)cookie; struct cb_bucket_st *bucket = ctx->bucket; VALUE key, val, flags, cas, exc = Qnil, res, raw; ctx->nqueries--; key = STR_NEW((const char*)resp->v.v0.key, resp->v.v0.nkey); cb_strip_key_prefix(bucket, key); if (error != LCB_KEY_ENOENT || !ctx->quiet) { exc = cb_check_error(error, "failed to get value", key); if (exc != Qnil) { rb_ivar_set(exc, cb_id_iv_operation, cb_sym_get); ctx->exception = exc; } } flags = ULONG2NUM(resp->v.v0.flags); cas = ULL2NUM(resp->v.v0.cas); raw = STR_NEW((const char*)resp->v.v0.bytes, resp->v.v0.nbytes); val = cb_decode_value(ctx->transcoder, raw, resp->v.v0.flags, ctx->transcoder_opts); if (rb_obj_is_kind_of(val, rb_eStandardError)) { VALUE exc_str = rb_funcall(val, cb_id_to_s, 0); VALUE msg = rb_funcall(rb_mKernel, cb_id_sprintf, 3, rb_str_new2("unable to convert value for key \"%s\": %s"), key, exc_str); ctx->exception = rb_exc_new3(cb_eValueFormatError, msg); rb_ivar_set(ctx->exception, cb_id_iv_operation, cb_sym_get); rb_ivar_set(ctx->exception, cb_id_iv_key, key); rb_ivar_set(ctx->exception, cb_id_iv_inner_exception, val); val = Qnil; } if (bucket->async) { /* asynchronous */ if (ctx->proc != Qnil) { res = rb_class_new_instance(0, NULL, cb_cResult); rb_ivar_set(res, cb_id_iv_error, exc); rb_ivar_set(res, cb_id_iv_operation, cb_sym_get); rb_ivar_set(res, cb_id_iv_key, key); rb_ivar_set(res, cb_id_iv_value, val); rb_ivar_set(res, cb_id_iv_flags, flags); rb_ivar_set(res, cb_id_iv_cas, cas); cb_proc_call(bucket, ctx->proc, 1, res); } } else { /* synchronous */ if (NIL_P(exc) && error != LCB_KEY_ENOENT) { if (ctx->extended) { val = rb_ary_new3(3, val, flags, cas); } if (ctx->all_replicas) { VALUE ary = rb_hash_aref(ctx->rv, key); if (NIL_P(ary)) { ary = rb_ary_new(); rb_hash_aset(ctx->rv, key, ary); } rb_ary_push(ary, val); } else { rb_hash_aset(ctx->rv, key, val); } } } if (ctx->nqueries == 0) { ctx->proc = Qnil; if (bucket->async) { cb_context_free(ctx); } } (void)handle; }
static VALUE trigger_timer(VALUE timer) { struct timer_st *tm = DATA_PTR(timer); return cb_proc_call(tm->callback, 1, timer); }