Couchbase-Client

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

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)

Changes  view on Meta::CPAN

    
    - 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,

MANIFEST  view on Meta::CPAN


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);



( run in 0.790 second using v1.01-cache-2.11-cpan-9b1e4054eb1 )