Skip to content

Commit 503f166

Browse files
committed
porting code to newer logic
1 parent 563e91b commit 503f166

File tree

2 files changed

+125
-73
lines changed

2 files changed

+125
-73
lines changed

include/mapcache.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -414,23 +414,10 @@ mapcache_cache* mapcache_cache_tc_create(mapcache_context *ctx);
414414
*/
415415
mapcache_cache* mapcache_cache_riak_create(mapcache_context *ctx);
416416

417-
#ifdef USE_REDIS
418-
typedef struct mapcache_cache_redis mapcache_cache_redis;
419-
/**\class mapcache_cache_redis
420-
* \brief a mapcache_cache on redis server
421-
* \implements mapcache_cache
422-
*/
423-
struct mapcache_cache_redis {
424-
mapcache_cache cache;
425-
char *host;
426-
unsigned long int port;
427-
};
428-
429417
/**
430418
* \memberof mapcache_cache_redis
431419
*/
432420
mapcache_cache* mapcache_cache_redis_create(mapcache_context* ctx);
433-
#endif
434421

435422
/** @} */
436423

lib/cache_redis.c

Lines changed: 125 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
* $Id$
33
*
44
* Project: MapServer
5-
* Purpose: MapCache tile caching support file: memcache cache backend.
6-
* Author: Thomas Bonfort and the MapServer team.
5+
* Purpose: MapCache tile caching support file: redis cache backend.
6+
* Author: Boris Manojlovic, Thomas Bonfort and the MapServer team.
77
*
88
******************************************************************************
99
* Copyright (c) 1996-2011 Regents of the University of Minnesota.
10+
* Copyright (c) 2021 Boris Manojlovic
1011
*
1112
* Permission is hereby granted, free of charge, to any person obtaining a
1213
* copy of this software and associated documentation files (the "Software"),
@@ -27,43 +28,96 @@
2728
* DEALINGS IN THE SOFTWARE.
2829
*****************************************************************************/
2930

30-
#include "mapcache-config.h"
31+
#include "mapcache.h"
3132
#ifdef USE_REDIS
3233

33-
#include "mapcache.h"
3434
#include <apr_strings.h>
3535
#include <limits.h>
3636
#include <errno.h>
3737

38-
#define REDIS_GET_CACHE(t) ((mapcache_cache_redis*)t->tileset->cache)
38+
39+
typedef struct mapcache_cache_redis mapcache_cache_redis;
40+
41+
/**\class mapcache_cache_redis
42+
* \brief a mapcache_cache for redis
43+
* \implements mapcache_cache
44+
*/
45+
struct mapcache_cache_redis {
46+
mapcache_cache cache;
47+
char *host;
48+
int port;
49+
char *key_template;
50+
char *bucket_template;
51+
};
52+
53+
struct redis_conn_params {
54+
mapcache_cache_redis *cache;
55+
};
56+
57+
#define REDIS_GET_CACHE(t) ((mapcache_cache_redis*)t->tileset->_cache)
3958
#define REDIS_GET_TILE_KEY(c, t) (mapcache_util_get_tile_key(c, t, NULL, " \r\n\t\f\e\a\b", "#"))
4059
#define IS_REDIS_ERROR_STATUS(r) (r->type != REDIS_REPLY_STATUS || strncmp(r->str, "OK", 2) != 0)
4160

