static void _mapcache_cache_riak_delete(mapcache_context *ctx, mapcache_cache *pcache, mapcache_tile *tile) { int error; RIACK_STRING key; struct RIACK_CLIENT *client; struct RIACK_DEL_PROPERTIES properties; mapcache_pooled_connection *pc; mapcache_cache_riak *cache = (mapcache_cache_riak*)pcache; memset(&properties, 0, sizeof(struct RIACK_DEL_PROPERTIES)); key.value = mapcache_util_get_tile_key(ctx, tile, NULL, " \r\n\t\f\e\a\b", "#"); GC_CHECK_ERROR(ctx); key.len = strlen(key.value); pc = _riak_get_connection(ctx, cache, tile); GC_CHECK_ERROR(ctx); client = pc->connection; properties.rw_use = 1; properties.rw = (4294967295 - 3); // Special value meaning "ALL" error = riack_delete(client, cache->bucket, key, &properties); mapcache_connection_pool_release_connection(ctx,pc); if (error != RIACK_SUCCESS) { ctx->set_error(ctx, 500, "riak: failed to delete key %s: %d", key, error); } }
static void _sqlite_dimension_release_conn(mapcache_context *ctx, mapcache_pooled_connection *pc) { if(GC_HAS_ERROR(ctx)) { mapcache_connection_pool_invalidate_connection(ctx,pc); } else { mapcache_connection_pool_release_connection(ctx,pc); } }
static int _mapcache_cache_riak_has_tile(mapcache_context *ctx, mapcache_cache *pcache, mapcache_tile *tile) { int error; int retries = 3; RIACK_STRING key; struct RIACK_GET_OBJECT obj; struct RIACK_CLIENT *client; mapcache_pooled_connection *pc; mapcache_cache_riak *cache = (mapcache_cache_riak*)pcache; key.value = mapcache_util_get_tile_key(ctx, tile, NULL, " \r\n\t\f\e\a\b", "#"); if (GC_HAS_ERROR(ctx)) { return MAPCACHE_FALSE; } key.len = strlen(key.value); pc = _riak_get_connection(ctx, cache, tile); if (GC_HAS_ERROR(ctx)) { return MAPCACHE_FALSE; } client = pc->connection; do { error = riack_get(client, cache->bucket, key, 0, &obj); if (error != RIACK_SUCCESS) { ctx->log(ctx, MAPCACHE_WARN, "Retry %d in riak_has_tile for tile %s from cache %s due to error %d", (4-retries), key.value, cache->cache.name, error); for (error = riack_reconnect(client); error != RIACK_SUCCESS && retries > 0; error = riack_reconnect(client)) { --retries; } --retries; } } while (error != RIACK_SUCCESS && retries >= 0); if (error != RIACK_SUCCESS) { riack_free_get_object(client, &obj); // riack_get allocates the returned object so we need to deallocate it. mapcache_connection_pool_invalidate_connection(ctx,pc); ctx->set_error(ctx, 500, "riak: failed to get key %s: %d", key, error); return MAPCACHE_FALSE; } if (obj.object.content_count < 1 || obj.object.content[0].data_len == 0) { error = MAPCACHE_FALSE; } else { error = MAPCACHE_TRUE; } riack_free_get_object(client, &obj); // riack_get allocates the returned object so we need to deallocate it. mapcache_connection_pool_release_connection(ctx,pc); return error; }
static void mapcache_sqlite_release_conn(mapcache_context *ctx, mapcache_pooled_connection *conn) { mapcache_connection_pool_release_connection(ctx,conn); }
/** * \brief push tile data to riak * * writes the content of mapcache_tile::data to the configured riak instance(s) * \private \memberof mapcache_cache_riak * \sa mapcache_cache::tile_set() */ static void _mapcache_cache_riak_set(mapcache_context *ctx, mapcache_cache *pcache, mapcache_tile *tile) { char *key,*content_type; int error; int connect_error = RIACK_SUCCESS; int retries = 3; struct RIACK_OBJECT object; struct RIACK_CONTENT content; struct RIACK_PUT_PROPERTIES properties; struct RIACK_CLIENT *client; mapcache_pooled_connection *pc; mapcache_cache_riak *cache = (mapcache_cache_riak*)pcache; memset(&content, 0, sizeof(struct RIACK_CONTENT)); memset(&object, 0, sizeof(struct RIACK_OBJECT)); memset(&properties, 0, sizeof(struct RIACK_PUT_PROPERTIES)); //Use Buckets defaults instead of setting the read/write attributes /* properties.w_use = 1; properties.w = 1; properties.dw_use = 1; properties.dw = 0;*/ 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); } content_type = tile->tileset->format?(tile->tileset->format->mime_type?tile->tileset->format->mime_type:NULL):NULL; if(!content_type) { /* compute the content-type */ mapcache_image_format_type t = mapcache_imageio_header_sniff(ctx,tile->encoded_data); if(t == GC_PNG) content_type = "image/png"; else if(t == GC_JPEG) content_type = "image/jpeg"; } pc = _riak_get_connection(ctx, cache, tile); GC_CHECK_ERROR(ctx); client = pc->connection; // Set up the riak object to put. Need to do this after we get the client connection object.bucket.value = cache->bucket.value; object.bucket.len = cache->bucket.len; object.key.value = key; object.key.len = strlen(key); object.vclock.len = 0; object.content_count = 1; object.content = &content; content.content_type.value = content_type; content.content_type.len = content_type?strlen(content_type):0; content.data = (uint8_t*)tile->encoded_data->buf; content.data_len = tile->encoded_data->size; // If we get an error it is advised that we call reconnect. It also appears // that every now and then we get an error and need to retry once again to // get it to work. do { error = riack_put(client, object, 0, &properties); if (error != RIACK_SUCCESS) { ctx->log(ctx, MAPCACHE_WARN, "Retry %d in riak_set for tile %s from cache %s due to eror %d", (4 - retries), key, cache->cache.name, error); for (connect_error = riack_reconnect(client); connect_error != RIACK_SUCCESS && retries > 0; connect_error = riack_reconnect(client)) { --retries; } --retries; } } while (error != RIACK_SUCCESS && retries >= 0); if (connect_error != RIACK_SUCCESS) mapcache_connection_pool_invalidate_connection(ctx,pc); else mapcache_connection_pool_release_connection(ctx,pc); if (error != RIACK_SUCCESS) { ctx->set_error(ctx, 500, "failed to store tile %s to cache %s due to error %d.", key, cache->cache.name, error); } }
/** * \brief get content of given tile * * fills the mapcache_tile::data of the given tile with content stored on the riak server * \private \memberof mapcache_cache_riak * \sa mapcache_cache::tile_get() */ static int _mapcache_cache_riak_get(mapcache_context *ctx, mapcache_cache *pcache, mapcache_tile *tile) { int error; int connect_error = RIACK_SUCCESS; int retries = 3; RIACK_STRING key; struct RIACK_GET_OBJECT obj; struct RIACK_GET_PROPERTIES properties; struct RIACK_CLIENT *client; mapcache_pooled_connection *pc; mapcache_cache_riak *cache = (mapcache_cache_riak*)pcache; memset(&properties, 0, sizeof(struct RIACK_GET_PROPERTIES)); //Use Buckets defaults instead of setting the read/write attributes /* properties.r_use = 1; properties.r = 1; */ key.value = mapcache_util_get_tile_key(ctx, tile, NULL, " \r\n\t\f\e\a\b", "#"); if (GC_HAS_ERROR(ctx)) { return MAPCACHE_FAILURE; } key.len = strlen(key.value); tile->encoded_data = mapcache_buffer_create(0, ctx->pool); pc = _riak_get_connection(ctx, cache, tile); if (GC_HAS_ERROR(ctx)) { return MAPCACHE_FAILURE; } client = pc->connection; // If we get an error it is advised that we call reconnect. It also appears // that every now and then we get an error and need to retry once again to // get it to work. do { error = riack_get(client, cache->bucket, key, &properties, &obj); if (error != RIACK_SUCCESS) { ctx->log(ctx, MAPCACHE_WARN, "Retry %d in riak_get for tile %s from cache %s due to error %d", (4-retries), key.value, cache->cache.name, error); for (connect_error = riack_reconnect(client); connect_error != RIACK_SUCCESS && retries > 0; connect_error = riack_reconnect(client)) { --retries; } --retries; } } while (error != RIACK_SUCCESS && retries >= 0); if (error != RIACK_SUCCESS) { if (connect_error != RIACK_SUCCESS) mapcache_connection_pool_invalidate_connection(ctx,pc); else mapcache_connection_pool_release_connection(ctx,pc); ctx->set_error(ctx, 500, "Failed to get tile %s from cache %s due to error %d", key.value, cache->cache.name, error); return MAPCACHE_FAILURE; } // Check if tile exists. If it doesn't we need to return CACHE_MISS or things go wrong. // Mapcache doesn't appear to use the has_tile function and uses _get instead so we need // to do this sort of test here instead of erroring. if (obj.object.content_count < 1 || obj.object.content[0].data_len == 0) { riack_free_get_object(client, &obj); // Need to free the object here as well. mapcache_connection_pool_release_connection(ctx,pc); return MAPCACHE_CACHE_MISS; } // Copy the data into the buffer mapcache_buffer_append(tile->encoded_data, obj.object.content[0].data_len, obj.object.content[0].data); riack_free_get_object(client, &obj); // riack_get allocates the returned object so we need to deallocate it. mapcache_connection_pool_release_connection(ctx,pc); return MAPCACHE_SUCCESS; }
/** * \private \memberof mapcache_source_mapserver * \sa mapcache_source::render_map() */ void _mapcache_source_mapserver_render_map(mapcache_context *ctx, mapcache_map *map) { errorObj *errors = NULL; mapcache_pooled_connection *pc; struct mc_mapobj *mcmap; double dx, dy; rasterBufferObj rb; imageObj *image; pc = _mapserver_get_connection(ctx, map); GC_CHECK_ERROR(ctx); mcmap = pc->connection; GC_CHECK_ERROR(ctx); if(mcmap->grid_link != map->grid_link) { if (msLoadProjectionString(&(mcmap->map->projection), map->grid_link->grid->srs) != 0) { ctx->set_error(ctx,500, "Unable to set projection on mapObj."); errors = msGetErrorObj(); while(errors) { ctx->set_error(ctx,500, "Unable to set projection on mapObj. MapServer reports: %s", errors->message); errors = errors->next; } mapcache_connection_pool_invalidate_connection(ctx,pc); return; } switch(map->grid_link->grid->unit) { case MAPCACHE_UNIT_DEGREES: mcmap->map->units = MS_DD; break; case MAPCACHE_UNIT_FEET: mcmap->map->units = MS_FEET; break; case MAPCACHE_UNIT_METERS: mcmap->map->units = MS_METERS; break; } mcmap->grid_link = map->grid_link; } /* ** WMS extents are edge to edge while MapServer extents are center of ** pixel to center of pixel. Here we try to adjust the WMS extents ** in by half a pixel. */ dx = (map->extent.maxx - map->extent.minx) / (map->width*2); dy = (map->extent.maxy - map->extent.miny) / (map->height*2); mcmap->map->extent.minx = map->extent.minx + dx; mcmap->map->extent.miny = map->extent.miny + dy; mcmap->map->extent.maxx = map->extent.maxx - dx; mcmap->map->extent.maxy = map->extent.maxy - dy; msMapSetSize(mcmap->map, map->width, map->height); image = msDrawMap(mcmap->map, MS_FALSE); if(!image) { ctx->set_error(ctx,500, "MapServer failed to create image."); errors = msGetErrorObj(); while(errors) { ctx->set_error(ctx,500, "MapServer reports: %s", errors->message); errors = errors->next; } mapcache_connection_pool_invalidate_connection(ctx,pc); return; } if(image->format->vtable->supports_pixel_buffer) { if( MS_SUCCESS != image->format->vtable->getRasterBufferHandle(image,&rb)) { ctx->set_error(ctx,500,"failed to get mapserver raster buffer handle"); mapcache_connection_pool_invalidate_connection(ctx,pc); return; } } else { ctx->set_error(ctx,500,"format %s has no pixel export",image->format->name); mapcache_connection_pool_invalidate_connection(ctx,pc); return; } map->raw_image = mapcache_image_create(ctx); map->raw_image->w = map->width; map->raw_image->h = map->height; map->raw_image->stride = 4 * map->width; map->raw_image->data = malloc(map->width*map->height*4); memcpy(map->raw_image->data,rb.data.rgba.pixels,map->width*map->height*4); apr_pool_cleanup_register(ctx->pool, map->raw_image->data,(void*)free, apr_pool_cleanup_null); msFreeImage(image); mapcache_connection_pool_release_connection(ctx,pc); }
static void _mapcache_memcache_release_conn(mapcache_context *ctx, mapcache_pooled_connection *con) { mapcache_connection_pool_release_connection(ctx, con); }