Trying to use libevent


#1

I am having some problems in using libevent using the application event loop. Couchbase lib version 2.0.6.

Please clarify that both libcouchbase and libcouchbase_libevent need to be linked.

I am getting the warning:

[warn] event_base_loop: reentrant invocation. Only one event_base_loop can run on each event_base at once.

Also, as a first step I am setting synchronous mode on all instances:

lcb_behavior_set_syncmode(apps_instance, LCB_SYNCHRONOUS);

However, all operations remain asynchronous.

Please advise.

-Marco G.


#2

You should link only against libcouchbase, it will load libevent-based IO plugin using dlopen. If it doesn’t solves your problem, could you show the source code and how you are building the stuff?


#3

/**

  • Initialize the registry.
  • @returns Non zero value to indicate an error.

*/
int
registry_init(struct event_base *base)
{
struct lcb_create_st create_options;
struct lcb_create_io_ops_st ciops;
lcb_io_opt_t ioops;
lcb_error_t ret;
char *ptr;
int i;

/* initialize the module array cluster_servers */
if (get_cluster_ips(myzone) != 0)
    return -1;

for (i = 0; cluster_servers[i] != NULL; i++)
    fprintf(stdout, "CB cluster_servers[%d]: %s\r\n", i, cluster_servers[i]);

/* 
 * Create Couchbase instances 
 */
memset(&ciops, 0, sizeof(ciops));
/* use libevent loop */
ciops.v.v0.type = LCB_IO_OPS_LIBEVENT;
ciops.v.v0.cookie = base;

ret = lcb_create_io_ops(&ioops, &ciops);
if (ret != LCB_SUCCESS) {
    fprintf(stderr, "Failed to create an IOOPS structure for libevent: %s\n", lcb_strerror(NULL, ret));
    return -1;
}
 
memset(&create_options, 0, sizeof(create_options));
/* apps instance */
create_options.v.v0.host = malloc(MAX_SERVERS_NUM * 128);
for (ptr = (char*)(create_options.v.v0.host), i = 0; cluster_servers[i] != NULL; i++) {
    memcpy(ptr, cluster_servers[i], strlen(cluster_servers[i]));
    ptr += strlen(cluster_servers[i]);
    *ptr++ = ';';   // separate IP addresses with a semicolon
}
*ptr = 0;
create_options.v.v0.user = "Administrator";
create_options.v.v0.passwd = "xxxx";
create_options.v.v0.bucket = "apps";
create_options.v.v0.io = ioops;

ret = lcb_create(&apps_instance, &create_options);
if (ret != LCB_SUCCESS) {
    fprintf(stderr, "Failed to create apps libcouchbase instance: %s\n", lcb_strerror(NULL, ret));
    return -1;
}

/* devices instance */
create_options.v.v0.bucket = "devices";
ret = lcb_create(&devices_instance, &create_options);
if (ret != LCB_SUCCESS) {
    fprintf(stderr, "Failed to create devices libcouchbase instance: %s\n", lcb_strerror(NULL, ret));
    return -1;
}

/* userdata instance */
create_options.v.v0.bucket = "userdata";
ret = lcb_create(&userdata_instance, &create_options);
if (ret != LCB_SUCCESS) {
    fprintf(stderr, "Failed to create userdata libcouchbase instance: %s\n", lcb_strerror(NULL, ret));
    return -1;
}

/* make everything synchronous */
lcb_behavior_set_syncmode(apps_instance, LCB_SYNCHRONOUS);
lcb_behavior_set_syncmode(devices_instance, LCB_SYNCHRONOUS);
lcb_behavior_set_syncmode(userdata_instance, LCB_SYNCHRONOUS);

/* 
 * Set up the Couchbase callbacks 
 */
lcb_set_configuration_callback(apps_instance, configuration_callback);
lcb_set_configuration_callback(devices_instance, configuration_callback);
lcb_set_configuration_callback(userdata_instance, configuration_callback); 

lcb_set_http_complete_callback(apps_instance, apps_complete_callback);
lcb_set_http_complete_callback(devices_instance, devices_complete_callback);
lcb_set_http_complete_callback(userdata_instance, devices_complete_callback);
    
lcb_set_store_callback(apps_instance, store_callback);
lcb_set_store_callback(devices_instance, store_callback);
lcb_set_store_callback(userdata_instance, store_callback);    

lcb_set_get_callback(devices_instance, devices_get_callback);

lcb_set_error_callback(apps_instance, error_callback);
lcb_set_error_callback(devices_instance, error_callback);
lcb_set_error_callback(userdata_instance, error_callback);

/*
 * Connect to the database
 */
 /* apps instance */
ret = lcb_connect(apps_instance);
if (ret != LCB_SUCCESS) {
    fprintf(stderr, "Failed to connect to Couchbase apps instance: %s\n", lcb_strerror(apps_instance, ret));
    return -1;
}
/* devices instance */
ret = lcb_connect(devices_instance);
if (ret != LCB_SUCCESS) {
    fprintf(stderr, "Failed to connect to Couchbase devices instance: %s\n", lcb_strerror(devices_instance, ret));
    return -1;
}
/* userdata instance */
ret = lcb_connect(userdata_instance);
if (ret != LCB_SUCCESS) {
    fprintf(stderr, "Failed to connect to Couchbase userdata_instance instance: %s\n", lcb_strerror(userdata_instance, ret));
    return -1;
}

/* Run the event loop and wait until we are connected */
// lcb_wait(apps_instance);
// lcb_wait(devices_instance);

fprintf(stderr, "Registry initialization completed.\n");
/* Registry initialization completed. */
return 0;

}

/* create the event base */ base = event_base_new(); if (!base) { fprintf(stderr, "Couldn't create an event_base. Exiting.\n"); return 1; }
/* Initialize and connect to the Registry -- after initializing the event base  */
if (registry_init(base) != 0) {
    fprintf(stderr, "Error in initializing access to Cometa Registry DB. Exiting ...\n");
    exit -1;
};

#4

Should perhaps:

lcb_io_opt_t ioops;

create_options.v.v0.io = ioops;

instead be:

lcb_io_opt_st ioops;

create_options.v.v0.io = &ioops;


#5

Solved the problem. It appears libcouchbase can only handle one instance with libevent.