42-
static struct redisContext* _redis_get_connection(mapcache_context *ctx,
43-
mapcache_tile* tile)
44-
{
45-
mapcache_cache_redis *cache = REDIS_GET_CACHE(tile);
61+
62+
63+
64+
65+
void mapcache_redis_connection_constructor(mapcache_context *ctx, void **conn_, void *params) {
66+
mapcache_cache_redis *cache = ((struct redis_conn_params*)params)->cache;
4667
redisContext* conn = redisConnect(cache->host, cache->port);
4768
if (!conn || conn->err) {
4869
ctx->set_error(ctx,500, "redis: failed to connect to server %s:%d", cache->host, cache->port);
49-
return NULL;
70+
return;
5071
}
51-
return conn;
72+
*conn_ = conn;
73+
}
74+
75+
76+
void mapcache_redis_connection_destructor(void *conn_) {
77+
struct redisContext *conn;
78+
conn = (struct redisContext *)conn_;
79+
redisFree(conn);
5280
}
5381

54-
static int _mapcache_cache_redis_has_tile(mapcache_context *ctx,
55-
mapcache_tile *tile)
82+
static mapcache_pooled_connection* _redis_get_connection(mapcache_context *ctx, mapcache_cache_redis *cache, mapcache_tile* tile)
5683
{
57-
char *key = REDIS_GET_TILE_KEY(ctx, tile);
84+
mapcache_pooled_connection *pc;
85+
struct redis_conn_params params;
86+
87+
params.cache = cache;
88+
89+
pc = mapcache_connection_pool_get_connection(ctx,cache->cache.name,mapcache_redis_connection_constructor,
90+
mapcache_redis_connection_destructor, &params);
91+
92+
return pc;
93+
94+
// redisContext *conn;
95+
// conn = redisConnect(cache->host, cache->port);
96+
// if (!conn || conn->err) {
97+
// ctx->set_error(ctx,500, "redis: failed to connect to server %s:%d", cache->host, cache->port);
98+
// return NULL;
99+
// }
100+
// return conn;
101+
}
102+
103+
static int _mapcache_cache_redis_has_tile(mapcache_context *ctx, mapcache_cache *pcache, mapcache_tile *tile) {
104+
int returnValue;
105+
redisContext *conn;
106+
redisReply *reply;
107+
mapcache_pooled_connection *pc;
108+
mapcache_cache_redis *cache = (mapcache_cache_redis*)pcache;
109+
110+
char *key = mapcache_util_get_tile_key(ctx, tile, cache->key_template, " \r\n\t\f\e\a\b", "#");
58111
if(GC_HAS_ERROR(ctx)) {
59112
return MAPCACHE_FALSE;
60113
}
61-
int returnValue = MAPCACHE_TRUE;
62-
redisContext *conn = _redis_get_connection(ctx, tile);
114+
returnValue = MAPCACHE_TRUE;
115+
pc = _redis_get_connection(ctx, cache, tile);
116+
conn = pc->connection;
63117
if(!conn) {
64118
return MAPCACHE_FALSE;
65119
}
66-
redisReply *reply = redisCommand(conn, "EXISTS %s", key);
120+
reply = redisCommand(conn, "EXISTS %s", key);
67121
if(reply->type != REDIS_REPLY_INTEGER) {
68122
returnValue = MAPCACHE_FALSE;
69123
}
@@ -75,36 +129,46 @@ static int _mapcache_cache_redis_has_tile(mapcache_context *ctx,
75129
return returnValue;
76130
}
77131

78-
static void _mapcache_cache_redis_delete(mapcache_context *ctx,
79-
mapcache_tile *tile)
132+
static void _mapcache_cache_redis_delete(mapcache_context *ctx, mapcache_cache *pcache, mapcache_tile *tile)
80133
{
81-
char* key = REDIS_GET_TILE_KEY(ctx, tile);
134+
redisContext *conn;
135+
redisReply *reply;
136+
mapcache_pooled_connection *pc;
137+
mapcache_cache_redis *cache = (mapcache_cache_redis*)pcache;
138+
139+
char *key = mapcache_util_get_tile_key(ctx, tile, cache->key_template, " \r\n\t\f\e\a\b", "#");
82140
GC_CHECK_ERROR(ctx);
83-
redisContext *conn = _redis_get_connection(ctx, tile);
141+
pc = _redis_get_connection(ctx, cache, tile);
142+
conn = pc->connection;
84143
if(!conn) {
85144
return;
86145
}
87-
redisReply *reply = redisCommand(conn, "DEL %s", key);
146+
reply = redisCommand(conn, "DEL %s", key);
88147
if(reply->type == REDIS_REPLY_ERROR) {
89148
ctx->set_error(ctx, 500, "redis: failed to delete key %s: %s", key, reply->str);
90149
}
91150
freeReplyObject(reply);
92151
redisFree(conn);
93152
}
94153

95-
static int _mapcache_cache_redis_get(mapcache_context *ctx,
96-
mapcache_tile *tile)
154+
static int _mapcache_cache_redis_get(mapcache_context *ctx, mapcache_cache *pcache, mapcache_tile *tile)
97155
{
156+
redisContext *conn;
157+
redisReply *reply;
158+
mapcache_pooled_connection *pc;
159+
mapcache_cache_redis *cache = (mapcache_cache_redis*)pcache;
160+
98161
char* key = REDIS_GET_TILE_KEY(ctx, tile);
99162
if(GC_HAS_ERROR(ctx)) {
100163
return MAPCACHE_FAILURE;
101164
}
102165
tile->encoded_data = mapcache_buffer_create(0, ctx->pool);
103-
redisContext *conn = _redis_get_connection(ctx, tile);
166+
pc = _redis_get_connection(ctx, cache, tile);
167+
conn = pc->connection;
104168
if(!conn) {
105169
return MAPCACHE_FAILURE;
106170
}
107-
redisReply *reply = redisCommand(conn, "GET %s", key);
171+
reply = redisCommand(conn, "GET %s", key);
108172
if(reply->type != REDIS_REPLY_STRING) {
109173
freeReplyObject(reply);
110174
return MAPCACHE_CACHE_MISS;
@@ -136,15 +200,21 @@ static int _mapcache_cache_redis_get(mapcache_context *ctx,
136200
* \private \memberof mapcache_cache_redis
137201
* \sa mapcache_cache::tile_set()
138202
*/
139-
static void _mapcache_cache_redis_set(mapcache_context *ctx,
140-
mapcache_tile *tile)
203+
static void _mapcache_cache_redis_set(mapcache_context *ctx, mapcache_cache *pcache, mapcache_tile *tile)
141204
{
142205
/* set expiration to one day if not configured */
143206
int expires = 86400;
207+
mapcache_pooled_connection *pc;
208+
mapcache_cache_redis *cache = (mapcache_cache_redis*)pcache;
209+
char *key;
210+
char *data;
211+
apr_time_t now;
212+
redisContext *conn;
213+
redisReply *reply;
144214
if(tile->tileset->auto_expire)
145215
expires = tile->tileset->auto_expire;
146-
mapcache_cache_redis *cache = REDIS_GET_CACHE(tile);
147-
char *key = mapcache_util_get_tile_key(ctx, tile,NULL," \r\n\t\f\e\a\b","#");
216+
cache = REDIS_GET_CACHE(tile);
217+
key = mapcache_util_get_tile_key(ctx, tile, cache->key_template," \r\n\t\f\e\a\b","#");
148218
GC_CHECK_ERROR(ctx);
149219

150220
if(!tile->encoded_data) {
@@ -154,26 +224,21 @@ static void _mapcache_cache_redis_set(mapcache_context *ctx,
154224

155225
/* concatenate the current time to the end of the memcache data so we can extract it out
156226
* when we re-get the tile */
157-
char *data = calloc(1,tile->encoded_data->size+sizeof(apr_time_t));
158-
apr_time_t now = apr_time_now();
227+
data = calloc(1,tile->encoded_data->size+sizeof(apr_time_t));
228+
now = apr_time_now();
159229
apr_pool_cleanup_register(ctx->pool, data, (void*)free, apr_pool_cleanup_null);
160230
memcpy(data,tile->encoded_data->buf,tile->encoded_data->size);
161231
memcpy(&(data[tile->encoded_data->size]),&now,sizeof(apr_time_t));
162232

163-
redisContext *conn = _redis_get_connection(ctx, tile);
233+
pc = _redis_get_connection(ctx, cache, tile);
234+
conn = pc->connection;
164235
if(!conn) {
165236
return;
166237
}
167-
redisReply *reply = redisCommand(conn,
168-
"SETEX %s %d %b",
169-
key,
170-
expires,
171-
data,
172-
tile->encoded_data->size + sizeof(apr_time_t));
238+
reply = redisCommand(conn, "SETEX %s %d %b", key, expires, data, tile->encoded_data->size + sizeof(apr_time_t));
173239

174240
if(IS_REDIS_ERROR_STATUS(reply)) {
175-
ctx->set_error(ctx, 500, "failed to store tile %d %d %d to redis cache %s",
176-
tile->x, tile->y, tile->z, cache->cache.name);
241+
ctx->set_error(ctx, 500, "failed to store tile %d %d %d to redis cache %s", tile->x, tile->y, tile->z, cache->cache.name);
177242
}
178243

179244
freeReplyObject(reply);
@@ -184,17 +249,13 @@ static void _mapcache_cache_redis_set(mapcache_context *ctx,
184249
/**
185250
* \private \memberof mapcache_cache_redis
186251
*/
187-
static void _mapcache_cache_redis_configuration_parse_xml(mapcache_context *ctx,
188-
ezxml_t node,
189-
mapcache_cache *cache,
190-
mapcache_cfg *config)
191-
{
252+
static void _mapcache_cache_redis_configuration_parse_xml(mapcache_context *ctx, ezxml_t node, mapcache_cache *cache, mapcache_cfg *config) {
253+
ezxml_t xhost,xport;
192254
mapcache_cache_redis *dcache = (mapcache_cache_redis*)cache;
193255
dcache->host = NULL;
194256
dcache->port = 0;
195-
196-
ezxml_t xhost = ezxml_child(node, "host");
197-
ezxml_t xport = ezxml_child(node, "port");
257+
xhost = ezxml_child(node, "host");
258+
xport = ezxml_child(node, "port");
198259

199260
if (!xhost || !xhost->txt || !*xhost->txt) {
200261
ctx->set_error(ctx, 400, "cache %s: redis cache with no <host>", cache->name);
@@ -222,34 +283,38 @@ static void _mapcache_cache_redis_configuration_parse_xml(mapcache_context *ctx,
222283
/**
223284
* \private \memberof mapcache_cache_redis
224285
*/
225-
static void _mapcache_cache_redis_configuration_post_config(mapcache_context *ctx,
226-
mapcache_cache *cache,
227-
mapcache_cfg *cfg)
228-
{
286+
static void _mapcache_cache_redis_configuration_post_config(mapcache_context *ctx, mapcache_cache *cache, mapcache_cfg *cfg) {
229287
}
230288

231289
/**
232290
* \brief creates and initializes a mapcache_redis_cache
233291
*/
234292
mapcache_cache* mapcache_cache_redis_create(mapcache_context *ctx)
235293
{
236-
mapcache_cache_redis *cache = apr_pcalloc(ctx->pool,
237-
sizeof(mapcache_cache_redis));
294+
mapcache_cache_redis *cache = apr_pcalloc(ctx->pool, sizeof(mapcache_cache_redis));
238295
if(!cache) {
239296
ctx->set_error(ctx, 500, "failed to allocate redis cache");
240297
return NULL;
241298
}
299+
242300
cache->cache.metadata = apr_table_make(ctx->pool,3);
243301
cache->cache.type = MAPCACHE_CACHE_REDIS;
244-
cache->cache.tile_get = _mapcache_cache_redis_get;
245-
cache->cache.tile_exists = _mapcache_cache_redis_has_tile;
246-
cache->cache.tile_set = _mapcache_cache_redis_set;
247-
cache->cache.tile_delete = _mapcache_cache_redis_delete;
302+
cache->cache._tile_get = _mapcache_cache_redis_get;
303+
cache->cache._tile_exists = _mapcache_cache_redis_has_tile;
304+
cache->cache._tile_set = _mapcache_cache_redis_set;
305+
cache->cache._tile_delete = _mapcache_cache_redis_delete;
248306
cache->cache.configuration_post_config = _mapcache_cache_redis_configuration_post_config;
249307
cache->cache.configuration_parse_xml = _mapcache_cache_redis_configuration_parse_xml;
308+
cache->host = NULL;
309+
cache->port = 6379;
310+
cache->bucket_template = NULL;
250311
return (mapcache_cache*)cache;
251312
}
252-
313+
#else
314+
mapcache_cache* mapcache_cache_redis_create(mapcache_context *ctx) {
315+
ctx->set_error(ctx,400,"redis support not compiled in this version");
316+
return NULL;
317+
}
253318
#endif
254319

255320
/* vim: ts=2 sts=2 et sw=2

0 commit comments

Comments
 (0)