text:
A newer version of this software is available
You are viewing the documentation for an older version of this software. To find the documentation for the current version, visit the Couchbase documentation home page.
This guide provides information for developers who want to use the Couchbase C SDK to build applications that use Couchbase Server.
Now that you've installed Couchbase and have created a cluster of servers, you need a client library to read and write data from the cluster. The Couchbase C client library, also known as libcouchbase, can be used from your application to access Couchbase Server.
Here's a quick outline of what you'll learn in this chapter:
Get the client library.
Build the client library from source (optional).
Write a simple program to connecting to Couchbase and save some data.
Download the latest client library from the Couchbase download
site. It is available as a source
archive in both
.zip and
Packages are provided for RedHat and Ubuntu Linux systems by providing your package manager with the Couchbase repository information. The method for installation is dependent on your platform:
You must populate RPM with a new source, which is dependent on your RedHat version:
RHEL/CentOS 5.5
shell> sudo wget -O/etc/yum.repos.d/couchbase.repo \
shell> sudo wget -O/etc/yum.repos.d/couchbase.repo \
RHEL/CentOS 6.2
shell> sudo wget -O/etc/yum.repos.d/couchbase.repo \
shell> sudo wget -O/etc/yum.repos.d/couchbase.repo \
Then to install libcouchbase with libevent backend, run:
shell> sudo yum check-update
shell sudo yum install -y libcouchbase2-libevent libcouchbase-devel
You must update the
apt-get repository to install the client library:
Ubuntu 12.04 Precise Pangolin (Debian unstable)
Also compatible with recent versions, which have
shell> sudo wget -O/etc/apt/sources.list.d/couchbase.list \
Ubuntu 11.10 Oneiric Ocelot (Debian unstable)
Also compatible with recent versions, which have
shell> sudo wget -O/etc/apt/sources.list.d/couchbase.list \
Ubuntu 10.04 Lucid Lynx (Debian stable or testing)
shell> sudo wget -O/etc/apt/sources.list.d/couchbase.list \
Also make sure you have the GPG key installed:
shell> wget -O- http://packages.couchbase.com/ubuntu/couchbase.key | sudo apt-key add -
Then to install libcouchbase with libevent backend, run:
shell> sudo apt-get update
shell> sudo apt-get install libcouchbase2-libevent libcouchbase-dev
This client library is available via a homebrew recipe. After you install homebrew, install libcouchbase:
shell> brew install \
Installation is like many common libraries, following the
make install conventions.
For libvbucket, extract the archive then
cd into the directory and run:
shell> ./configure
shell> make install
Standard configure options such as
--prefix can be passed to the configure
command. For additional information on configuration options, run./configure
with –help.
For libcouchbase, extract the archive, then cd into the directory and run:
shell> ./configure CPPFLAGS="-I/opt/couchbase/include" --disable-couchbasemock
shell> make install
--disable-couchbasemock simply disables some tests which are common during
the development of libcouchbase, but not required when installing a release.
Building and installing on Microsoft Windows requires
nmake and tools in
Microsoft Visual Studio 2010.
Open the Visual Studio Command Prompt and navigate to the directory for the
extracted archive for libcouchbase. The NMakefile defines an
INSTALL variable
C:\local. Edit the NMakefile if you want to change the installation
location. Then build and install libcouchbase:
shell> nmake -f NMakefile install
From libcouchbase version 2.1.0, you can also use CMake system to generate correct MS Visual Studio project, for example:
shell> cmake -G "Visual Studio 10"
The C client library,
libcouchbase, is a callback-oriented client which makes
it very easy to write high performance programs. There are a few ways you can
drive IO with the library. The simplest approach is to use the synchronous
interface over the asynch internals of the library. More advanced programs will
either call the
libcouchbase_wait() function after generating some operations
or drive the event loop themselves.
To connect, you first configure the connection options and then create an instance of the connection to the cluster:
struct lcb_create_st create_options;
lcb_t instance;
lcb_error_t err;
memset(&create_options, 0, sizeof(create_options));
create_options.v.v0.host = "myserver:8091";
create_options.v.v0.user = "mybucket";
create_options.v.v0.passwd = "secret";
create_options.v.v0.bucket = "mybucket";
err = lcb_create(&instance, &create_options);
if (err != LCB_SUCCESS) {
fprintf(stderr, "Failed to create libcouchbase instance: %s\n",
lcb_strerror(NULL, err));
return 1;
/* Set up the handler to catch all errors! */
lcb_set_error_callback(instance, error_callback);
* Initiate the connect sequence in libcouchbase
if ((err = lcb_connect(instance)) != LCB_SUCCESS) {
fprintf(stderr, "Failed to initiate connect: %s\n",
lcb_strerror(NULL, err));
return 1;
/* Run the event loop and wait until we've connected */
Callbacks are used by the library and are simple functions which handle the result of operations. For example:
struct lcb_create_st create_options;
lcb_t instance;
lcb_error_t err;
memset(&create_options, 0, sizeof(create_options));
create_options.v.v0.host = "myserver:8091";
create_options.v.v0.user = "mybucket";
create_options.v.v0.passwd = "secret";
create_options.v.v0.bucket = "mybucket";
err = lcb_create(&instance, &create_options);
if (err != LCB_SUCCESS) {
fprintf(stderr, "Failed to create libcouchbase instance: %s\n",
lcb_strerror(NULL, err));
return 1;
/* Set up the handler to catch all errors! */
lcb_set_error_callback(instance, error_callback);
* Initiate the connect sequence in libcouchbase
if ((err = lcb_connect(instance)) != LCB_SUCCESS) {
fprintf(stderr, "Failed to initiate connect: %s\n",
lcb_strerror(NULL, err));
return 1;
/* Run the event loop and wait until we've connected */
Callbacks can be set up for all of your operations called in libcouchbase. In the API, you'll note the use of a cookie. This is metadata from your application which is associated with the request. The libcouchbase library will not inspect any cookie or send the cookie to the server.
When you put the connect logic and the get callback together and plug them into a complete program with the include headers, you get:
#include <libcouchbase/couchbase.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static void error_callback(lcb_t instance,
lcb_error_t err,
const char *errinfo)
fprintf(stderr, "Error %s: %s", lcb_strerror(instance, err),
errinfo ? errinfo : "");
/* the callback invoked by the library when receiving a get response */
static void get_callback(lcb_t instance,
const void *cookie,
lcb_error_t error,
const lcb_get_resp_t *resp)
if (error != LCB_SUCCESS) {
fprintf(stderr, "Failed to retrieve \"");
fwrite(resp->v.v0.key, 1, resp->v.v0.nkey, stderr);
fprintf(stderr, "\": %s\n", lcb_strerror(instance, error));
} else {
fprintf(stderr, "Data for key: \"");
fwrite(resp->v.v0.key, 1, resp->v.v0.nkey, stderr);
fprintf(stderr, "\" is : ");
fwrite(resp->v.v0.bytes, 1, resp->v.v0.nbytes, stderr);
(void)cookie; /* ignore */
int main(void)
struct lcb_create_st create_options;
lcb_t instance;
lcb_error_t err;
memset(&create_options, 0, sizeof(create_options));
create_options.v.v0.host = "myserver:8091";
create_options.v.v0.user = "mybucket";
create_options.v.v0.passwd = "secret";
create_options.v.v0.bucket = "mybucket";
err = lcb_create(&instance, &create_options);
if (err != LCB_SUCCESS) {
fprintf(stderr, "Failed to create libcouchbase instance: %s\n",
lcb_strerror(NULL, err));
return 1;
/* set up the handler to catch all errors */
lcb_set_error_callback(instance, error_callback);
/* initiate the connect sequence in libcouchbase */
err = lcb_connect(instance);
if (err != LCB_SUCCESS) {
fprintf(stderr, "Failed to initiate connect: %s\n",
lcb_strerror(NULL, err));
return 1;
/* run the event loop and wait until we've connected */
/* set up a callback for our get requests */
lcb_set_get_callback(instance, get_callback);
lcb_get_cmd_t cmd;
const lcb_get_cmd_t *commands[1];
commands[0] = &cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.v.v0.key = "foo";
cmd.v.v0.nkey = 3;
err = lcb_get(instance, NULL, 1, commands);
if (err != LCB_SUCCESS) {
fprintf(stderr, "Failed to get: %s\n",
lcb_strerror(NULL, err));
return 1;
To compile this sample program, you must link to
libcouchbase :
shell> gcc -o hellocb -lcouchbase hellocb.c
This tutorial assumes you have installed libcouchbase on your systems per the installation instructions in the Getting Started section of this guide. Because the approach for building a program based on libcouchbase may vary between Linux/Mac OS and Windows, this tutorial will focus on the components of the program rather than how to build it.
If you need to set up a server node or data bucket, you can do so with Couchbase Administrative Console, Couchbase Command-Line Interface (CLI), or Couchbase REST API. For information and instructions, see:
Using the Couchbase Web Console, for information on using the Couchbase Administrative Console,
Couchbase CLI, for the command line interface,
Couchbase REST API, for creating and managing Couchbase resources.
After you've set up your Couchbase Server and installed the needed client libraries, you can compile and run the following basic program.
Before getting into a more complex example of the programming model to this library, we will walk through a straightforward example of a program which builds with libcouchbase, connects to a server, and sets and gets a value:
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
* Copyright 2012 Couchbase, Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* cc -o minimal minimal.c -lcouchbase
* cl /DWIN32 /Iinclude minimal.c lib\libcouchbase.lib
* valgrind -v --tool=memcheck --leak-check=full --show-reachable=yes ./minimal
* ./minimal <host:port> <bucket> <passwd>
* mininal.exe <host:port> <bucket> <passwd>
#include <stdio.h>
#include <libcouchbase/couchbase.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#ifdef _WIN32
#define PRIu64 "I64u"
#include <inttypes.h>
static void error_callback(lcb_t instance, lcb_error_t error, const char *errinfo)
fprintf(stderr, "ERROR: %s (0x%x), %s\n",
lcb_strerror(instance, error), error, errinfo);
static void store_callback(lcb_t instance, const void *cookie,
lcb_storage_t operation,
lcb_error_t error,
const lcb_store_resp_t *item)
if (error == LCB_SUCCESS) {
fprintf(stderr, "STORED \"");
fwrite(item->v.v0.key, sizeof(char), item->v.v0.nkey, stderr);
fprintf(stderr, "\" CAS: %"PRIu64"\n", item->v.v0.cas);
} else {
fprintf(stderr, "STORE ERROR: %s (0x%x)\n",
lcb_strerror(instance, error), error);
static void get_callback(lcb_t instance, const void *cookie, lcb_error_t error,
const lcb_get_resp_t *item)
if (error == LCB_SUCCESS) {
fprintf(stderr, "GOT \"");
fwrite(item->v.v0.key, sizeof(char), item->v.v0.nkey, stderr);
fprintf(stderr, "\" CAS: %"PRIu64" FLAGS:0x%x SIZE:%lu\n",
item->v.v0.cas, item->v.v0.flags, (unsigned long)item->v.v0.nbytes);
fwrite(item->v.v0.bytes, sizeof(char), item->v.v0.nbytes, stderr);
fprintf(stderr, "\n");
} else {
fprintf(stderr, "GET ERROR: %s (0x%x)\n",
lcb_strerror(instance, error), error);
int main(int argc, char *argv[])
lcb_error_t err;
lcb_t instance;
struct lcb_create_st create_options;
struct lcb_create_io_ops_st io_opts;
io_opts.version = 0;
io_opts.v.v0.type = LCB_IO_OPS_DEFAULT;
io_opts.v.v0.cookie = NULL;
memset(&create_options, 0, sizeof(create_options));
err = lcb_create_io_ops(&create_options.v.v0.io, &io_opts);
if (err != LCB_SUCCESS) {
fprintf(stderr, "Failed to create IO instance: %s\n",
lcb_strerror(NULL, err));
return 1;
if (argc > 1) {
create_options.v.v0.host = argv[1];
if (argc > 2) {
create_options.v.v0.user = argv[2];
create_options.v.v0.bucket = argv[2];
if (argc > 3) {
create_options.v.v0.passwd = argv[3];
err = lcb_create(&instance, &create_options);
if (err != LCB_SUCCESS) {
fprintf(stderr, "Failed to create libcouchbase instance: %s\n",
lcb_strerror(NULL, err));
return 1;
(void)lcb_set_error_callback(instance, error_callback);
/* Initiate the connect sequence in libcouchbase */
if ((err = lcb_connect(instance)) != LCB_SUCCESS) {
fprintf(stderr, "Failed to initiate connect: %s\n",
lcb_strerror(NULL, err));
return 1;
(void)lcb_set_get_callback(instance, get_callback);
(void)lcb_set_store_callback(instance, store_callback);
/* Run the event loop and wait until we've connected */
lcb_store_cmd_t cmd;
const lcb_store_cmd_t *commands[1];
commands[0] = &cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.v.v0.operation = LCB_SET;
cmd.v.v0.key = "foo";
cmd.v.v0.nkey = 3;
cmd.v.v0.bytes = "bar";
cmd.v.v0.nbytes = 3;
err = lcb_store(instance, NULL, 1, commands);
if (err != LCB_SUCCESS) {
fprintf(stderr, "Failed to set: %s\n", lcb_strerror(NULL, err));
return 1;
lcb_get_cmd_t cmd;
const lcb_get_cmd_t *commands[1];
commands[0] = &cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.v.v0.key = "foo";
cmd.v.v0.nkey = 3;
err = lcb_get(instance, NULL, 1, commands);
if (err != LCB_SUCCESS) {
fprintf(stderr, "Failed to get: %s\n", lcb_strerror(NULL, err));
return 1;
return 0;
In addition to the other sections of this manual, such as the Getting Started guide and the API reference, the libcouchbase package includes an examples directory and a tools directory. Each of these show simple Couchbase tools and an example libcouchbase programs.
On Linux you may find these examples in TODO…
Starting from the version 2.2 libcouchbase supports CRAM-MD5 authentication mechanism. Which allows to avoid passing bucket password as a plain text over the wires.
Along with this change, new setting was introduced
LCB_CNTL_FORCE_SASL_MECH. It forces a specific SASL mechanism to use
for authentication. This can allow a user to ensure a certain level of
security and have the connection fail if the desired mechanism is not available.
lcb_cntl(instance, LCB_CNTL_GET, LCB_CNTL_FORCE_SASL_MECH, "CRAM-MD5");
This tutorial assumes you have installed libcouchbase on your systems, following the installation instructions in the Getting Started section of this guide. Because the approach for building a program based on libcouchbase may vary between Linux/Mac OS and Windows, this tutorial will focus on the components of the program rather than how to build it.
The libcouchbase is written in C and can be integrated in various ways with your application. The simplest integration scenario is when your application is written in a scripting language (supported by a Couchbase client library) that already has a libcouchbase wrapper. Couchbase has built and maintains following libcouchbase-based libraries:
Users of these libraries automatically get an API, which looks natural for their platform, so that it doesn't require knowledge of libcouchbase APIs. This tutorial is mostly about two other use cases:
Add libcouchbase into an existing application to implement persistence layer. This section will contain two parts: first we will create a simple echo server written using libev library. Second, we will show how to persist each message going through the server to Couchbase.
Get complete code here: https://github.com/couchbaselabs/libev-couchbase-example
Build applications around libcouchbase. Here we'll show how to build a proxy server for regular memcached clients. Building this proxy server is just like building a moxi server, but the proxy server will be more limited more limited in abilities.
Get complete code here: https://github.com/couchbaselabs/libcouchbase-proxy-sample
Let's start with a specific existing application for this example. Our application is the asynchronous single-threaded echo server, which leverages libev to solve C10K problem and efficiently serves a huge number of concurrent connections. It should listen to the given port (in this sample 4567) and send back everything the client submitted to it.
The libev library implements reactor
pattern which uses the term
event loop to represent an entity which encapsulates the register of handlers
for various IO events and the timers. To start, we have the application code
from the main function:
int main()
struct ev_loop *loop = ev_default_loop(0);
int sd;
struct sockaddr_in addr;
struct ev_io server;
if ((sd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
fail("socket error");
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT_NO);
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sd, (struct sockaddr *) &addr, sizeof(addr)) != 0) {
fail("bind error");
if (listen(sd, 2) < 0) {
fail("listen error");
ev_io_init(&server, accept_cb, sd, EV_READ);
ev_io_start(loop, &server);
printf("Listen on %d\n", PORT_NO);
ev_run(loop, 0);
return 0;
Here we are create an event loop instance, and create and bind a new socket to
local port
PORT_NO (4567). After that we can mark this socket as listening and
ask libev to call the function
accept_cb when the socket become ready to read,
that is when the new client will come to us. The final step is to run
which does all the server interaction.
accept_cb is in charge of allocating client structures 60 the buffer for
messages. The sample is using ring buffers from the libcouchbase code for easier
managing memory for IO buffers.
void accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
struct client_s *client;
int flags;
if (EV_ERROR & revents) {
fail("got invalid event");
client = malloc(sizeof(struct client_s));
if (!client) {
fail("client watcher alloc");
if (!ringbuffer_initialize(&client->buf, BUFFER_SIZE)) {
fail("client buffer alloc");
client->naddr = sizeof(client->addr);
client->fd = accept(watcher->fd, (struct sockaddr *)&client->addr,
if (client->fd < 0) {
fail("accept error");
if ((flags = fcntl(client->fd, F_GETFL, NULL)) == -1) {
if (fcntl(client->fd, F_SETFL, flags | O_NONBLOCK) == -1) {
fail("fcntl(F_SETFL, O_NONBLOCK)");
printf("Successfully connected with client\n");
ev_io_init((ev_io *)client, client_cb, client->fd, EV_READ);
ev_io_start(loop, (ev_io *)client);
The most interesting part of the function above is in the last two lines. It
registers the new handler,
client_cb, upon reading an event for the client
socket. This handler will be called each time when the kernel receives new data
from the socket, so that it could be read with a non-blocking call.
The last snippet of our application depicts the
client_cb function, which
handles all the application logic. It reads everything from the socket if it is
ready, registers itself for write events, and then sends all the contents out to
the network. It is also the handling end of a stream situation, which means that
the client closed the connection with the Couchbase server.
void client_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
struct lcb_iovec_st iov[2];
ssize_t nbytes;
struct client_s *client = (struct client_s *)watcher;
if (EV_READ & revents) {
ringbuffer_ensure_capacity(&client->buf, BUFFER_SIZE);
ringbuffer_get_iov(&client->buf, RINGBUFFER_WRITE, iov);
nbytes = io_recvv(watcher->fd, iov);
if (nbytes < 0) {
fail("read error");
} else if (nbytes == 0) {
ev_io_stop(loop, watcher);
printf("Peer disconnected\n");
} else {
ringbuffer_produced(&client->buf, nbytes);
printf("Received %zu bytes\n", nbytes);
ev_io_stop(loop, watcher);
ev_io_set(watcher, watcher->fd, EV_WRITE);
ev_io_start(loop, watcher);
} else if (EV_WRITE & revents) {
ringbuffer_get_iov(&client->buf, RINGBUFFER_READ, iov);
nbytes = io_sendv(watcher->fd, iov);
if (nbytes < 0) {
fail("write error");
} else if (nbytes == 0) {
ev_io_stop(loop, watcher);
printf("Peer disconnected\n");
} else {
ringbuffer_consumed(&client->buf, nbytes);
printf("Sent %zu bytes\n", nbytes);
ev_io_stop(loop, watcher);
ev_io_set(watcher, watcher->fd, EV_READ);
ev_io_start(loop, watcher);
} else {
fail("got invalid event");
Again, the whole application is stored on github at https://github.com/couchbaselabs/libev-couchbase-example. Let's see it in action. To clone and build the applications, use the following commands:
~ $ git clone git://github.com/couchbaselabs/libev-couchbase-example.git
~ $ cd libev-couchbase-example/step1
step1 $ ./autogen.sh && ./configure && make
As a client for an echo application, we can build any telnet-like application. The following listing simulates two terminals by splitting them with a vertical line:
step 1 $ ./server | step1 $ telnet localhost 4567
Listen on 4567 | Trying 127.0.0.1...
Successfully connected with client | Connected to localhost.
Received 14 bytes | Escape character is '^]'.
Sent 14 bytes | Hello world!
Received 9 bytes | Hello world!
Sent 9 bytes | foo bar
Peer disconnected | foo bar
| ^]
| telnet> Connection closed.
Now that we described our application, let's integrate Couchbase as the database
using libcouchbase. The
server.c file will have some small additions. In the
main function, before initializing server socket, we will call
and assign the connection information to the server structure variable.
server.handle = storage_init(loop, "localhost:8091", "default", null);
Also in the
client_cb handler, each time libcouchbase receives data from the
client, it will send the data to Couchbase server with
storage_put where
the_key is a string
storage_put(client, the_key, val, nbytes);
Here, the initial application from step one is already using its own custom event loop to handle other IO in the application. The application could be more complex, but libcouchbase has a separate interface to inject your IO implementation into the library. In the simplest case, for example if your application is using one of the IO libraries supported by libcouchbase, you can just pass your event loop instance into the initializer, and libcouchbase won't create new one. Instead it will register all its events on this external loop. In case your application is using its own implementation of a reactor pattern, such as nginx, or you use linux epoll API, you can easily write your own IO plugin and pass it to the connection initializer.
The echo server is using libev library, and libcouchbase provides a plugin to
libev out-of-the-box. In this case we can imagine that it doesn't already have
it. In this case, we can copy the plugin from libcouchbase distribution into the
step2/lcb-plugin/ and update build files appropriately.
Now we inspect the
storage.c, where our
storage_init() and
lcb_t storage_init(struct ev_loop *loop, const char *host, const char *bucket, const char *password)
struct lcb_create_st opts;
struct lcb_create_io_ops_st io_opts;
lcb_t handle;
lcb_error_t err;
io_opts.version = 1;
io_opts.v.v1.sofile = NULL;
io_opts.v.v1.symbol = "lcb_create_libev_io_opts";
io_opts.v.v1.cookie = loop;
opts.version = 0;
opts.v.v0.host = host;
opts.v.v0.bucket = bucket;
opts.v.v0.user = bucket;
opts.v.v0.passwd = password;
err = lcb_create_io_ops(&opts.v.v0.io, &io_opts);
if (err != LCB_SUCCESS) {
error_callback(NULL, err, "failed to create IO object");
return NULL;
err = lcb_create(&handle, &opts);
if (err != LCB_SUCCESS) {
error_callback(NULL, err, "failed to create connection object");
return NULL;
(void)lcb_set_error_callback(handle, error_callback);
(void)lcb_set_store_callback(handle, storage_callback);
err = lcb_connect(handle);
if (err != LCB_SUCCESS) {
error_callback(handle, err, "failed to connect to the server");
return NULL;
return handle;
The end of the function may look familiar, but the
io_opts structure is more
interesting. It defines how to look up our custom IO plugin. The
io_opts.v.v1.sofile is set to
NULL to specify that our plugin compiled into
the current executable image. In this case,
symbol is the string name of the
function with the following signature:
lcb_error_t lcb_create_libev_io_opts(int version, lcb_io_opt_t *io, void *loop);
This initializes the IO plugin and then the
cookie will be passed to this
function as the
loop argument. You can refer to the
manpage for other ways to initialize IO subsystem.
The libcouchbase client is purely asynchronous; therefore, each data operation isplits into two parts: a function-scheduler, which validates and copies all arguments to internal buffers for further handing, and a function-callback, which will be called with the results of the operation. It is possible to implement a wrapper which will provide a more synchronous API, but it is difficult to write a library API that is both generic and efficient. Since all communication is done by using function arguments, it is easier to maintain backward compatible APIs by versioning both incoming structures and results. Let's see how we did it in our sample:
void storage_put(struct client_s *client, const char *key,
const void *val, size_t nval)
lcb_error_t err;
lcb_store_cmd_t cmd;
const lcb_store_cmd_t *cmds[] = { &cmd };
memset(&cmd, 0, sizeof(cmd));
cmd.version = 0;
cmd.v.v0.key = key;
cmd.v.v0.nkey = strlen(key);
cmd.v.v0.bytes = val;
cmd.v.v0.nbytes = nval;
cmd.v.v0.operation = LCB_SET;
err = lcb_store(client->handle, client, 1, cmds);
if (err != LCB_SUCCESS) {
error_callback(client->handle, err, "failed to schedule store operation");
void storage_callback(lcb_t instance, const void *cookie,
lcb_storage_t operation, lcb_error_t error,
const lcb_store_resp_t *resp)
struct client_s *client = (struct client_s *)cookie;
struct ev_io* watcher = (struct ev_io*)client;
char cas_str[128];
ssize_t nb;
nb = snprintf(cas_str, 128, "%"PRIu64"\n", resp->v.v0.cas);
if (nb < 0) {
fail("output CAS value");
ringbuffer_ensure_capacity(&client->out, nb);
if (ringbuffer_write(&client->out, cas_str, nb) != nb) {
fail("write CAS into the buffer");
ev_io_stop(client->loop, watcher);
ev_io_set(watcher, watcher->fd, EV_WRITE);
ev_io_start(client->loop, watcher);
Here, the
storage_put() function is a wrapper over
lcb_store(3). The
storage_put() function translates arguments to the versioned structure and
lcb_store to pass it to the library. The data won't be sent immediately,
but when the library connects to the data socket, it will be ready to accept
data. After the server processes the request, the application will be notified
asynchronously via
storage_callback. This callback will copy CAS value to the
output buffer to be sent to the client.
Time to demonstrate an application. This application is built the same as
before, except you need to navigate to
step2/ directory. As previously noted,
the script will be split to demonstrate both server and the client:
step2 $ ./server | step2 $ telnet localhost 4567
Listen on 4567 | Trying 127.0.0.1...
Successfully connected with client | Connected to localhost.
Received 14 bytes | Escape character is '^]'.
Sent 20 bytes | Hello world!
Peer disconnected | 2916447493390860288
| ^]
| telnet> Connection closed.
Now you can install
cbc tools from package
libcouchbase2-bin. If you
installed libcouchbase from source, you most likely have it already. Then you
can check that it created a key example and that the CAS values are matching:
step2 $ printf "%x\n" 2916447493390860288
step2 $ cbc cat example
"example" Size:14 Flags:0 CAS:28794d8b11a40000
Hello world!
You can use libcouchbase when you are building Couchbase-enabled application and want to bootstrap quickly. To do so you can build your application using the IO abstraction provided with libcouchbase.
In this example, we create a thin proxy application which will expose the memcached-compatible API for the system. Similar approaches exist for moxi server. Also this application will use less hard-coded logic and more look like real-life service. Full source code can be found at https://github.com/couchbaselabs/libcouchbase-proxy-sample.
For clarity, we skip parsing and initialization of the Couchbase connection from
main function. The proxy code begins in
run_proxy, which is similar to
the main function in the previous section. The important difference here is that
we are using the IO abstraction from libcouchbase, to register events, and drive
an event loop.
void run_proxy(lcb_t conn)
lcb_io_opt_t io;
struct sockaddr_in addr;
int sock, rv;
server_t server;
io = opts.v.v0.io;
info("starting proxy on port %d", port);
sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock == -1) {
fail("socket()", strerror(errno));
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
rv = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
if (rv == -1) {
rv = listen(sock, 10);
if (rv == -1) {
server.conn = conn;
server.io = io;
server.event = io->v.v0.create_event(io);
if (server.event == NULL) {
fail("failed to create event for proxy");
io->v.v0.update_event(io, sock, server.event, LCB_READ_EVENT,
&server, proxy_accept_callback);
lcb_set_error_callback(conn, error_callback);
lcb_set_get_callback(conn, get_callback);
lcb_set_store_callback(conn, store_callback);
info("use ctrl-c to stop");
As in the previous example, we create a listening socket, and then we bind a
handler to process read events. The handler is
proxy_accept_callback, and it
will be triggered for each new client. In turn it will create a new client
structure, defined as follows:
typedef struct client_st client_t;
struct client_st {
int id;
server_t *server;
int sock;
ringbuffer_t in;
ringbuffer_t out;
void *event;
This initializes input and output buffers,and makes the socket descriptors
non-blocking. At the end, the code will register the handler function
proxy_client_callback for read events, and then wait for incoming data.
The proxy implements a very limited number of protocol commands: GET, SET, and VERSION. But other commands can be easily added. Here's an example:
void proxy_client_callback(lcb_socket_t sock, short which, void *data)
struct lcb_iovec_st iov[2];
ssize_t rv;
lcb_io_opt_t io;
client_t *cl = data;
io = cl->server->io;
if (which & LCB_READ_EVENT) {
for (;;) {
/* read in chunks of BUFFER_SIZE */
ringbuffer_ensure_capacity(&cl->in, BUFFER_SIZE);
ringbuffer_get_iov(&cl->in, RINGBUFFER_WRITE, iov);
rv = io->v.v0.recvv(io, cl->sock, iov, 2);
if (rv == -1) {
if (io->v.v0.error == EINTR) {
/* interrupted by signal */
} else if (io->v.v0.error == EWOULDBLOCK) {
/* nothing to read right now */
io->v.v0.update_event(io, cl->sock, cl->event,
LCB_WRITE_EVENT, cl,
} else {
fail("read error");
} else if (rv == 0) {
/* end of stream */
io->v.v0.destroy_event(io, cl->event);
info("[%d] disconnected", cl->id);
} else {
ringbuffer_produced(&cl->in, rv);
for (;;) {
protocol_binary_request_header req;
lcb_size_t nr, sz;
char *buf;
/* make sure the buffer is aligned */
if (ringbuffer_ensure_alignment(&cl->in) != 0) {
fail("cannot align the buffer");
/* take the packet header from the buffer */
nr = ringbuffer_peek(&cl->in, req.bytes, sizeof(req));
if (nr < sizeof(req)) {
/* make sure the buffer has whole the body */
sz = ntohl(req.request.bodylen) + sizeof(req);
if (cl->in.nbytes < sz) {
/* copy packet into intermediate buffer */
buf = malloc(sizeof(char) * sz);
if (buf == NULL) {
fail("cannot allocate buffer for packet");
nr = ringbuffer_read(&cl->in, buf, sz);
if (nr < sizeof(req)) {
fail("input buffer doesn't contain enough data");
/* handle packet and deallocate the intermediate
* buffer */
handle_packet(cl, buf);
if (which & LCB_WRITE_EVENT) {
/* check if we have something to send */
ringbuffer_get_iov(&cl->out, RINGBUFFER_READ, iov);
if (iov[0].iov_len + iov[1].iov_len == 0) {
io->v.v0.delete_event(io, cl->sock, cl->event);
rv = io->v.v0.sendv(io, cl->sock, iov, 2);
if (rv < 0) {
fail("write error");
} else if (rv == 0) {
io->v.v0.destroy_event(io, cl->event);
info("[%d] disconnected", cl->id);
} else {
ringbuffer_consumed(&cl->out, rv);
io->v.v0.update_event(io, cl->sock, cl->event,
LCB_READ_EVENT, cl,
The function
proxy_client_callback logically divided into two parts.
The first part occurs when the event loop notifies us that the socket is ready
for non-blocking reading. At this point, the function tries to read all the data
available on the socket. It finds the packets and passes aligned byte arrays to
handle_packet. Once the code gets a special code from the IO subsystem get
from the IO subsystem special code, that it cannot read anything without
blocking, it stops processing and registers itself for write events, because in
nearest future, responses will appear in the output buffer.
The second part of the function reacts to write events and is much simpler. It just checks to see if there is data in the output buffer. If there is data in the output buffer, it will try to send that data to the client. If not, the functionwill unregister itself from write events to save CPU cycles.
The function
handle_packet is a good place to start playing with this example
if you'd like to add new features there. It decodes protocol packet and
translates it into libcouchbase calls.
void handle_packet(client_t *cl, char *buf)
protocol_binary_request_header *req = (void *)buf;
protocol_binary_response_header res;
union {
lcb_get_cmd_t get;
lcb_store_cmd_t set;
} cmd;
union {
const lcb_get_cmd_t *get[1];
const lcb_store_cmd_t *set[1];
} cmds;
cookie_t *cookie;
cookie = malloc(sizeof(cookie_t));
if (cookie == NULL) {
fail("cannot allocate buffer for command cookie");
cookie->client = cl;
cookie->opaque = req->request.opaque;
cookie->opcode = req->request.opcode;
memset(&cmd, 0, sizeof(cmd));
switch (req->request.opcode) {
case PROTOCOL_BINARY_CMD_GET:
cmds.get[0] = &cmd.get;
cmd.get.v.v0.nkey = ntohs(req->request.keylen);
cmd.get.v.v0.key = buf + sizeof(*req);
info("[%d] get \"%.*s\"", cl->id,
(int)cmd.get.v.v0.nkey, (char *)cmd.get.v.v0.key);
lcb_get(cl->server->conn, (const void*)cookie, 1, cmds.get);
case PROTOCOL_BINARY_CMD_SET:
cmds.set[0] = &cmd.set;
cmd.set.v.v0.operation = LCB_SET;
cmd.set.v.v0.nkey = ntohs(req->request.keylen);
cmd.set.v.v0.key = buf + sizeof(*req) + 8;
cmd.set.v.v0.nbytes = ntohl(req->request.bodylen) - 8 - ntohs(req->request.keylen);
cmd.set.v.v0.bytes = buf + sizeof(*req) + 8 + ntohs(req->request.keylen);
cmd.set.v.v0.cas = req->request.cas;
cmd.set.v.v0.datatype = req->request.datatype;
memcpy(&cmd.set.v.v0.flags, buf + sizeof(*req), 4);
cmd.set.v.v0.flags = ntohl(cmd.set.v.v0.flags);
memcpy(&cmd.set.v.v0.exptime, buf + sizeof(*req) + 4, 4);
cmd.set.v.v0.exptime = ntohl(cmd.set.v.v0.exptime);
info("[%d] set \"%.*s\"", cl->id,
(int)cmd.set.v.v0.nkey, (char *)cmd.set.v.v0.key);
lcb_store(cl->server->conn, (const void*)cookie, 1, cmds.set);
case PROTOCOL_BINARY_CMD_VERSION:
info("[%d] version", cl->id);
res.response.magic = PROTOCOL_BINARY_RES;
res.response.opcode = req->request.opcode;
res.response.keylen = 0;
res.response.extlen = 0;
res.response.datatype = PROTOCOL_BINARY_RAW_BYTES;
res.response.status = PROTOCOL_BINARY_RESPONSE_SUCCESS;
res.response.bodylen = htonl(sizeof(version_msg));
res.response.opaque = req->request.opaque;
res.response.cas = 0;
ringbuffer_ensure_capacity(&cl->out, sizeof(res));
ringbuffer_write(&cl->out, res.bytes, sizeof(res));
ringbuffer_write(&cl->out, version_msg, sizeof(version_msg));
info("[%d] unsupported command: 0x%02x", cl->id, req->request.opcode);
res.response.magic = PROTOCOL_BINARY_RES;
res.response.opcode = req->request.opcode;
res.response.keylen = 0;
res.response.extlen = 0;
res.response.datatype = PROTOCOL_BINARY_RAW_BYTES;
res.response.status = PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED;
res.response.bodylen = htonl(sizeof(notsup_msg));
res.response.opaque = req->request.opaque;
res.response.cas = 0;
ringbuffer_ensure_capacity(&cl->out, sizeof(notsup_msg) + sizeof(res));
ringbuffer_write(&cl->out, res.bytes, sizeof(res));
ringbuffer_write(&cl->out, notsup_msg, sizeof(notsup_msg));
To maintain a logical link between requests and responses for the clients, the
protocol defines a special field
opaque, which can be a special tag or
sequence number. To preserve this field in the response, we will put it into a
cookie_t structure. During the proxy initialization, we defined two
callback-functions for libcouchbase:
lcb_set_get_callback(conn, get_callback);
lcb_set_store_callback(conn, store_callback);
In this kind of application, these functions just build a protocol response from
libcouchbase return value. They also register the
proxy_client_callback on
write events to send out data recently written into the buffer.
void get_callback(lcb_t conn, const void *cookie, lcb_error_t err,
const lcb_get_resp_t *item)
cookie_t *c = (cookie_t *)cookie;
client_t *cl = c->client;
lcb_io_opt_t io = cl->server->io;
protocol_binary_response_get res;
res.message.header.response.magic = PROTOCOL_BINARY_RES;
res.message.header.response.opcode = PROTOCOL_BINARY_CMD_GET;
res.message.header.response.keylen = 0;
res.message.header.response.extlen = 4;
res.message.header.response.datatype = item->v.v0.datatype;
res.message.header.response.status = htons(map_status(err));
res.message.header.response.bodylen = htonl(4 + item->v.v0.nbytes);
res.message.header.response.opaque = c->opaque;
res.message.header.response.cas = item->v.v0.cas;
res.message.body.flags = htonl(item->v.v0.flags);
ringbuffer_ensure_capacity(&cl->out, sizeof(res.bytes) + item->v.v0.nbytes);
ringbuffer_write(&cl->out, res.bytes, sizeof(res.bytes));
ringbuffer_write(&cl->out, item->v.v0.bytes, item->v.v0.nbytes);
io->v.v0.update_event(io, cl->sock, cl->event, LCB_WRITE_EVENT,
cl, proxy_client_callback);
These are viritually all the integration points with libcouchbase. As we demonstrated, libcouchbase more than a protocol parser; it also an abstract and portable IO framework, allowing you to build asynchronous applications around Couchbase Server.
To conclude, let's run your favourite memcached client and verify our proxy. First you need to clone and build it:
$ git clone git://github.com/couchbaselabs/libcouchbase-proxy-sample.git
$ cd libcouchbase-proxy-sample
libcouchbase-proxy-sample $ make
Run the server and send couple of commands to it. We will use the dalli ruby gem here:
libcouchbase-proxy-sample $ ./proxy | $ irb
connecting to bucket "default" at "localhost:8091" | irb:001:0> require 'dalli'
starting proxy on port 1987 | true
use ctrl-c to stop | irb:002:0> m = Dalli::Client.new "localhost:1987"
[1] connected | #<Dalli::Client:0x007f716321ce20 @servers=["localhost:1987"], @options={}, @ring=nil>
[1] version | irb:003:0> m.set("foo", "bar")
[1] set "foo" | true
[1] get "foo" | irb:004:0> m.get("foo")
[1] disconnected | "bar"
The following sections provide release notes for individual release versions of Couchbase Client Library C. To browse or submit new issues, see Couchbase Client Library C Issues Tracker.
New Features and Behavior Changes in 2.2.0
Handle 302 redirects in HTTP (views and administrative requests). By
default the library follows up to three redirects. After the
limit is reached, the request is terminated with code
LCB_TOO_MANY_REDIRECTS. The limit is configurable through
LCB_CNTL_MAX_REDIRECTS. If it is set to -1, it disables the redirect
limit. The following example shows how to set the limit:
int new_value = 5;
lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_MAX_REDIRECTS, &new_value);
Issues: CCBC-169
Replace isasl with cbsasl. cbsasl implements both PLAIN and CRAM-MD5 authentication mechanisms.
LCB_CNTL_MEMDNODE_INFO command updated to include effective
SASL mechanism:
cb_cntl_server_t node;
node.version = 1;
node.v.v1.index = 0; /* first node */
lcb_cntl(instance, LCB_CNTL_GET, LCB_CNTL_MEMDNODE_INFO, &node);
if (node.v.v1.sasl_mech) {
printf("authenticated via SASL '%s'\n",
You can force a specific authentication mechanism for
the connection handle by using the
LCB_CNTL_FORCE_SASL_MECH command:
lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_FORCE_SASL_MECH, "PLAIN");
Issues: CCBC-243
Stricter, more inspectable behavior for the configuration cache. This provides a
test and an additional
lcb_cntl operation to check the status of
the configuration cache. Also, it switches off the configuration cache with
memcached buckets.
int is_loaded;
lcb_cntl(instance, LCB_CNTL_GET, LCB_CNTL_CONFIG_CACHE_LOADED, &is_loaded);
if (is_loaded) {
printf("Configuration cache saved us a trip to the config server\n");
} else {
printf("We had to contact the configuration server for some reason\n");
Fixes in 2.2.0
libuv plugin: use the same CRT for free and malloc.
Issues : CCBC-286
NOT_MY_VBUCKET responses on time-out.
Issues : CCBC-288
Do a full purge when negotiation times out. In this case we must purge the server from all commands and not simply pop individual items.
Issues : CCBC-275
Reset the server's buffers upon reconnection. This fixes a crash
experienced when requesting a new read with the previous buffer
still intact. This was exposed by calling
lcb_failout_server on a
time-out error while maintaining the same server struct.
Issues : CCBC-275
Make server buffers reentrant-safe. When purging implicit commands, we invoke callbacks that might in turn cause other LCB entry points to be invoked, which can shift the contents or positions of the ring buffers that we're reading from.
Issues : CCBC-282
Use common config retry mechanism for bad configuration cache. This uses the
same error handling mechanism as when a bad configuration has been
received from the network. New
LCB_CONFIG_CACHE_INVALID error code
to notify the user of such a situation
Issues : CCBC-278
Handle getl and unl when purging the server (thanks Robert Groenenberg).
Issues : CCBC-274
Don't fail out all commands on a time-out. Only fail those commands that are old enough to have timed out already.
Don't record and use TTP/TTR from observe. Just poll at a fixed interval, because the responses from the server side can be unreliable.
Issues : CCBC-269
Allow hooks for mapping server codes to errors. This also helps handle sane behavior if a new error code is introduced, or allow user-defined logging when a specific error code is received.
lcb_errmap_callback default_callback;
lcb_error_t user_map_error(lcb_t instance, lcb_uint16_t in)
if (in == PROTOCOL_BINARY_RESPONSE_ETMPFAIL) {
fprintf(stderr, "temporary failure on server\n");
return default_callback(instance, in);
default_callback = lcb_set_errmap_callback(conn, user_map_error);
Add an example of a connection pool. See
lcb_wait return result of wait operation instead of
lcb_get_last_error. It returns
last_error if and only if the
handle is not yet configured
Issues : CCBC-279
cbc-pillowfight: compute item size correctly during set If
minSize and
maxSize are set to the same value it can sometimes
crash since it may try to read out of memory bounds from the
allocated data buffer.
Issues : CCBC-284
Apply key prefix CLI option in cbc-pillowfight
Issues : CCBC-283
--enable-maintainer-mode. Maintainer mode enables
--enable-werror --enable-warnings --enable-debug, forces all
plugins to be installed and forces all tests, tools, and examples to
be built
LCB_MAX_ERROR to allow user-defined codes
Issues : CCBC-255
New Features and Behavior Changes in 2.1.3
Use cluster type connection for cbc-bucket-flush. Although flush command is accessible for bucket type connections, cbc-bucket-flush doesn't use provided bucket name to connect to, therefore it will fail if the bucket name isn't "default".
Allow to make connect order deterministic. It allows the user to toggle between deterministic and random connect order for the supplied nodes list. By default it will randomize the list.
Fixes in 2.1.3
Updated gtest to version 1.7.0. Fixes issue with building test suite with new XCode 5.0 version being released later this month.
Do not try to parse config for
handles. It fixes timouts for management operations (like 'cbc
bucket-create', 'cbc bucket-flush', 'cbc bucket-delete' and 'cbc
Issues : CCBC-265
Skip unfinished SASL commands on rebalance. During rebalance, it is possible that the newly added server doesn't have chance to finish SASL auth before the cluster will push config update, in this case packet relocator messing cookies. Also the patch makes sure that SASL command/cookie isn't mixing with other commands
Issues : CCBC-263
Do not allow to use Administrator account for
Fig segmentation faults during tests load of
node.js. Sets
inside_handler on
socket_connected. Previously we
were always using SASL auth, and as such, we wouldn't flush packets
from the
cmd_log using
server_send_packets (which calls
apply_want shouldn't be called more than once per
event loop entry – so this sets and unsets the
Issues : CCBC-258
Added support of libuv 0.8
Close config connection before trying next node. It will fix
asserts in case of the config node becomes unresponsive, and the
threshold controlled by
LCB_CNTL_CONFERRTHRESH and
Fixes in 2.1.2
Use bucket name in SASL if username omitted. Without this fix, you can may encounter a segmentation faults for buckets, which are not protected by a password.
Preserve IO cookie in
options_from_info when using v0 plugins
with user-provided IO loop instance. This issue was introduced in
Display the effective IO backend in
cbc-version. This is helpful
to quickly detect what is the effective IO plugin on a given
New Features and Behavior Changes in 2.1.1
Fallback to 'select' IO plugin if default plugin cannot be loaded. On UNIX-like systems, default IO backend is 'libevent', which uses third-party library might be not available at the run-time. Read in lcb_cntl(3couchbase) man page in section LCB_CNTL_IOPS_DEFAULT_TYPES about how to determine effective IO plugin, when your code chose to use LCB_IO_OPS_DEFAULT during connection instantiation. The fallback mode doesn't affect application which specify IO backend explicitly.
Issues : CCBC-246
Skip misconfigured nodes in the list. New lcb_cntl(3couchbase) added to control whether the library will skip nodes in initial node list, which listen on configuration port (8091 usually) but doesn't meet required parameters (invalid authentication or missing bucket). By default report this issue and stop trying nodes from the list, like all previous release. Read more at man page lcb_cntl(3couchbase) in section LCB_CNTL_SKIP_CONFIGURATION_ERRORS_ON_CONNECT
Issues : CCBC-192
Distribute debug information with release binaries on Windows
Issues : CCBC-245
Fixes in 2.1.1
Do not use socket after failout. Fixes segmentation faults during rebalance.
Issues : CCBC-239
Use provided credentials for authenticating to the data nodes. With this fix, it is no longer possible to use Administrator credentials with a bucket. If your configuration does so, you must change the credentials you use before applying this update. No documentation guides use of Administrator credentials, so this change is not expected to affect few, if any deployments.
Do not disable config.h on UNIX-like platforms. It fixes build issue, when application is trying to include plugins from the tarball.
Issues : CCBC-248
New Features and Behavior Changes in 2.1.0
New backend
select. This backend is based on the select(2) system call and its
Windows version. It could be considered the most portable solution and is
available with the libcouchbase core.
API for durability operations. This new API is based on
lcb_observe(3) and
allows you to monitor keys more easily. See the man pages
lcb_durability_poll(3) and
lcb_set_durability_callback(3) for more info.
Issues : CCBC-145
New backend
libuv. This backend previously was part of the
couchnode project and is now available
as a plugin. Because libuv doesn't ship binary packages there is no binary
libcouchbase2-libuv. You can build plugin from the source
distribution, or through the
libcouchbase-dev or
libcouchbase-devel package
on UNIX like systems.
Issues : CCBC-236
New backend
iocp. This is a Windows specific backend, which uses "I/O
Completion Ports". As a part of the change, a new version of plugin API was
introduced which is more optimized to this model of asynchronous IO.
New configuration interface
lcb_cntl(3) along with new tunable options of the
library and connection instances. In this release the following settings are
available. See the man page for more information and examples.:
LCB_CNTL_OP_TIMEOUT operation timeout (default 2.5 seconds)
LCB_CNTL_CONFIGURATION_TIMEOUT time to fetch cluster configuration. This is similar to a connection timeout (default 5 seconds)
LCB_CNTL_VIEW_TIMEOUT timeout for couchbase views (default 75 seconds)
LCB_CNTL_HTTP_TIMEOUT timeout for other HTTP operations like RESTful flush, bucket creating etc. (default 75 seconds)
LCB_CNTL_RBUFSIZE size of the internal read buffer (default 32768 bytes)
LCB_CNTL_WBUFSIZE size of the internal write buffer (default 32768 bytes)
LCB_CNTL_HANDLETYPE type of the
lcb\_t handler (readonly)
LCB_CNTL_VBCONFIG returns pointer to VBUCKET_CONFIG_HANDLE (readonly)
LCB_CNTL_IOPS get the implementation of IO (lcb_io_opt_t)
LCB_CNTL_VBMAP get vBucket ID for a given key
LCB_CNTL_MEMDNODE_INFO get memcached node info
LCB_CNTL_CONFIGNODE_INFO get config node info
LCB_CNTL_SYNCMODE control synchronous behavior (default LCB_ASYNCHRONOUS)
LCB_CNTL_IP6POLICY specify IPv4/IPv6 policy (default LCB_IPV6_DISABLED)
LCB_CNTL_CONFERRTHRESH control configuration error threshold (default 100)
LCB_CNTL_DURABILITY_TIMEOUT durability timeout (default 5 seconds)
LCB_CNTL_DURABILITY_INTERVAL durability polling interval (default 100 milliseconds)
LCB_CNTL_IOPS_DEFAULT_TYPES get the default IO types
LCB_CNTL_IOPS_DLOPEN_DEBUG control verbose printing of dynamic loading of IO plugins.
Fixes in 2.1.0
Fixed bug when
REPLICA_SELECT didn't invoke callbacks for negative error codes
Issues : CCBC-228
Fixed bug when
LCB_REPLICA_FIRST fails if first try does not return key
Issues : CCBC-229
Known Issues in 2.1.0
From the release the 2.1.0 package
libcouchbase2 will not install an IO
backend automatically. If you are upgrading, there are no changes because you
have already
libcouchbase2-libev or
libcouchbase2-libevent packages
installed. For new installations, a backend must be selected for the client
library to work correctly.
If for example you are using the PHP SDK, the old way, which works for pre-2.1.0 versions is:
# DEB-based systems
shell> sudo apt-get install libcouchbase2 libcouchbase-dev
# RPM-based systems
shell> sudo yum install libcouchbase2 libcouchbase-devel
But a more explicit way to do this, which works for all versions (including 2.1.0) is:
# DEB-based systems
shell> sudo apt-get install libcouchbase2-libevent libcouchbase-dev
# RPM-based systems
shell> sudo yum install libcouchbase2-libevent libcouchbase-devel
New Features and Behavior Changes in 2.0.7
lcb\_get\_replica(). Now it is possible to choose between three
LCB_REPLICA_FIRST : Previously accessible and now the default, the caller will
get a reply from the first replica to successfully reply within the timeout for
the operation or will receive an error.
LCB_REPLICA_ALL : Ask all replicas to send documents/items back.
LCB_REPLICA_SELECT : Select one replica by the index in the configuration
starting from zero. This approach can more quickly receive all possible replies
for a given topology, but it can also generate false negatives.
Note that applications should not assume the order of the replicas indicates more recent data is at a lower index number. It is up to the application to determine which version of a document/item it may wish to use in the case of retrieving data from a replica.
Issues : CCBC-183
New Features and Behavior Changes in 2.0.6
Added an example to properly use the bucket credentials for authentication instead of administrator credentials
Issues : CCBC-179
Add Host header in http request http://cbugg.hq.couchbase.com/bug/bug-555 points out that Host is a required field in HTTP 1.1
Issues : CCBC-201
Fixes in 2.0.6
Fix segfault when rebalancing. When a (!connected) server is reconnected, the tasks in its "pending" buffer will be moved into "output" buffer. If its connection is broken again immediately, relocate_packets() will go to wrong path.
Issues : CCBC-188
Don't try to switch to backup nodes when timeout is reached
Issues : CCBC-202
Fix compile error with sun studio.
"src/event.c", line 172: error: statement
not reached (E_STATEMENT_NOT_REACHED)
Don't invoke HTTP callbacks after cancellation, because user code might assume a previously-freed resource is still valid
Check if SASL struct is valid before disposing
Issues : CCBC-188
example/yajl/couchview.c: pass cookie to the command Fixes coredump when executing./examples/yajl/couchview
New Features and Behavior Changes in 2.0.5
Fixes in 2.0.5
Try to search the –libdir for modules if dlopen fails to find the module in the default library path
New compat mode (experimental) for configuration caching. See man lcb_create_compat
Issues : CCBC-190
Fix reconnecting issues on windows (http://review.couchbase.org/25170 and http://review.couchbase.org/25155)
Fix build on FreeBSD (http://review.couchbase.org/25289)
Fixes in 2.0.4
Build error on solaris/sparc: -Werror=cast-align
Issues : CCBC-178
Fixed illegal memory access in win32 plugin
Issues : CCBC-147
Work properly on systems where EWOULDBLOCK != EAGAIN
Issues : CCBC-175
The library stops iterating backup nodes list if the next one isn't accessible.
Issues : CCBC-182
The bootstrap URI is not parsed correctly
Issues : CCBC-185
Segmentation fault when the hostname resolved into several addresses and first of them reject couchbase connections.
Issues : CCBC-180
New Features and Behavior Changes in 2.0.3
Add a new library: libcouchbase_debug.so (see include/libcouchbase/debug.h) which is a new library that contains new debug functionality.
Added manual pages for the library.
Fixes in 2.0.3
Observe malfunctions in the case of multiple keys and server failure.
Issues : CCBC-155
Reset internal state on lcb_connect(). Allow caller to use lcb_connect() multiple times to implement reconnecting using the same lcb_t instance. Also it sets up the initial-connection timer for users who don't use lcb_wait() and drive IO loop manually.
Issues : CCBC-153
Invalid read in libevent plugin, when the plugin compiled in 1.x mode
Issues : CCBC-171
Shrink internal lookup tables (and reduce the size of lcb_t)
Issues : CCBC-156
Fixes in 2.0.2
Document LCB_SERVER_BUG and LCB_PLUGIN_VERSION_MISMATCH. Enhance the lcb_strerror test to detect undocumented error codes.
Commands sent to multiple servers fail to detect the respose if mixed with other commands.
Issues : CCBC-150
Under high load the library could generate LCB_ETIMEDOUT errors without reason owing to internal limitations.
Issues : CCBC-153
Cancellation of the HTTP request might lead to memory leaks or to segfaults (2e3875c2).
Issues : CCBC-151
New Features and Behavior Changes in 2.0.1
Fixes in 2.0.1
Fix a memory leak on the use of http headers
Issues : CCBC-130
libev-plugin: delay all timers while the loop isn't active. It will fix LCB_ETIMEOUT in the following scenario:
connect the instance
sleep for time greater than default timeout (e.g. 3 seconds)
schedule and execute a command (it will be timed out immediately)
Do not abort when purging SASL commands
Issues : CCBC-136
Fix possible SEGFAULT. Not-periodic timers are destroyed after calling user's callback, after that library performed read from freed pointer.
Compensate for cluster nodes lacking couchApiBase
Issues : CCBC-131
Ensure HTTP works even when the network may be unreliable. This changeset encompasses several issues which had been found with HTTP requests during network errors and configuration changes. Specifically some duplicate code paths were removed, and the process for delivering an HTTP response back to the user is more streamlined.
libev-plugin: reset IO event on delete. We need to reset it, because it might be re-used later
Make library C89 friendly again
New Features and Behavior Changes in 2.0.0
Fixes in 2.0.0
Minor update of the packaging layout:
libcouchbase-all package comes without version
extract debug symbols from libcouchbase-{bin,core} to libcouchbase-dbg package
Install unlock callback in synchronous mode
New Features and Behavior Changes in 2.0.0beta3
Try all known plugins for LCB_IO_OPS_DEFAULT in run time
Allow to use 'cbc-hash' with files
Create man pages for cbc and cbcrc
Use dynamic versioning for plugins
Lookup the plugin symbol also in the current executable image.
Issues : CCBC-114
Allow the user to specify a different hash key. All of the data operations contains a hashkey and nhashkey field. This allows you to "group" items together in your cluster. A typical use case for this is if you're storing lets say data for a single user in multiple objects. If you want to ensure that either all or none of the objects are available if a server goes down, it could be a good idea to locate them on the same server. Do bear in mind that if you do try to decide where objects is located, you may end up with an uneven distribution of the number of items on each node. This will again result in some nodes being more busy than others etc. This is why some clients doesn't allow you to do this, so bear in mind that by doing so you might not be able to get your objects from other clients.
Issues : CCBC-119
Add documentation about the error codes
Issues : CCBC-87
Add lcb_verify_compiler_setup(). This function allows the "user" of the library to verify that the compiler use a compatible struct packing scheme.
Fixes in 2.0.0beta3
lcb_error_t member in the http callbacks shouldn't reflect the HTTP response code. So the error code will be always LCB_SUCCESS if the library managed to receive the data successfully.
Issues : CCBC-118
Fix cbc-bucket-create. `sasl-password' is misspelled, and it fails to parse the command line option.
Remove libtool version from the plugins
Do not allow admin operations without authentication
check for ewouldblock/eintr on failed send
Purge stale OBSERVE packets
Issues : CCBC-120
Allow to use gethrtime() from C++
Remove unauthorized asserion (d344037). The lcb_server_send_packets() function later check if the server object connected and establish connection if not (with raising possible errors)
Issues : CCBC-113
Don't use the time_t for win32. When compiling from php it turns out that it gets another size of the time_t type, causing the struct offsets to differ.
Reformat and refactor lcb_server_purge_implicit_responses:
move packet allocation out of GET handler
dropping NOOP command shouldn't return error code
Issues : CCBC-120
Try to switch another server from backup list on timeout
Issues : CCBC-122
Timer in libev uses double for interval. Ref: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#code_ev_timer_code_relative_and_opti
Fix illegal memory access. Reconnect config listener if the config connection was gone without proper shutdown.
Issues : CCBC-104
Fix using freed memory (was introduced in 4397181)
Return zero from do_read_data() if operations_per_call reached. The `operations_per_call' limit was introduced to prevent from freezing event loop. But in the function variable rv could store two different results and in case of reaching this limit it is returning number of the processed records, which is wrong. The function should return either zero (success) or non-zero (failure).
Issues : CCBC-115
New Features and Behavior Changes in 2.0.0beta2
Implement a new libev plugin. It is compatible with both libev3 and libev4.
Allow libcouchbase to connect to an instance without specifying bucket. It is useful when the bucket not needed, e.g. when performing administration tasks.
Allow users to build the library without dependencies. For example, without plugins at all. This may be useful if the plugin is implemented by or built into the host application.
Allow users to use environment variables to pick the event plugin
Add a new interface version for creating IO objects via plugins
Allow to disable CXX targets
Allow users to install both libraries (2.x and 1.x) on the same system.
Cleanup HTTP callbacks. Use the same callbacks both for Management and View commands, and rename them to lcb_http_complete_callback and lcb_http_data_callback.
Add support for raw http requests. libcouchase already contains all the bits to execute a raw http request, except for the possibility to specify a host:port, username and password.
Make the content type optional for lcb_make_http_request()
Fixes in 2.0.0beta2
Fix invalid memory access in cbc tool. Affected command is cbc-bucket-create
Search ev.h also in ${includedir}/libev
Fix password memory leak in http.c (7e71493)
lcb_create: replace assert() with error code
Breakout event loop in default error_callback. This provides better default behavior for users who haven't defined global error callback.
Issues : CCBC-105
Fix linked event/timer lists for win32
Issues : CCBC-103
Fix SEGFAULT if IO struct is allocated not by the lcb_create()
Fix memory leak after an unsuccessful connection
lcb_connect() should honor the syncmode setting. Automatically call lcb_wait() when in synchronous mode
New Features and Behavior Changes in 2.0.0beta
Bundle Windows packages as zip archives
Refactor the API. This is a full redesign of the current libcouchbase API that'll allow us to extend parts of the API without breaking binary compatibility. Also it renames all functions to have lcb prefix instead of libcouchbase and LCB/LIBCOUCHBASE in macros.
Implement getter for number of nodes in the cluster: lcb_get_num_nodes()
Add lcb_get_server_list() to get current server list
Deliver HTTP headers via callbacks
Implement RESTful flush in the cbc toolset
Merge lcb_get_locked into lcb_get function
Bundle libvbucket
Fixes in 2.0.0beta
Fix a problem with allocating too few slots in the backup_nodes. Fixes illegal memory access.
Include sys/uio.h. Needed by OpenBSD
--enable-fat-binary. Helps to solve issues when linking with fat
binaries on MacOS.
Differentiate between TMPFAILs. This allows a developer to know if the temporary condition where the request cannot be handled is due to a constraint on the client or the server.
Issues : CCBC-98
Correct buffer length for POST/PUT headers
Issues : CCBC-96
Fix switching to backup node in case of server outage
Issues : CCBC-91
Fix locking keys in multi-get mode
Release the memory allocated by the http parser
Issues : CCBC-89
Fix initialization of backup nodes array. The code switching nodes relies on NULL terminator rather than nbackup_nodes variable. Fixes illegal memory access.
Issues : CCBC-90
Default to IPv4 only
Issues : CCBC-80
Reset timer for commands with NOT_MY_VBUCKET response
Issues : CCBC-91
Sync memcached/protocol_binary.h. Pull extra protocol_binary_datatypes declarations.
Fix bug where HTTP method is not set
Don't try to put the current node last in the backup list. This may cause "duplicates" in the list if the REST server returns another name for the server than you used. Ex: you specify "localhost" and the REST response contains 127.0.0.1
Release ringbuffer in lcb_purge_single_server
Issues : CCBC-92
Fixes in 1.1.0dp9
New Features and Behavior Changes in 1.1.0dp8
Allow the user to get the number of replicas using libcouchbase_get_num_replicas()
Separate HTTP callbacks for couch and management requests
Implement read replica
Issues : CCBC-82
Let users detect if the event loop running already using libcouchbase_is_waiting() function.
Add OBSERVE command
Issues : CCBC-15
Allow users to specify content type for HTTP request.
Allow a user to breakout from the event loop in callbacks using libcouchbase_breakout()
New cbc commands and options:
cbc-view (remove couchview example)
Add -p and -r options to cbc-cp to control persistence (uses OBSERVE internally)
Allow the client to specify the verbosity level on the servers using lcb_set_verbosity() function.
Implement general purpose timers. It is possible for users to define their own timers using libcouchbase_timer_create() function. (See headers for more info). Implement multiple timers for windows
Issues : CCBC-85
Fixes in 1.1.0dp8
Claim that server has data in buffers if there are HTTP requests pending. Without this patch the event loop can be stopped prematurely.
Make libcouchbase_wait() re-entrable
Fix to handle the case when View base doesn't have URI schema.
Bind timeouts to server sockets instead of commands. This means that from this point timeout interval will be started from the latest IO activity on the socket. This is a behavior change from the 1.0 series.
Use separate error code for ENOMEM on the client
Issues : CCBC-77
New Features and Behavior Changes in 1.1.0dp7
Implement function to execution management requests. Using libcouchbase_make_management_request() function you can configure the cluster, add/remove buckets, rebalance etc. It behaves like libcouchbase_make_couch_request() but works with another endpoint.
Add support for notification callbacks for configuration changes. Now it is possible to install a hook using function libcouchbase_set_configuration_callback(), and be notified about all configuration changes.
Fixes in 1.1.0dp7
New Features and Behavior Changes in 1.1.0dp6
Implement 'help' command for cbc tool
Issues : RCBC-71
Fixes in 1.1.0dp6
Undefine NDEBUG to avoid asserts to be optimized out
Fix compilation on macosx with gtest from homebrew
Issues : RCBC-72
Close dynamic libraries. Fixes small memory leak
Issues : RCBC-70
Include types definitions for POSIX systems. Fixes C++ builds on some systems.
Issues : RCBC-63
Fix win32 builds:
Add suffix to cbc command implementations;
Fix guards for socket errno macros;
Define size_t types to fix MSVC 9 build;
MSVC 9 isn't C99, but has stddef.h, so just include it.
New Features and Behavior Changes in 1.1.0dp5
Fixes in 1.1.0dp5
Fixes in 1.1.0dp4
New Features and Behavior Changes in 1.1.0dp3
Implement GET_LOCKED (GETL) command
Issues : CCBC-68
Implement UNLOCK_KEY (UNL) command
Issues : CCBC-68
Fixes in 1.1.0dp3
Timeouts can occur during topology changes, rather than be correctly retried. Send the retry-packet to new server
Issues : CCBC-64
Fix ringbuffer_memcpy() (36afdb2). Fix ringbuffer_is_continous().
A hang could occur in libcouchbase_wait() after the timeout period. Check for breakout condition after purging servers
Issues : CCBC-62
Destroy view requests items when server get destroyed. Fixes memory leaks.
A fix for a buffer overflow with the supplied password as has been integrated. While it is a buffer overflow issue, this is not considered to be a possible security issue because the password to the bucket is not commonly supplied by an untrusted source
Issues : RCBC-33
A small memory leak can occur with frequent calls to libcouchbase_create() and libcouchbase_destroy()
Issues : CCBC-65
Use vbucket_found_incorrect_master() to get correct server index during relocating buffers. Pick up cookies from pending buffer unless node connected.
Do not call View callbacks for cancelled requests
hashset.c: iterate over whole set on rehashing. Fixes memory leaks related to hash collisions (905ef95)
Fixes in 1.1.0dp2
Don't wait for empty buffers. If called with no operations queued, libcouchbase_wait() will block forever. This means that a single threaded application that calls libcouchbase_wait() at different times to make sure operations are sent to the server runs the risk of stalling indefinitely. This is a very likely scenario.
Issues : CCBC-59
Don't define size_t and ssize_t for VS2008
Fix segfault while authorizing on protected buckets (211bb04)
New Features and Behavior Changes in 1.1.0dp
libcouchbase_make_couch_request() function. See the associated
documentation and header files for more details.
Fixes in 1.1.0dp
Request the tap bytes in a known byte order (adf2b30)
Issues : MB-4834
Check for newer libvbucket


text:
- Women
- Women
- Men
- Men
- Children
- Children
- Accessories
- Sports
- Sports
- Atmosphere
- Atmosphere
- Clearance
- Blog
- Brands
You must be well equipped to enjoy camping! The PocketRocket 2 canister stove will be very useful for your outdoor activities.
Please note that store inventory is updated online every 24 hours. As a result, do not hesitate to contact the store before going to confirm product availability. Inventory may vary by store.
To view in store inventory, please enter a postal code, city or address
2019 © FGL Sports Ltd. All rights reserved.

subset: commoncrawl


text:
Fishfinders / GPSGarmin GPSMAP 840xs Chartplotter Fishfinder w/ USA Charts
Garmin GPSMAP 840xs Chartplotter Fishfinder Combo with USA Charts (Mount & Cable Only)
DetailsGPSMAP 840xs w/US Coastal & LakeVu Maps - No Transducer
The 8" color Garmin GPSMAP 840xs keyed chartplotter/sonar combo includes US Coastal BlueChart g2 US LakeVu HD maps and built-in 10 Hz GPS/GLONASS. Supports your choice of any compatible Garmin transducer, including 50/200 kHz, 77/200 kHz, Garmin DownVu scanning sonar with CHIRP technology, even CHIRP. For an ultra clear sonar picture of objects, structure and fish that pass below (DownVu) and to the sides (SideVu) of the boat, add the optional GCV 10 black box sonar for both DownVu Garmin and SideVu scanning sonar with CHIRP technology (sold separately). Sonar-recording capability saves digital sonar information. Wirelessly connect to Apple iOS device for BlueChart Mobile.
- 8" color SVGA display
- Includes US Coastal BlueChart g2 and US LakeVu HD maps
- Built-in Garmin HD-ID and DownVu scanning sonar with CHIRP technology for a nearly photographic view of structure under boat (all-in-one transducer sold separately)
- Supports your choice of any compatible Garmin transducer, including 50/200 kHz, 77/200 kHz, DownVu, even CHIRP
- Supports GCV 10 black box sonar that adds both DownVu and Garmin SideVu scanning sonar with CHIRP technology (sold separately)
- Transmit power: 1kW RMS (8000W peak-to-peak); CHIRP: 600W RMS (4800W peak-to-peak)
- Includes water surface temperature
- Capable of 1 kW RMS, 8,000W peak-to-peak and 600W CHIRP
- High-sensitivity internal10 Hz GPS/GLONASS provides position and heading updates 10 times per second
- NMEA 2000 support for autopilot capability, engine data, SiriusXM weather and more
- Sonar recording
- Wirelessly connect to Apple iOS device for BlueChart Mobile
- Flat, flush and bail mounting options
- 2 SD data card slots for gigabytes of storage
Package Includes
Package Includes:
- GPSMAP 840xs preloaded with LakeVu HD and BlueChart g2 coastal maps
- Power/data cable
- Bail mount
- Flush mount
- Protective cover
- Documentation
You May Also Be Interested In...
- Wrist / Fitness GPS
- Automotive GPS Units
- Handheld GPS Units
- Chartplotters / GPS
- Fishfinders / GPS
- Motorcycle / ATV GPS
- Two-Way Radio / GPS
- Safety & Tracking
- Camping & Outdoors
"Great selection, unbeatable prices, fast shipping. I am extremely happy with Tiger GPS and am recommending them to everyone I know."
- Gary, West Virginia
"Prompt shipment, great communication and a willingness to work for the customer. I would definitely highly recommend Tiger GPS!"
- Karen, California
"It arrived earlier than I expected. I also like the fact that I got e-mail from them confirming my order and giving me their contact info right away. It seemed personalized which I like."
- Stephen, Massachusetts
"The most informative site I have come across. Prices are amazing too - not sure why you would shop for GPS anywhere else."
- Wendy, Louisiana
"These guys know their stuff. They answer their phone right away, and the knowledgeable reps helped me pick the right GPS and even saved me some money!"
- Robert, New York
"No other site is willing to ship to a military APO address, and GPS is crucial out here. Great prices - thank you for supporting the troops."
- Edwin, USMC in Iraq


text:
Office 365
Use it anywhere and anytime you need, from any of your devices
Office 365 enables you to share your emails, schedules, files with your colleagues wherever they are. It is convenient and secure.
50GB of email capacity!
50GB of capacity is provided for each account. You can use email, schedule, and contact anytime anywhere, inside or outside the company, domestic or overseas.
Various functions in one service!
Various functions crucial for business, including email, schedule, and the latest versions of Microsoft products, are combined in Office 365.
Ability to work and revise from tablets!
Ideal for those who often need to make documents revisions from tablets.
What is Office 365?
A business standard cloud service by Microsoft Office. More than 80% of companies are using Office 365* . Large numbers of customers are moving their business platform to cloud.
Microsoft 365 enables people to work not only from computers but also tablets or smartphones, anywhere and anytime. Ideal for companies going global.
* Information from Microsoft as of October 2014
Providing Microsoft Office Suite (Word, Excel, PowerPoint, etc.) as a cloud service
Exchange Online
A cloud service providing a 50GB mailbox, schedule sharing, and reservation tools
SharePoint Online
A cloud service providing information sharing site and in-house portal
OneDrive for Business
A secure cloud storage for business people. A large capacity of 1TB giving you smooth access through tablets. Capabilities for collaborative editing are also provided.
Skype for Business Online
A cloud service providing instant message and presence function
Office 365 Extra File Storage
Ability to increase SharePoint Online capacity in 1GB increments
Exchange Online Archiving
Provide mail archive
Azure Rights Management
These settings can be applied to Office files: access/editing authority, authority period of validation, print/copy restriction.
Add on
KDDI Business ID
A tool to enhance security by setting user-specific access location limitation or multifactor authentication.


text:
Cowboys Lose Leading Tackler Lee to Toe Injury
IRVING, Texas (AP) - Dallas Cowboys leading tackler Sean Lee has been placed on injured reserve and will miss the rest of the season because of a right big toe injury.
Coach Jason Garrett said Wednesday that Lee will have surgery in the "next week or so." Garrett says an MRI showed ligament damage that will require the surgery and end hopes of Lee possibly being able to return in four to six weeks.
Lee, a third-year pro, also calls the defensive signals for the Cowboys. The Dallas Cowboys signed veteran linebacker Ernie Sims, who played 13 games last year for Indianapolis.
Dallas also put punter Chris Jones on injured reserve. The Cowboys host the Giants this Sunday.
Copyright 2012 by The Associated Press. All rights reserved. Material may not be redistributed.


text:
Welcome to the Home Page of the
Application Technology Research Unit
The Application Technology Research Unit (ATRU) utilizes a multi-disciplinary approach in developing methods to enhance crop protection while safeguarding environmental quality, food and worker safety.
Personnel located in Wooster, OH and Toledo, OH bring together scientific principles from engineering, entomology, plant pathology and horticulture while conducting on-site, on-farm research in nurseries and greenhouses.
Develop technologies to improve the accuracy of pesticide, water, and fertilizer delivery systems.
show me
|Horticultural Insects
Improve knowledge and management of Japanese Beetle, White Grubs, Black Vine Weevil, and Emerald Ash Borer in nursery crops.
|Plant Pathology
Identify pathogens and fungicide residue using Cold Field-Emission Electron Beam Analysis.
|Greenhouse Production Research(Toledo,OH)
Study greenhouse floral production through the use of soilless media and hydroponics systems.
|IR-4 Food Use and Ornamentals
Pesticide registration and label expansion for ornamental and food-use crops.


text:
As you can see in the video and in these two images, there are many different complexity stages when drawing a house.
Now it's your turn to experiment with creating objects using those basic shapes. How far can you reduce an object? Remember the bike or the car?
So, take your sketchbook and pick an object on your desk.
- Which basic shapes can you identify?
- Draw the object in a reduced manner and take a picture.
- Then, go ahead and add details (using the basic shapes).
- Take another picture to compare the two drawings and upload them into your journal. Which one do you like better?
- Have a look at other journal entries and let them know which one you think is better and why.


text:
Clearly, this isn't what you were hoping to find.
Most likely you were hoping to view a Nxtbook that either isn't live yet, because it's very new, or one that is so old that it's no longer live. If it's the former, please be patient and try again later. If it's the latter, well, we're sorry. Our publishers have the ability to keep books live for a very long time, but eventually, we all clean house, you know?
But then again, it might just be a completely random event that brought you here. Who knows?
At any rate, feel free to browse around the site for more content or information about Nxtbook Media.


text:
Metallic Spray Paint
by Krylon
For a bright, shiny, durable finish on almost any surface. Ideal for holiday decorations, jewelry, home decor accents, or wherever a brilliant finish is desired. Quick and easy application fast-drying, extra-durable finish.
Ask a question about Metallic Spray Paint Ask a question about this product | See all questions & answers (1)
Average User Rating: Based on (3 Reviews)
5 3
~Amy~ from New York says:
First off I need to say that finding glossy copper spray is almost impossible to find in my area, but then I remembered Mister Art,com and Voila!! There is was, I ordered it, and it arrived within 3...[more]
Please wait...
You May Also Like...
How to get VIP Club Prices
Anyone can be a VIP Member with:
Only $25/year
Product Questions and Answers
Ask a QuestionAsk a Question
What kinds of surfaces will it adhere to: plastic, glass, or metal?- Asked by Pat King on 22-Nov-13
It is enamel, which sticks to just about any surface, except perhaps plastic, as Krylon has a special line called Fusion which is expressly for plastic, but I don't believe there are metallic colors in the Fusion.- Answered by MisterArt on 22-Nov-13
Ask a Question About Metallic Spray Paint
Your email will not be shared. We will only use your email address to respond to your question. When asking your question, please be as descriptive as possible, it will allow us to give you the most accurate answer possible.
Please wait...
Please wait...


text:
Location Pin
Ashburn, VA
We help the right members find you.
Time-saving features make it easy.
We're always here to help you succeed.
It's affordable.
There was a problem, please try again.
You must choose at least one topic.
You can only choose up to 15 topics.
There was a problem, please try again.
You can only choose up to 15 topics.
"This is a group for anyone interested in hiking, rock climbing, camping, kayaking, bouldering, etc. All skill levels are welcome. I started this group to meet other outdoor enthusiasts. Looking forward to exploring the outdoors with everybody."
"Calling all Chihuahua owners! I'd love for my Chihuahua Becky to meet other Chihuahuas and other small dogs! We'll meet once a week at the park to get together and let our dogs play. We can also meet at the Captain's Table down the street (they allow dogs on their patio!) for some food and drink afterward."
"Let's get together for affordable activities in our neighborhood, like going to storytime at the library, having picnics at McCarren Park, and play dates in our homes. We can also have events for just the ladies, like moms night-out, movies, dinner, and anything else that looks like fun."
errorPlease write at least 50 characters.
We review all Meetups based on our Community Guidelines.
Your name is public. We'll use your email address to send you updates, and your location to find Meetups near you.
When you "Continue", you agree to Meetup's Terms of Service. We will manage information about you as described in our Privacy Policy, and Cookie Policy.
By clicking "Continue", you agree to our Terms of Service, Privacy Policy, and Cookie Policy.
Already a member?
Log in.
Or sign up with email
Already a member? Log in.


text:
- Reviews
- Ingredients
- Usage Faqs
Usage & FaqsUse ½ capful in the rinse cycle of your laundry load for softening and static removal. Safe for all washable fabrics. Not for use on children's sleepwear or items labeled flame retardant.COMMON QUESTIONSQ. Is your Fabric Softener safe to use in high efficiency washing machines?A. Yes.Q. Can I use your fabric softener on a "no softeners" fabric such as workout clothes or baby sleep wear?A. We do not recommend using our fabric softener on clothing items that state to not use fabric softeners when laundering. Our Fabric softener works to soften and protect your clothing from static by coating the fabric. This action would render any quick dry fabric to not dry quickly, "breathable" fabric to be less breathable and any flame retardant fabric to not be flame retardant.


text:
Tuesday, April 10, 2012
Grousefull-2 - 3 - 4
This appeared in Bombay Times today....
Money down the tube….?
When one watches seriously awful movies that go all over the place without going anywhere, it hurts! I watched 'Housefull-2' at a reasonably packed multiplex, and was both bewildered and astonished. Why bewildered? Because I actually heard a few people laughing! That too at some of the most ludicrous scenes, like a particularly nasty one in which Mithun Chakraborthy is shown running around a tree with an English maid. Nothing wrong with it…. except that the maid is played by a dwarf. And the offensive 'joke' revolves around her physical stature. Surely, as senior an actor as Mithun, could have refused to enact such an insensitive scene? There are enough obligatory messages that assure audiences no animals have been harmed during the shoot, and that cigarette smoking is injurious to health. What about somebody objecting to the cruel projection of people with physical problems. There were several distasteful jibes which are blatantly racist /sexist. Like referring to a dark complexioned man as a negro and implying his wife had slept with a fair complexioned chap to produce their son( Shreyas Talpade).Most of the humour is off-colour and far-from-funny. It's the vulgar cracks in our movies that need better monitoring. Cracks, that display our deep rooted prejudices so brazenly. Of course, the four over age and over grown 'boys' in the film have done their best with the lousy material and put in spirited performances despite the complete absence of any logic or even basic decency. Take the 'painfully' long drawn out sequence involving an alligator biting Riteish's bottom and a python going for Shreyas's crotch .The absurd movie hurtles along on nothing more than koila gags. In all probability, it will be declared a huge hit. Which will provide the green signal to make Housefull-3. Aaaaargh!
Finally managed to catch up with Agent Vinod three weeks after its launch. And once again, I was bewildered and amused, but for entirely different reasons.Why had this slick and stylish film been savaged and dismissed? There wasn't a single dull or clumsy moment and the pace was breathless. Saif retained his positioning as one of the most sophisticated stars in Bollywood, with a witty, tongue-in-cheek performance in the best traditions of international spy thrillers. Who looks for a linear, credible storyline in projects like this? How plausible was Mission Impossible? Apart from Kareena's saucy nautch girl number, with its overt lesbian moves, everything else in this ambitious film worked brilliantly. Particularly, Saif's perfectly pitched gay scene with Freddy Khambatta, the prancing airline purser. Most importantly,one can actually see where the big bucks went in 'Agent Vinod'.The extravagantly shot Karachi wedding sequence was pure eye candy. Still puzzled why the movie has been banned in Pakistan – are our neighbours on an over-active guilt trip??
But the movie to watch out for is a modest, high concept, small budget quickie titled, 'Vicky Donor'. I can't wait to see a film about a professional sperm donor which has the tagline, "Every drop counts…"
14 comments:
- Vishal said...
Agree with you on Housefull 2. senseless comic caper and n I hardly laughed. Wonder what's wrong with Sajid? Housefull 1 was better.
- April 11, 2012 at 1:06 AM
- Tsomo85 said...
Wow! Saves me from guilt trip that I've no time for movies. Still have yet to catch Kahani, Dirty Picture, etc from last year.
- April 11, 2012 at 8:07 AM
- Unknown said...
Cakes give the reasons to go delicious, and that's the reason that this king of confectionary items centre all the celebrations and moods. The mood will go crazy now, for, the cake specialist called CakesDeliveryHyderabad.com is on action now. Join the cake cascade that www.cakesdeliveryhyderabad.com is filled with.
- April 11, 2012 at 10:29 AM
- manish said...
Respected Madam,
I am on the behalf of modern school vasant vihar , delhi, would like to call you our Chief guest for Mod Debate which is scheduled on 24th of april .please revert on email@example.com or give the concern person name to contact
Thanks and Regards
- April 11, 2012 at 11:24 AM
- Hari Akkavajhula said...
I watch a lot of old black-n-white movies. The actors are so fully dressed and the movies make so much sense and the comedy is so good. No wonder they are referred to as classics even today!
Can't agree more on housefull2 but racism is everywhere around. I think I 'adopted' myself too much to accept this. Is there a way to control this? As far as movies are concerned, as you said, its high time that censor board tweaked its regulations.
- April 11, 2012 at 4:08 PM
- numerounity said...
Oh I really liked the depiction- Grousefull! I am sure it would be quite a grossy movie than it's original avtar.
Indian comedy has gone from good to worse, wonder with so much technological advancement how our stars and directors manage to be so yucky, racist & absolutely offensive.
I heard Agent Vinod is better one and cant wait to watch it.
BTW, guy am back in blogging sphere..hoping to stay for some decent time..pl check my blog & lemme know ur feedbacks- http://ektakhetan.blogspot.in
Sorry for marketing Ms De. Hope u be ok :)
- April 11, 2012 at 7:08 PM
- collage days said...
when i heard this type of comment on films lyk housefull-2,double dhamaal,rascals and so on...i feel very gud...becoz if we dont oppose these types of logic less movies..the directors are not stop to make audience fool...
they just want to make money...they have no scripts, no story...
they just have superstars and some sexy pieces for thier films...
- April 11, 2012 at 7:42 PM
- Rajat Gaur said...
Just like Housefull (part 1), Housefull (2) is also a lousy movie. I recently read a review, which said that its a movie for a 4 year old child who will laugh at the characters doing stupid stuff like mocking at a physically disabled person. Quality of comedy aside, the movie is also very bad from ethical point of view.
As far as agent Vinod is concerned, I haven't watched it. But one thing that I can comment about even without watching is its music. Pritam..!.......I think you would have understood what I mean to say.
Boney-M's famous song Rasputin was dubbed as "I'll Do The Talking Tonight" and an Iranian band has also accused it of steeling the initial part if its song.
- April 11, 2012 at 8:17 PM
- *Aham* said...
i knew it.
i knew it.
while i was watching grousefull i was just thinking.. "de will so want to give a Hi5 to Sajid khan's face"
the script writer should be called Archimedes or Newton or Galileo for to even recollect the several Jollies in the film and weave them together in a screenplay is no jolly easy task.
but you know de, i expected a gibberish stupid silly insane film and it stood up to my expectation.
how stupid and pissing-off-silly can it get.
i felt so bad for the crocodile and python. Which respectable animal would bite riteish's and tusshar's bum or crotch.
but thank god the director didnt get them to bite my Man-Mandir-Ka-Devta John's vitals. He would be out of expressions if something happens to it. (remember you said - his butt is more expressive than his face. LOL)
The stream of consciousness in this film has no fish in it.
i feel there is an L to differentiate public and pubic. The film is just dyslexic.
- April 12, 2012 at 12:02 PM
- thailandtours said...
It's the abroad tour that everyone could afford, and the Thailand tour package offers it all. To be precise, it is the travel package for everyone, and ThailandToursInc.com arranges teh deal. The link at www.thailandtoursinc.com comes with the complete details.
- April 12, 2012 at 3:25 PM
- Abhishek said...
I found some helpful information from this site,
there is also a very useful site that i have found very interesting,site is http://www.ancapitalmarket.com
- April 13, 2012 at 4:02 PM
- chrisjarvis said...
Deciding to stop smoking can a daunting decision.
STC Technologies
- April 19, 2012 at 12:04 PM
- chinese girl said...
Great post! I've been wondering lately - why it seems like everybody has been looking in the same places for the inspiration and you give answers. Thank you for the insight!chnlove
- July 24, 2012 at 8:33 AM
- chinese girl said...
Favorite post having such an fantastic and useful informative content.idateasia
- August 13, 2012 at 7:13 AM


text:
The OpenMP 4.0 Release Candidate 1 is now available for public discussion on this forum.
Also note this Birds of a Feather session at Supercomputing 2012:
Tuesday, Nov 13th, 5:30 - 7:00pm [Room 355-A]
Birds of a Feather: "OpenMP: Next Release and Beyond" – Barbara M. Chapman, Bronis R. de Supinski, Matthijs van Waveren
We will present and release a comment draft of the next specification version, which includes several significant enhancements, and we will discuss plans for the continued evolution of OpenMP. A lively panel discussion will critique the draft. We will solicit audience opinions on what features are most needed for future specifications. http://sc12.supercomputing.org/schedule/event_detail.php?evid=bof112.


text:
© 2014 J.D. Power and Associates, McGraw Hill Financial. All Rights Reserved.
Automotive Inquiry
For more information about how J.D. Power can help you create, monitor and manage a superior customer experience, please provide the following information. A representative will contact you based on the information you provide, so please be as complete as possible.
If you need immediate assistance, please contact us at firstname.lastname@example.com or toll-free at (888) 537-6937.
J.D. Power
2625 Townsgate Road, Suite 100
Westlake Village, CA 91361
Toll Free: (888) 537-6937
Phone: (805) 418-8000
Fax: (805) 418-8900


text:
A 1964 Facel Vega once owned by Ringo Starr is coming up for auction at Bonhams in London December 1. It's a right-hand drive car, powered by a 6.7-liter Chrysler-derived V8 and it will probably go faster than even Ringo's sticks on the snare drum. Bonhams thinks the car will fetch as much as $566,000, according to this Los Angeles Times piece.
Sales of celebrity cars invariably do well — we are something of a celebrity-worshipping world, after all — and other Beatles cars have been snapped up the minute they hit the auction block. A year ago, RM Auctions got $496,613 for Paul McCartney's 1964 Aston Martin DB5. And three months ago, John Lennon's first car, a 1965 Ferrari 330GT he bought shortly after he passed his driver's license test, was sold by Bonhams for about $576,000.


text:
Paul Banwell is an internationally-known, fully accredited Plastic & Cosmetic Surgeon who runs a modern cosmetic surgery practice in the South East of England and London. Impeccable credentials and an honest approach allied with an artistic touch and friendly manner mean his skills are in great demand.
Whether you are interested in subtle refinements or want bolder changes, Mr Banwell believes in listening carefully to your wishes and helping you achieve a natural result.
Mr Banwell strives to provide a professional, premium service for all his patients within a safe, caring environment: the best private hospitals, the latest proven techniques with minimal scarring, comprehensive aftercare and customer service to match.
Mr Banwell believes healthy skin is beautiful skin. It's all about intelligent beauty - gentle, considered, yet powerful treatments to obtain luminous skin. We offer a full range of non-surgical solutions and anti-ageing treatments together with cutting edge, tailored medical-grade skin care programmes.
Consultant Cosmetic Surgeon, Mr Paul Banwell FRCS(Plast) is one of the UK's most well-known Plastic & Cosmetic Surgeons. He has had extensive training in cosmetic surgery and anti-ageing medicine both within the UK and abroad (Australia, Sweden and USA). Based at the famous McIndoe Surgical Centre in East Grinstead, he has won numerous awards and distinctions in his career and amongst other honours is a Visiting Professor in Plastic Surgery to Harvard University.
...the care I received was expert, professional and totally honest
Mr Banwell has an international reputation as a special expert in Skin Health and Skin Care treatments including cosmeceuticals, dermal fillers, wrinkle treatments, chemical peels, skin needling and has pioneered many innovative concepts in this field. His patients come from all over the UK and Europe for skin assessments and treatments. He can prescribe individual tailored programmes including the latest cosmeceutical creations from UK-based Medik8 and other premium brands from around the world.
Mr Banwell is a regular face in the media (BBC1, ITV, Channel 4, Times, Telegraph, Daily Mail, The Sun, Marie Claire, Look, She, Stylist Magazine, Professional Beauty, Woman's Own, Expert Beauty and Cosmetic Surgery & Aesthetics Guide) and has been listed in the Times Magazine as one of the UK's Top 100 Doctors.


text:
On Sunday January 17th at 2PM
the SW chapter of OEFFA (Ohio Ecological Food and Farming Association)
will be showing "Fresh", a movie that details "new thinking about what we're eating", followed by a panel discussion with local growers , with local popcorn, microgreens and cider being served.
OEFFA members free, $3 for non-members
RSVP by Friday, 1/15/10
Contact: Sally Godschalk at email@example.com or 561-7400
The Civic Garden Center is located at 2715 Reading Rd., Cincinnati, OH. 45206
Across from the old Bethesda Oak Hospital
Learn more about the film Fresh at http://www.freshthemovie.com/
Tuesday, January 5, 2010
Fresh Screening at Civic Garden Center January 17th
2 comments:
- Pama Mitchell said...
I am a locavore (when possible) and a supporter of the slow food movement. I also write a Cincinnati based blog about healthy eating.
Would you consider adding my site to your blogroll? Check it out when you have time to see whether you think it fits on your site.
Thanks --- Pama Mitchell
- January 11, 2010 at 9:08 PM
- Mark said...
As part of the UC|Sustainability Winter 2010 'Green' Workshop Series, there will be a Intro to Permaculture I course tomorrow, 5:00 PM, at UC's Catskeller bar. You can register for the event at email@example.com.
- January 18, 2010 at 3:55 AM
Subscribe to: Post Comments (Atom)


text:
Loud and proud
Rock, pop, blues, jazz, and even punk music all have some surprising UMass connections, and yes, UMass has been represented at the Grammy Awards. More than once.
Perhaps you've heard of Natalie Cole? The daughter of the legendary Nat King Cole, and an acclaimed singer in her own right with nine Grammys, she started her education at UMass, briefly transferred to University of Southern California, then returned to get her degree in child psychology in 1972. Only a few years later she won her first Grammy for best female R&B vocal performance.
Another UMass Grammy winner is Buffy Sainte-Marie. Who? The theme song to the Richard Gere/Debra Winger movie, "An Officer and a Gentleman,'' is Joe Cocker singing "Up Where We Belong,'' which was written in part by Sainte-Marie, who got her bachelor's degree from UMass in 1963 and PhD in 1983.
You like your music a little harder? Jeff Penalty, former lead singer of the punk band Dead Kennedys, attended UMass. So did Kenny Aronoff, a drummer who has played with Bob Dylan, Elton John, Ray Charles, and the Rolling Stones, among many others.
But if jazz and blues are more your style, UMass has a trio of legends: Drummer Max Roach was recruited to the faculty in the early 1970s, pianist and composer Billy Taylor cofounded the school's Jazz in July improvisation program, and guitarist Taj Mahal studied there.


text:
Maralinga Bombs Lest we forget
These Posters were made early 2008.
Scott and Helen own the original paintings. Kunmanu Brown (Deceased) © Kunmanu Brown did the painting when he was working with Max Mansell in Adelaide. Max and Helen were in Victoria with Kunmanu Brown when he passed. Kunmanu Edwards © (Deceased) came to ADAC to paint the story about the Maralinga Bombs, in the last week he was here. Yvonne Edwards © Wife came with Kunmanu Edwards to ADAC in his last week to help him tell the story about the Maralinga Bombs
Maralinga Bombs Lest we forget


text:
Mike Digg - Permission [User Submitted]
One of the hardest new songs of the year. Permission by
Mike DiGG...It's working it's way down on mixtapes from Fl.
To ATL further north. Expect Big things from this Rated Next Artist !!!
Currently touring and taking u.s booking dates.
Please click the "Report" button below if the video on this page is not working properly.
Comments will only be displayed by verified emails. No Spamming or Racism.


text:
Member Audios
Melissa Tucker
Melissa Tucker
Jessica L Robinson
Cheryl Kirksey
Donnette Jacobs
Jay Grayson
Golden V. Adams Jr.
Melanie Waxman
Melanie Waxman
michael cohen
Amanda Henson
Nick Irmo
Gordon Taylor
Close X
Avoid confusion and save time by watching this brief orientation video. You'll learn where things are located and how to get started. Look in this section for important messages every time you log in. Let's get started by watching this video.
Legacy Photo Books 20% off Use Code LPB20GO NOW!
Close X
Start your family history Story Blog to write your stories one at a time. Use our story prompts to elicit memories in all life stages, milestones, and wisdom, etc. Share your stories with only family or promote your blog in our public library. Print your legacy stories in an heirloom Legacy Book.
Backup, organize and share your highest priority legacy photos by creating Legacy Slide Shows. Share your slide shows with family or contribute to our public library for research and enrichment. Create heirloom Legacy Photo Books by using our easy templates.
Our free mobile app records your oral history in pictures, capturing your dialect, personality, attitude. Upload, organize and share recordings with family or contribute to our public library. Convert recordings to video to preserve on personalized heirloom thumb drives.
Copyright © 2008-2019 LegacyStories. All Rights Reserved.
LegacyStories.org offers personal history tools, training, archiving and sharing features to help people pass down to heirs their life lessons, values and traditions.