Ticket #1884: cacheexpiry.patch

File cacheexpiry.patch, 6.6 KB (added by amm, 10 years ago)

Updated patch to take jochen's changes into account

  • render_config.h

     
    4040// Typical interval between planet imports, used as basis for tile expiry times
    4141#define PLANET_INTERVAL (7 * 24 * 60 * 60)
    4242
     43// Maximum duration in seconds for the cache expiry header
     44#define CACHE_DURATION_MAX (7 * 24 * 60 * 60)
     45
     46// Duration in seconds for the cache expiry of known out of date tiles
     47#define CACHE_DURATION_DIRTY (30 * 60)
     48
     49// Zoom level up to which the low zoom caching heuristic applies
     50#define CACHE_LOW_ZOOM_LEVEL 6
     51// Zoom level up to which the medium zoom caching heuristic applies
     52#define CACHE_MEDIUM_ZOOM_LEVEL 12
     53
     54// Duration in seconds for the cache expiry of low zoom tiles
     55#define CACHE_DURATION_LOWZOOM (6*24*60*60)
     56// Duration in seconds for the cache expiry of medium zoom tiles
     57#define CACHE_DURATION_MEDIUMZOOM (1*24*60*60)
     58// Duration in seconds for the cache expiry of high zoom tiles
     59#define CACHE_DURATION_HIGHZOOM (3*60*60)
     60
     61
    4362// Planet import should touch this file when complete
    4463#define PLANET_TIMESTAMP HASH_PATH "/planet-import-complete"
    4564
  • mod_tile.c

     
    5050typedef struct {
    5151    char xmlname[XMLCONFIG_MAX];
    5252    char baseuri[PATH_MAX];
     53    int mincachetime[MAX_ZOOM];
    5354    int minzoom;
    5455    int maxzoom;
    5556} tile_config_rec;
     
    203204                    //perror("recv error");
    204205                    break;
    205206                }
    206  
     207
    207208                if (cmd->x == resp.x && cmd->y == resp.y && cmd->z == resp.z && !strcmp(cmd->xmlname, resp.xmlname)) {
    208209                    if (resp.cmd == cmdDone)
    209210                        return 1;
    210211                    else
    211212                        return 0;
    212213                } else {
    213                     ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, 
    214                        "Response does not match request: xml(%s,%s) z(%d,%d) x(%d,%d) y(%d,%d)", cmd->xmlname, 
    215                        resp.xmlname, cmd->z, resp.z, cmd->x, resp.x, cmd->y, resp.y);                   
     214                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
     215                       "Response does not match request: xml(%s,%s) z(%d,%d) x(%d,%d) y(%d,%d)", cmd->xmlname,
     216                       resp.xmlname, cmd->z, resp.z, cmd->x, resp.x, cmd->y, resp.y);
    216217                }
    217218            } else if (s == 0) {
    218219                break;
     
    300301
    301302static void add_expiry(request_rec *r, struct protocol * cmd)
    302303{
    303     apr_time_t expires, holdoff, planetTimestamp;
     304    apr_time_t holdoff;
    304305    apr_table_t *t = r->headers_out;
    305306    enum tileState state = tile_state(r, cmd);
     307    apr_finfo_t *finfo = &r->finfo;
    306308    char *timestr;
     309    long int planetTimestamp, maxAge, minCache, lastModified;
    307310
    308     /* Append expiry headers ... */
     311    ap_conf_vector_t *sconf = r->server->module_config;
     312    tile_server_conf *scfg = ap_get_module_config(sconf, &tile_module);
     313    tile_config_rec *tile_configs = (tile_config_rec *) scfg->configs->elts;
    309314
    310315    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "expires(%s), uri(%s), filename(%s), path_info(%s)\n",
    311316                  r->handler, r->uri, r->filename, r->path_info);
    312317
    313     // We estimate an expiry based on when the next planet dump is (or was) due
    314     // If we are past this time already then round up to request time
    315     // Then add a randomisation of up to 3 hours
    316     planetTimestamp = (state == tileCurrent) ? (getPlanetTime(r) + apr_time_from_sec(PLANET_INTERVAL)) : getPlanetTime(r);
    317     holdoff = apr_time_from_sec(3 * 60 * 60) * (rand() / (RAND_MAX + 1.0));
    318     expires = MAX(r->request_time, planetTimestamp) + holdoff;
     318    /* Test if the tile we are serving is out of date, then set a low maxAge*/
     319    if (state == tileOld) {
     320        holdoff = (CACHE_DURATION_DIRTY /2) * (rand() / (RAND_MAX + 1.0));
     321        maxAge = CACHE_DURATION_DIRTY + holdoff;
     322    } else {
     323        // cache heuristic based on zoom level
     324        minCache = tile_configs->mincachetime[cmd->z];
     325        // Time to the next known complete rerender
     326        planetTimestamp = apr_time_sec( + getPlanetTime(r) + apr_time_from_sec(PLANET_INTERVAL) - r->request_time) ;
     327        // Time since the last render of this tile
     328        lastModified = apr_time_sec(r->request_time - finfo->mtime);
     329        // Add a random jitter of 3 hours to space out cache expiry
     330        holdoff = (3 * 60 * 60) * (rand() / (RAND_MAX + 1.0));
    319331
     332        maxAge = MAX(minCache, planetTimestamp);
     333        maxAge = MAX(maxAge,lastModified);
     334        maxAge += holdoff;
     335
     336        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
     337                        "caching heuristics: next planet render %ld; zoom level based %ld; last modified %ld\n",
     338                        planetTimestamp, minCache, lastModified);
     339    }
     340
     341    maxAge = MIN(maxAge, CACHE_DURATION_MAX);
     342
     343    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Setting tiles maxAge to %ld\n", maxAge);
     344
    320345    apr_table_mergen(t, "Cache-Control",
    321346                     apr_psprintf(r->pool, "max-age=%" APR_TIME_T_FMT,
    322                      apr_time_sec(expires - r->request_time)));
     347                     maxAge));
    323348    timestr = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
    324     apr_rfc822_date(timestr, expires);
     349    apr_rfc822_date(timestr, (apr_time_from_sec(maxAge) + r->request_time));
    325350    apr_table_setn(t, "Expires", timestr);
    326351}
    327352
    328 
    329353double get_load_avg(request_rec *r)
    330354{
    331355    double loadavg[1];
     
    578602
    579603static const char *_add_tile_config(cmd_parms *cmd, void *mconfig, const char *baseuri, const char *name, int minzoom, int maxzoom)
    580604{
     605    int i;
    581606    if (strlen(name) == 0) {
    582607        return "ConfigName value must not be null";
    583608    }
    584609
    585610    tile_server_conf *scfg = ap_get_module_config(cmd->server->module_config, &tile_module);
    586     tile_config_rec *tilecfg = apr_array_push(scfg->configs);   
     611    tile_config_rec *tilecfg = apr_array_push(scfg->configs);
    587612
    588613    strncpy(tilecfg->baseuri, baseuri, PATH_MAX-1);
    589614    tilecfg->baseuri[PATH_MAX-1] = 0;
     
    591616    tilecfg->xmlname[XMLCONFIG_MAX-1] = 0;
    592617    tilecfg->minzoom = minzoom;
    593618    tilecfg->maxzoom = maxzoom;
    594    
     619    for (i = tilecfg->minzoom = minzoom; i < tilecfg->maxzoom; i++) {
     620             if (i < CACHE_LOW_ZOOM_LEVEL) {
     621                 tilecfg->mincachetime[i] = CACHE_DURATION_LOWZOOM;
     622             } else if (i < CACHE_MEDIUM_ZOOM_LEVEL) {
     623                 tilecfg->mincachetime[i] = CACHE_DURATION_MEDIUMZOOM;
     624             } else {
     625                 tilecfg->mincachetime[i] = CACHE_DURATION_HIGHZOOM;
     626             }
     627         }
     628
     629
    595630    return NULL;
    596631}
    597632