Example #1
0
/**
 * \brief get content of given tile
 * 
 * fills the mapcache_tile::data of the given tile with content stored on the couchbase server
 * \private \memberof mapcache_cache_couchbase
 * \sa mapcache_cache::tile_get()
 */
static int _mapcache_cache_couchbase_get(mapcache_context *ctx, mapcache_tile *tile) {
   char *key[1];
   size_t keySize[1];
   libcouchbase_t *instance;
   libcouchbase_error_t error;
   getStruct_t request;

   key[0] = mapcache_util_get_tile_key(ctx, tile, NULL, " \r\n\t\f\e\a\b", "#");
   if(GC_HAS_ERROR(ctx)) {
      return MAPCACHE_FAILURE;
   }
   
   keySize[0] = strlen(key[0]);

   tile->encoded_data = mapcache_buffer_create(0, ctx->pool);

   libcouchbase_time_t expires = 86400;
   if(tile->tileset->auto_expire)
      expires = tile->tileset->auto_expire;

   instance = _couchbase_get_connection(ctx, tile);
   if (GC_HAS_ERROR(ctx)) {
      return MAPCACHE_FAILURE;
   }

   request.tileBuffer = tile->encoded_data;
   error = libcouchbase_mget(*instance, &request, 1, (const void * const*)key, keySize, &expires);
   if (error != LIBCOUCHBASE_SUCCESS) {
      ctx->set_error(ctx, 500, "couchbase cache returned error on mget %s", libcouchbase_strerror(*instance, error));
      _couchbase_invalidate_connection(tile, instance);
      return MAPCACHE_FAILURE;
   }
   
   libcouchbase_wait(*instance);

   if(request.error != LIBCOUCHBASE_SUCCESS) {
       _couchbase_release_connection(tile, instance);
       return MAPCACHE_CACHE_MISS;
   }

   if (tile->encoded_data->size == 0) {
      _couchbase_release_connection(tile, instance);
      ctx->set_error(ctx, 500, "couchbase cache returned 0-length data for tile %d %d %d", tile->x, tile->y, tile->z);
      return MAPCACHE_FAILURE;
   }
   
   apr_time_t now = apr_time_now();
   tile->mtime = now;

   _couchbase_release_connection(tile, instance);
   return MAPCACHE_SUCCESS;
}
Example #2
0
/* Not sure if we need this. */
static void _couchbase_error_callback(libcouchbase_t instance,
                                      libcouchbase_error_t error,
                                      const char *errinfo)
{
   /* Ignore timeouts... */
   if (error != LIBCOUCHBASE_ETIMEDOUT) {
      fprintf(stderr, "\nFATAL ERROR: %s\n",
              libcouchbase_strerror(instance, error));
      if (errinfo && strlen(errinfo) != 0) {
         fprintf(stderr, "\t\"%s\"\n", errinfo);
      }
   }
}
Example #3
0
static void _mapcache_cache_couchbase_delete(mapcache_context *ctx, mapcache_tile *tile) {
   char *key;
   libcouchbase_t *instance;
   libcouchbase_error_t error;

   key = mapcache_util_get_tile_key(ctx, tile,NULL," \r\n\t\f\e\a\b","#");
   GC_CHECK_ERROR(ctx);

   instance = _couchbase_get_connection(ctx, tile);

   error = libcouchbase_remove(*instance, 0, key, strlen(key), 0);
   if (error != LIBCOUCHBASE_SUCCESS) {
      ctx->set_error(ctx, 500, "couchbase: failed to delete key %s: %s", key, libcouchbase_strerror(*instance, error));
   }
   
   libcouchbase_wait(*instance);

   error = libcouchbase_get_last_error(*instance);
   if (error != LIBCOUCHBASE_SUCCESS) {
      ctx->set_error(ctx, 500, "couchbase: failed to delete key %s: %s", key, libcouchbase_strerror(*instance, error));
   }

   _couchbase_release_connection(tile, instance);
}
Example #4
0
static int _mapcache_cache_couchbase_has_tile(mapcache_context *ctx, mapcache_tile *tile) {
   char *key[1];
   libcouchbase_t *instance;
   libcouchbase_error_t error;
   size_t keySize[1];
   getStruct_t request;

   key[0] = mapcache_util_get_tile_key(ctx, tile, NULL, " \r\n\t\f\e\a\b", "#");
   if(GC_HAS_ERROR(ctx)) {
      return MAPCACHE_FALSE;
   }

   keySize[0] = strlen(key[0]);

   instance = _couchbase_get_connection(ctx, tile);
   request.tileBuffer = 0;
   request.error = LIBCOUCHBASE_KEY_ENOENT;
   error = libcouchbase_mget(*instance, &request, 1, (const void * const*)key, keySize, 0);
   if (error != LIBCOUCHBASE_SUCCESS) {
      ctx->set_error(ctx, 500, "couchbase: failed to get key %s: %s", key, libcouchbase_strerror(*instance, error));
      _couchbase_invalidate_connection(tile, instance);
      return MAPCACHE_FALSE;
   }
   
   libcouchbase_wait(*instance);

   error = request.error;
   if (error != LIBCOUCHBASE_SUCCESS) {
      ctx->set_error(ctx, 500, "couchbase: failed to get key %s: %s", key, libcouchbase_strerror(*instance, error));
      _couchbase_invalidate_connection(tile, instance);
      return MAPCACHE_FALSE;
   }

   _couchbase_release_connection(tile, instance);
   return MAPCACHE_TRUE;
}
void
PLCBA_connect(SV *self)
{
    libcouchbase_t instance;
    PLCBA_t *async;
    PLCB_t *base;
    libcouchbase_error_t err;
    
    _mk_common_vars(self, instance, base, async);
    if( (err = libcouchbase_connect(instance)) != LIBCOUCHBASE_SUCCESS) {
        die("Problem with initial connection: %s (%d)",
            libcouchbase_strerror(instance, err), err);
    }
    libcouchbase_wait(instance);
}
Example #6
0
static void error_callback(libcouchbase_t instance,
                           libcouchbase_error_t err,
                           const char *errinfo)
{
    err_exit("Error %s: %s", libcouchbase_strerror(instance, err), errinfo);
}
Example #7
0
/**
 * \brief push tile data to couchbase
 * 
 * writes the content of mapcache_tile::data to the configured couchbased instance(s)
 * \private \memberof mapcache_cache_couchbase
 * \sa mapcache_cache::tile_set()
 */
