Couchbase
  • Why NoSQL?
  • Couchbase Server
  • Download
  • Resources
  • Careers
Home | Forums | SDKs | SDKs

Using libcouchbase in async mode

6 replies [Last post]
  • Login or register to post comments
Tue, 06/05/2012 - 11:08
mleib
Offline
Joined: 08/16/2011
Groups: None

Hello...

I'm evaluating libcouchbase with Couchbase Server 2.0 DEV4 and have a question regarding use
of the library in async mode. All of the examples I've seen in the docs and on the web (and
there are not that many) make use of libcouchbase_wait(handle); in a pseudo-synchronous manner
to know when the queued operations have completed, in addition to any and all registered callbacks.

Ok, cool...I understand that. However, my applications are all written using libev and are
async, using the event loop to keep the application alive while they wait for events to process.

In other words, a daemon.

To quote the product page:

"More advanced programs will want to either call the libcouchbase_wait() function after generating some
operations, or drive the event loop themselves."

I'm willing to switch my code from libev to libevent (I've used both and prefer libev, but ok...I'll switch)
however can someone explain (which I don't see anywhere) how I get access to the event handle after
libevent has been initialized by libcouchbase and the event loop started (or is it not started until the first
action called into libcouchbase)?

I can't block....and unless I can get access to the handle, I think I'm stuck.
A small example would be stellar!! :>

Thanks in advance....

Top
  • Login or register to post comments
Wed, 06/06/2012 - 11:30
mleib
Offline
Joined: 08/16/2011
Groups: None

Disappointed I didn't see any replies to this....

So, started ripping through the library source code...

To further refine my question:

If I do:

if ((io = libcouchbase_create_io_ops(LIBCOUCHBASE_IO_OPS_DEFAULT, NULL, NULL) ) == NULL ) {
fprintf(stderr, "Failed to create io\n");
exit(EXIT_FAILURE);
}

if ((handle = libcouchbase_create(host, username, password, bucket, io)) == NULL){
/* Failed to create the handle */
fprintf(stderr, "Failed to create instance\n");
exit(EXIT_FAILURE);
}

..... lots of stuff, including setting up my own events to libevent

// Start libevent event loop
io->run_event_loop(io);

Can I indeed use ((struct libevent_cookie *)iops->cookie)->base as the handle to libevent for
my own event/callback purposes for code that has nothing to do with couchbase?

Michael

Top
  • Login or register to post comments
Fri, 06/08/2012 - 08:06
mleib
Offline
Joined: 08/16/2011
Groups: None

Here is how I finally got it to work

#include < stdlib.h >
#include < stdio.h >
#include < string.h >
#include < event.h >
#include < stdbool.h >
#include < libcouchbase/couchbase.h >

static struct event_base * base = NULL;
static libcouchbase_t * handle = NULL;
static bool done = false;

static void error_callback( libcouchbase_t instance, libcouchbase_error_t error, const char *errinfo )
{
fprintf( stderr, "%s", libcouchbase_strerror( instance, error ) );
if ( errinfo )
fprintf( stderr, ": %s", errinfo );
fprintf( stderr, "\n" );
exit( EXIT_FAILURE );
}

void timer_cb( int fd, short event, void *arg )
{
char key[80];
static int n = 0;
int nkey;

if ( n++ > 100 ) {
done = true;
return;
}

printf( "cb_func called %d times so far.\n", n );

/* Add store events to the queue */
nkey = sprintf( key, "%d", n );
libcouchbase_store( *handle, NULL, LIBCOUCHBASE_SET, key, nkey, &n, sizeof(n), 0, 0, 0 );

printf("cb_func call done\n");
}

static void storage_callback( libcouchbase_t instance, const void *cookie, libcouchbase_storage_t operation,
libcouchbase_error_t error, const void *key, size_t nkey, uint64_t cas )
{
static struct event ev;
static struct timeval tv;

if ( error != LIBCOUCHBASE_SUCCESS ) {
fprintf( stderr, "Failed to store \"" );
fwrite( key, nkey, 1, stderr );
fprintf( stderr, "\"\n" );
exit( EXIT_FAILURE );
}

/* libevent api to start a timer */
tv.tv_sec = 0;
tv.tv_usec = 0;
event_set( &ev, -1, 0, timer_cb, NULL );
event_base_set( base, &ev );
event_add( &ev, &tv );
}

void timer_end_cb( int fd, short event, void *arg )
{
static struct event ev_end;
static struct timeval tv_end;

/* We have seen all responses */
if ( done )
exit( EXIT_SUCCESS );

/* libevent api to start a timer */
tv_end.tv_sec = 1;
tv_end.tv_usec = 0;
event_set( &ev_end, -1, 0, timer_end_cb, NULL );
event_base_set( base, &ev_end );
event_add( &ev_end, &tv_end );
}

static void free_resources( void )
{
/* Free the instance */
if ( handle ) {
libcouchbase_destroy( *handle );
free( handle );
}

/* Free the base, since we created it */
if ( base )
event_base_free( base );
}

int main( int argc, char **argv )
{
const char *host = NULL; /* Use localhost:8091 */
const char *username = NULL; /* No user specified */
const char *password = NULL; /* No password specified */
const char *bucket = NULL; /* use default bucket */
static libcouchbase_io_opt_t *io = NULL;
struct event ev, ev_end;
struct timeval tv, tv_end;

atexit( free_resources );

if ( ( base = event_base_new() ) == NULL ) {
fprintf( stderr, "Failed to create base\n" );
exit( EXIT_FAILURE );
}

if ( ( io = libcouchbase_create_io_ops( LIBCOUCHBASE_IO_OPS_DEFAULT, base, NULL ) ) == NULL ) {
fprintf( stderr, "Failed to create io\n" );
exit( EXIT_FAILURE );
}

if ( ( handle = malloc( sizeof( libcouchbase_t ) ) ) == NULL ) {
fprintf( stderr, "malloc() failed\n" );
exit( EXIT_FAILURE );
}
memset( handle, 0, sizeof( libcouchbase_t ) );

if ( ( *handle = libcouchbase_create(host, username, password, bucket, io ) ) == NULL ){
fprintf( stderr, "Failed to create instance\n" );
exit( EXIT_FAILURE );
}

libcouchbase_set_error_callback( *handle, error_callback );
libcouchbase_set_storage_callback( *handle, storage_callback );

libcouchbase_connect( *handle );
libcouchbase_wait( *handle );

/* libevent api to start a timer */
tv.tv_sec = 0;
tv.tv_usec = 0;
event_set( &ev, -1, 0, timer_cb, NULL );
event_base_set( base, &ev );
event_add( &ev, &tv );

tv_end.tv_sec = 1;
tv_end.tv_usec = 0;
event_set( &ev_end, -1, 0, timer_end_cb, NULL );
event_base_set( base, &ev_end );
event_add( &ev_end, &tv_end );

/* Spark libevent - we won't be back until the loop is stopped */
event_base_loop( base, 0 );

return 0;
}

I hope this might help somebody sometime because nobody helped me.

Top
  • Login or register to post comments
Sun, 10/21/2012 - 14:29
cjr2k3
Offline
Joined: 10/21/2012
Groups: None

Hi,

I will look at this code better, since I'm stuck with the same problem. I have a heavy threaded application that needs to write/read to couchbase. I can't find a single place how to drive the event loop... And using the wait function doesn't cut it for me.

Top
  • Login or register to post comments
Sun, 10/21/2012 - 20:41
avsej
avsej's picture
Offline
Joined: 06/15/2011
Groups: None

Hi guys, sorry for late response, but I wrote simple eample of how to integrate libcouchbase with your own application which possibly has own event framework.

https://github.com/avsej/libev-couchbase-example

In this example initially you have echo server built on libev on step and on step two it have libcouchbase integrated and using event stuff from host application. I'm using libev here because we've wrote libcouchbase plugin for it, but it could be any other framework if you'll will implement couple of functions in plugin

Update. The code was written 20 days ago before recent libcouchbase release, so there could be trivial compile errors. I will fix them in couple of hours today

__________________

Find me on FreeNode IRC in #libcouchbase channel

Top
  • Login or register to post comments
Tue, 10/23/2012 - 00:12
byzhang
Offline
Joined: 02/25/2012
Groups: None

Hi guys, I actually have a question in another extreme. How to use it in the sync mode? From the website, I read this: "The simplest is to use the synchronous interface over the asynch internals of the library." But I cannot find an example, nor in the header files.
Any lights on sync examples?

Thanks

Top
  • Login or register to post comments
Tue, 10/23/2012 - 00:42
avsej
avsej's picture
Offline
Joined: 06/15/2011
Groups: None

We have example for synchronous mode too:

https://github.com/couchbase/libcouchbase/blob/master/example/syncmode/m...

Note although, that this approach still requires callbacks, but I think it won't be very complex to generalize them and wrap into single calls.

__________________

Find me on FreeNode IRC in #libcouchbase channel

Top
  • Login or register to post comments
  • Login or register to post comments
  • Login
  • Register

Company

  • About Us
  • Leadership
  • Customers
  • Partners
  • Contact Us

Product

  • Couchbase Server
  • Couchbase SDKs
  • Use Cases
  • Documentation
  • Forums

Open Source

  • Couchbase Project
  • Couchbase vs. CouchDB

Commercial

  • Subscriptions & Support
  • Training & Services

News

  • Blog
  • Newsletter
  • Press Releases
  • Buzz

Follow Us

    
  • Customer Login
  • Terms of Service
  • Privacy Policy
  • Trademark Policy
  • Site Map

© 2013 COUCHBASE All rights reserved.

Sign in to Couchbase Community

close
  • Create new account
  • Request new password
You are logging into the Forums, Wiki and Issue Tracker