view release on metacpan or search on metacpan
Author: Mark Nunberg <mnunberg@haskalah.org>
Date: Tue Jan 31 18:06:44 2012 -0800
Multi-interface for synchronouse mode
Synchronous interface has multi-mode
Callbacks refactored to manipulate opaque AV* directly, instead of
proxying values to PLCB_sync_t.
Provided functions to switch callbacks between multi and non-multi mode
CAS is now an IV on 64 bit perls.
Tests for multi-mode
commit 18390812c7247362f2110424ed5d8eb652d86b1f
Author: Mark Nunberg <mnunberg@haskalah.org>
Date: Mon Jan 30 00:31:18 2012 -0800
Extra settings and tunables (WIP)
- Fixed bug in delete/remove
Refactored debugging code into separate test module
commit cac72dbf829be7cfc74693582ff48ca306b17b66
Author: Mark Nunberg <mnunberg@haskalah.org>
Date: Fri Jan 20 15:13:01 2012 -0800
Implemented arithmetic, delete operations
Refactored callbacks to a separate file.
Refactored some redundant code into macros
Added dependencies in Makefile.PL
commit 31e11ff07d095cb49266444d82d19f28c51774d4
Author: Mark Nunberg <mnunberg@haskalah.org>
Date: Thu Jan 19 19:26:47 2012 -0800
Cache::Memcached::* compatible interface,
xs/Client.xs
xs/Client_multi.xs
xs/Async.xs
xs/perl-couchbase.h
xs/perl-couchbase-async.h
xs/plcb-util.h
xs/plcb-return.h
xs/callbacks.c
xs/convert.c
xs/ctor.c
xs/async_base.c
xs/async_callbacks.c
xs/async_events.c
constants/idx_constants.pl
constants/error_constants.pl
constants/print_constants.pl
t/00-load.t
t/01-main.t
t/02-compat.t
Makefile.PL view on Meta::CPAN
my ($cls,$h) = @_;
$MM_TopLevel = $h;
return $h;
};
################################################################################
### Our C Source Files ###
################################################################################
{
my @C_Modules = qw(
callbacks convert ctor async_base async_callbacks async_events);
my @XS_Modules = qw(Client Client_multi);
foreach (@XS_Modules, @C_Modules) {
my $obj = $_ . $Config{obj_ext};
push @{ $MM_Options{OBJECT} }, File::Spec->catfile('xs', $obj);
}
$MM_Options{OBJECT} = join(' ', @{$MM_Options{OBJECT}});
foreach my $xs (@XS_Modules) {
lib/Couchbase/Client/Async.pm view on Meta::CPAN
my $arglist = Couchbase::Client::_MkCtorIDX($options);
$arglist->[CTORIDX_CBEVMOD] = delete $async_opts{cb_update_event}
and
$arglist->[CTORIDX_CBERR] = delete $async_opts{cb_error}
and
$arglist->[CTORIDX_CBWAITDONE] = delete $async_opts{cb_waitdone}
and
$arglist->[CTORIDX_CBTIMERMOD] = delete $async_opts{cb_update_timer}
or die "We require update_event, error, and wait_done callbacks";
if($async_opts{bless_events}) {
$arglist->[CTORIDX_BLESS_EVENT] = 1;
}
my $o = $cls->construct($arglist);
return $o;
}
#Establish proxy methods:
lib/Couchbase/Client/Async.pm view on Meta::CPAN
This part of the module provides a framework in which event libraries can provide
interfaces to users, so that they can perform commands on a couchbase cluster, and
receive their results asynchronously.
=head1 EVENT MANAGEMENT
Event, Timer, and I/O management is the lower level of this module, and constitutes
the interface which event loop integrators would need to be most attune to.
At the most basic level, you are required to implement four callbacks. These
callbacks are indicated by values passed to their given hash keys in the object's
constructor.
=head3 C<cb_update_event>
cb_update_event => sub {
my ($evdata,$action,$flags) = @_;
if(ref($evdata) ne "Couchbase::Client::Event") {
bless $evdata, "Couchbase::Client::Event";
}
xs/Client.xs view on Meta::CPAN
}
Newxz(object, 1, PLCB_t);
object->io_ops = io_ops;
plcb_ctor_conversion_opts(object, options);
plcb_ctor_init_common(object, instance, options);
libcouchbase_set_cookie(instance, object);
plcb_callbacks_setup(object);
blessed_obj = newSV(0);
sv_setiv(newSVrv(blessed_obj, "Couchbase::Client"), PTR2IV(object));
if( (object->my_flags & PLCBf_NO_CONNECT) == 0) {
PLCB_connect(blessed_obj);
}
return blessed_obj;
}
xs/Client_multi.xs view on Meta::CPAN
if(exps) {
_fetch_assert(tmpsv, argav, 1, "expiry");
if(! (exps[i] = SvUV(*tmpsv)) ) {
die("expiry of 0 passed. This is not what you want");
}
}
}
}
plcb_callbacks_set_multi(object);
if(cmd == MULTI_CMD_TOUCH) {
err = libcouchbase_mtouch(instance, syncp, nreq,
(const void* const*)keys, sizes, exps);
} else {
err = libcouchbase_mget(instance, syncp, nreq,
(const void* const*)keys, sizes, NULL);
}
if(err == LIBCOUCHBASE_SUCCESS) {
object->io_ops->run_event_loop(object->io_ops);
} else {
for(i = 0; i < nreq; i++) {
AV *errav = newAV();
plcb_ret_set_err(object, errav, err);
hv_store(ret, keys[i], sizes[i],
plcb_ret_blessed_rv(object, errav), 0);
}
}
plcb_callbacks_set_single(object);
return newRV_inc( (SV*)ret);
}
static SV*
PLCB_multi_set_common(SV *self, AV *args, int cmd)
{
_dMULTI_VARS
PLCB_sync_t *syncs = NULL;
PLCB_sync_t syncs_stacked[MULTI_STACK_ELEM];
xs/async_base.c view on Meta::CPAN
plcb_ctor_cbc_opts(options, &host, &username, &password, &bucket);
instance = libcouchbase_create(host, username, password, bucket,
plcba_make_io_opts(async));
if(!instance) {
die("Couldn't create instance!");
}
plcb_ctor_init_common(&async->base, instance, options);
plcba_setup_callbacks(async);
async->base_rv = newRV_inc(newSViv(PTR2IV(&(async->base))));
blessed_obj = newSV(0);
sv_setiv(newSVrv(blessed_obj, pkg), PTR2IV(async));
return blessed_obj;
}
/*called from perl when an event arrives*/
void
PLCBA_HaveEvent(const char *pkg, short flags, SV *opaque)
xs/async_callbacks.c view on Meta::CPAN
libcouchbase_error_t err)
{
AV *ret;
warn("Got immediate error for %s", key);
ret = newAV();
plcb_ret_set_err((&(async->base)), ret, err);
tell_perl(cookie, ret, key, nkey);
}
/*macro to define common variables and operations for callbacks*/
#define _CB_INIT \
PLCBA_cookie_t *cookie; \
AV *ret; \
PLCB_t *object; \
\
ret = newAV(); \
cookie = (PLCBA_cookie_t*)(v_cookie); \
object = &(cookie->parent->base); \
plcb_ret_set_err(object, ret, err);
xs/async_callbacks.c view on Meta::CPAN
XPUSHs(sv_2mortal(newSVpv(errinfo, 0)));
PUTBACK;
call_sv(async->cv_err, G_DISCARD);
FREETMPS;
LEAVE;
}
void
plcba_setup_callbacks(PLCBA_t *async)
{
libcouchbase_t instance;
instance = async->base.instance;
libcouchbase_set_get_callback(instance, get_callback);
libcouchbase_set_storage_callback(instance, storage_callback);
libcouchbase_set_arithmetic_callback(instance, arithmetic_callback);
libcouchbase_set_remove_callback(instance, remove_callback);
/*
xs/callbacks.c view on Meta::CPAN
XPUSHs(sv_2mortal(server_sv));
XPUSHs(sv_2mortal(key_sv));
XPUSHs(sv_2mortal(data_sv));
PUTBACK;
call_pv(PLCB_STATS_SUBNAME, G_DISCARD);
FREETMPS;
LEAVE;
}
void plcb_callbacks_set_multi(PLCB_t *object)
{
libcouchbase_t instance = object->instance;
libcouchbase_set_get_callback(instance, plcb_callback_multi_get);
libcouchbase_set_touch_callback(instance, keyop_multi_callback);
}
void plcb_callbacks_set_single(PLCB_t *object)
{
libcouchbase_t instance = object->instance;
libcouchbase_set_get_callback(instance, plcb_callback_get);
libcouchbase_set_touch_callback(instance, keyop_callback);
}
void plcb_callbacks_setup(PLCB_t *object)
{
libcouchbase_t instance = object->instance;
libcouchbase_set_get_callback(instance, plcb_callback_get);
libcouchbase_set_storage_callback(instance, plcb_callback_storage);
libcouchbase_set_error_callback(instance, plcb_callback_error);
#ifdef PLCB_HAVE_CONNFAIL
libcouchbase_set_connfail_callback(instance, plcb_callback_connfail);
#endif
libcouchbase_set_touch_callback(instance, keyop_callback);
xs/perl-couchbase-async.h view on Meta::CPAN
struct {
int64_t delta;
uint64_t initial;
int create;
} arithmetic;
} PLCBA_request_t;
/*wire callbacks*/
void plcba_setup_callbacks(PLCBA_t *async);
/*wire io structure*/
plcba_cbcio *plcba_make_io_opts(PLCBA_t *async);
/*immediate error notification*/
void plcba_callback_notify_err(PLCBA_t *async,
PLCBA_cookie_t *cookie,
const char *key, size_t nkey,
libcouchbase_error_t err);
xs/perl-couchbase.h view on Meta::CPAN
PLCBf_RET_EXTENDED_FIELDS = 0x100,
PLCBf_DEREF_RVPV = 0x200,
} PLCB_flags_t;
#define PLCBf_DO_CONVERSION \
(PLCBf_USE_COMPRESSION|PLCBf_USE_STORABLE|PLCBf_USE_CONVERT_UTF8)
struct PLCB_st {
libcouchbase_t instance; /*our library handle*/
PLCB_sync_t sync; /*object to collect results from callbacks*/
HV *stats_hv; /*object to collect statistics from*/
AV *errors; /*per-operation error stack*/
HV *ret_stash; /*stash with which we bless our return objects*/
PLCB_flags_t my_flags;
/*maybe make this a bit more advanced?*/
int connected;
SV *cv_serialize;
SV *cv_deserialize;
xs/perl-couchbase.h view on Meta::CPAN
PLCB_CTORIDX_SERIALIZE_METHODS,
/*provided object for event loop handling*/
PLCB_CTORIDX_EVLOOP_OBJ,
PLCB_CTORIDX_TIMEOUT,
PLCB_CTORIDX_NO_CONNECT,
} PLCB_ctor_idx_t;
void plcb_callbacks_setup(PLCB_t *object);
void plcb_callbacks_set_multi(PLCB_t *object);
void plcb_callbacks_set_single(PLCB_t *object);
/*options for common constructor settings*/
void plcb_ctor_cbc_opts(AV *options,
char **hostp, char **userp, char **passp, char **bucketp);
void plcb_ctor_conversion_opts(PLCB_t *object, AV *options);
void plcb_ctor_init_common(PLCB_t *object, libcouchbase_t instance,
AV *options);
void plcb_errstack_push(PLCB_t *object,
libcouchbase_error_t err, const char *errinfo);