static void _mapcache_cache_couchbase_set(mapcache_context *ctx, mapcache_tile *tile) {
   char *key;
   libcouchbase_t *instance;
   libcouchbase_error_t error;
   const int max_retries = 3;
   int retries = max_retries;
   apr_interval_time_t delay;

   /* set expiration to one day if not configured */
   libcouchbase_time_t expires = 86400;
   if(tile->tileset->auto_expire)
      expires = tile->tileset->auto_expire;

   mapcache_cache_couchbase *cache = (mapcache_cache_couchbase*)tile->tileset->cache;
   key = mapcache_util_get_tile_key(ctx, tile, NULL, " \r\n\t\f\e\a\b", "#");
   GC_CHECK_ERROR(ctx);
   
   if(!tile->encoded_data) {
      tile->encoded_data = tile->tileset->format->write(ctx, tile->raw_image, tile->tileset->format);
      GC_CHECK_ERROR(ctx);
   }
   
   instance = _couchbase_get_connection(ctx, tile);
   GC_CHECK_ERROR(ctx);

   do
   {
      error = libcouchbase_store(*instance, &error, LIBCOUCHBASE_SET, key, strlen(key), tile->encoded_data->buf, tile->encoded_data->size, 0, expires, 0);
      if (error != LIBCOUCHBASE_SUCCESS) {
          _couchbase_release_connection(tile, instance);
          ctx->set_error(ctx, 500, "failed to store tile %d %d %d to couchbase cache %s due to eror %s.",
                         tile->x, tile->y, tile->z, cache->cache.name, libcouchbase_strerror(*instance, error));
          return;
      }
   
      libcouchbase_wait(*instance);

      if (error == LIBCOUCHBASE_ETMPFAIL) {
          if (retries > 0) {
              delay = 100000 * (1 << (max_retries - retries));	// Do an exponential back off of starting at 100 milliseconds
              apr_sleep(delay);
          }
          else {
              _couchbase_release_connection(tile, instance);
              ctx->set_error(ctx, 500, "failed to store tile %d %d %d to couchbase cache %s due to %s. Maximum number of retries used.",
                             tile->x, tile->y, tile->z, cache->cache.name, libcouchbase_strerror(*instance, error));
              return;
          }

          --retries;
      }

      else if (error != LIBCOUCHBASE_SUCCESS) {
          _couchbase_release_connection(tile, instance);
          ctx->set_error(ctx, 500, "failed to store tile %d %d %d to couchbase cache %s due to error %s.",
                         tile->x, tile->y, tile->z, cache->cache.name, libcouchbase_strerror(*instance, error));
          return;
      }
   }
   while (error == LIBCOUCHBASE_ETMPFAIL);

   _couchbase_release_connection(tile, instance);
}