/** * \brief push tile data to memcached * * writes the content of mapcache_tile::data to the configured memcached instance(s) * \returns MAPCACHE_FAILURE if there is no data to write, or if the tile isn't locked * \returns MAPCACHE_SUCCESS if the tile has been successfully written * \private \memberof mapcache_cache_memcache * \sa mapcache_cache::tile_set() */ static void _mapcache_cache_memcache_set(mapcache_context *ctx, mapcache_tile *tile) { char *key; int rv; /* set expiration to one day if not configured */ int expires = 86400; if(tile->tileset->auto_expire) expires = tile->tileset->auto_expire; mapcache_cache_memcache *cache = (mapcache_cache_memcache*)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); } /* concatenate the current time to the end of the memcache data so we can extract it out * when we re-get the tile */ char *data = calloc(1,tile->encoded_data->size+sizeof(apr_time_t)); apr_time_t now = apr_time_now(); apr_pool_cleanup_register(ctx->pool, data, (void*)free, apr_pool_cleanup_null); memcpy(data,tile->encoded_data->buf,tile->encoded_data->size); memcpy(&(data[tile->encoded_data->size]),&now,sizeof(apr_time_t)); rv = apr_memcache_set(cache->memcache,key,data,tile->encoded_data->size+sizeof(apr_time_t),expires,0); if(rv != APR_SUCCESS) { ctx->set_error(ctx,500,"failed to store tile %d %d %d to memcache cache %s", tile->x,tile->y,tile->z,cache->cache.name); return; } }
/** * \brief push tile data to memcached * * writes the content of mapcache_tile::data to the configured memcached instance(s) * \returns MAPCACHE_FAILURE if there is no data to write, or if the tile isn't locked * \returns MAPCACHE_SUCCESS if the tile has been successfully written * \private \memberof mapcache_cache_memcache * \sa mapcache_cache::tile_set() */ static void _mapcache_cache_memcache_set(mapcache_context *ctx, mapcache_cache *pcache, mapcache_tile *tile) { char *key; int rv; /* set no expiration if not configured */ int expires =0; mapcache_buffer *encoded_data = NULL; mapcache_cache_memcache *cache = (mapcache_cache_memcache*)pcache; mapcache_pooled_connection *pc; struct mapcache_memcache_pooled_connection *mpc; pc = _mapcache_memcache_get_conn(ctx,cache,tile); GC_CHECK_ERROR(ctx); mpc = pc->connection; key = mapcache_util_get_tile_key(ctx, tile,NULL," \r\n\t\f\e\a\b","#"); if(GC_HAS_ERROR(ctx)) goto cleanup; if(tile->tileset->auto_expire) expires = tile->tileset->auto_expire; if(cache->detect_blank) { if(!tile->raw_image) { tile->raw_image = mapcache_imageio_decode(ctx, tile->encoded_data); GC_CHECK_ERROR(ctx); } if(mapcache_image_blank_color(tile->raw_image) != MAPCACHE_FALSE) { encoded_data = mapcache_buffer_create(5,ctx->pool); ((char*)encoded_data->buf)[0] = '#'; memcpy(((char*)encoded_data->buf)+1,tile->raw_image->data,4); encoded_data->size = 5; } } if(!encoded_data) { if(!tile->encoded_data) { tile->encoded_data = tile->tileset->format->write(ctx, tile->raw_image, tile->tileset->format); if(GC_HAS_ERROR(ctx)) goto cleanup; } encoded_data = tile->encoded_data; } /* concatenate the current time to the end of the memcache data so we can extract it out * when we re-get the tile */ char *data = calloc(1,encoded_data->size+sizeof(apr_time_t)); apr_time_t now = apr_time_now(); apr_pool_cleanup_register(ctx->pool, data, (void*)free, apr_pool_cleanup_null); memcpy(data,encoded_data->buf,encoded_data->size); memcpy(&(data[encoded_data->size]),&now,sizeof(apr_time_t)); rv = apr_memcache_set(mpc->memcache,key,data,encoded_data->size+sizeof(apr_time_t),expires,0); if(rv != APR_SUCCESS) { ctx->set_error(ctx,500,"failed to store tile %d %d %d to memcache cache %s", tile->x,tile->y,tile->z,cache->cache.name); goto cleanup; } cleanup: _mapcache_memcache_release_conn(ctx,pc); }
/** * \private \memberof mapcache_cache_memcache */ static void _mapcache_cache_memcache_configuration_parse_xml(mapcache_context *ctx, ezxml_t node, mapcache_cache *cache, mapcache_cfg *config) { ezxml_t cur_node; mapcache_cache_memcache *dcache = (mapcache_cache_memcache*)cache; int servercount = 0; for(cur_node = ezxml_child(node,"server"); cur_node; cur_node = cur_node->next) { servercount++; } if(!servercount) { ctx->set_error(ctx,400,"memcache cache %s has no <server>s configured",cache->name); return; } if(APR_SUCCESS != apr_memcache_create(ctx->pool, servercount, 0, &dcache->memcache)) { ctx->set_error(ctx,400,"cache %s: failed to create memcache backend", cache->name); return; } for(cur_node = ezxml_child(node,"server"); cur_node; cur_node = cur_node->next) { ezxml_t xhost = ezxml_child(cur_node,"host"); ezxml_t xport = ezxml_child(cur_node,"port"); const char *host; apr_memcache_server_t *server; apr_port_t port; if(!xhost || !xhost->txt || ! *xhost->txt) { ctx->set_error(ctx,400,"cache %s: <server> with no <host>",cache->name); return; } else { host = apr_pstrdup(ctx->pool,xhost->txt); } if(!xport || !xport->txt || ! *xport->txt) { ctx->set_error(ctx,400,"cache %s: <server> with no <port>", cache->name); return; } else { char *endptr; int iport = (int)strtol(xport->txt,&endptr,10); if(*endptr != 0) { ctx->set_error(ctx,400,"failed to parse value %s for memcache cache %s", xport->txt,cache->name); return; } port = iport; } if(APR_SUCCESS != apr_memcache_server_create(ctx->pool,host,port,4,5,50,10000,&server)) { ctx->set_error(ctx,400,"cache %s: failed to create server %s:%d",cache->name,host,port); return; } if(APR_SUCCESS != apr_memcache_add_server(dcache->memcache,server)) { ctx->set_error(ctx,400,"cache %s: failed to add server %s:%d",cache->name,host,port); return; } if(APR_SUCCESS != apr_memcache_set(dcache->memcache,"mapcache_test_key","mapcache",8,0,0)) { ctx->set_error(ctx,400,"cache %s: failed to add test key to server %s:%d",cache->name,host,port); return; } } }
/* * store a name/value pair in memcache */ static apr_byte_t oidc_cache_memcache_set(request_rec *r, const char *section, const char *key, const char *value, apr_time_t expiry) { oidc_debug(r, "enter, section=\"%s\", key=\"%s\"", section, key); oidc_cfg *cfg = ap_get_module_config(r->server->module_config, &auth_openidc_module); oidc_cache_cfg_memcache_t *context = (oidc_cache_cfg_memcache_t *) cfg->cache_cfg; apr_status_t rv = APR_SUCCESS; /* see if we should be clearing this entry */ if (value == NULL) { rv = apr_memcache_delete(context->cache_memcache, oidc_cache_memcache_get_key(r->pool, section, key), 0); if (rv == APR_NOTFOUND) { oidc_debug(r, "apr_memcache_delete: key %s not found in cache", oidc_cache_memcache_get_key(r->pool, section, key)); } else if (rv != APR_SUCCESS) { // TODO: error strings ? oidc_error(r, "apr_memcache_delete returned an error; perhaps your memcache server is not available?"); } } else { /* calculate the timeout from now */ apr_uint32_t timeout = apr_time_sec(expiry - apr_time_now()); /* store it */ rv = apr_memcache_set(context->cache_memcache, oidc_cache_memcache_get_key(r->pool, section, key), (char *) value, strlen(value), timeout, 0); // TODO: error strings ? if (rv != APR_SUCCESS) { oidc_error(r, "apr_memcache_set returned an error; perhaps your memcache server is not available?"); } } return (rv == APR_SUCCESS); }
/* Core functionality of our setter functions: store LENGH bytes of DATA * to be identified by KEY in the memcached given by CACHE_VOID. Use POOL * for temporary allocations. */ static svn_error_t * memcache_internal_set(void *cache_void, const void *key, const char *data, apr_size_t len, apr_pool_t *scratch_pool) { memcache_t *cache = cache_void; const char *mc_key; apr_status_t apr_err; SVN_ERR(build_key(&mc_key, cache, key, scratch_pool)); apr_err = apr_memcache_set(cache->memcache, mc_key, (char *)data, len, 0, 0); /* ### Maybe write failures should be ignored (but logged)? */ if (apr_err != APR_SUCCESS) return svn_error_wrap_apr(apr_err, _("Unknown memcached error while writing")); return SVN_NO_ERROR; }