Ticket #1884: cache.patch

File cache.patch, 5.5 KB (added by amm, 10 years ago)

Patch to add more cache heuristics

  • render_config.h

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

     
    5050typedef struct {
    5151    char xmlname[XMLCONFIG_MAX];
    5252    char baseuri[PATH_MAX];
     53    int mincachetime[MAX_ZOOM];
    5354} tile_config_rec;
    5455
    5556typedef struct {
     
    292293
    293294static void add_expiry(request_rec *r, struct protocol * cmd)
    294295{
    295     apr_time_t expires, holdoff, planetTimestamp;
     296    apr_time_t holdoff;
    296297    apr_table_t *t = r->headers_out;
    297298    enum tileState state = tile_state(r, cmd);
     299    apr_finfo_t *finfo = &r->finfo;
    298300    char *timestr;
     301    long int planetTimestamp, maxAge, minCache, lastModified;
    299302
    300     /* Append expiry headers ... */
     303    ap_conf_vector_t *sconf = r->server->module_config;
     304    tile_server_conf *scfg = ap_get_module_config(sconf, &tile_module);
     305    tile_config_rec *tile_configs = (tile_config_rec *) scfg->configs->elts;
    301306
    302307    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "expires(%s), uri(%s), filename(%s), path_info(%s)\n",
    303308                  r->handler, r->uri, r->filename, r->path_info);
    304309
    305     // We estimate an expiry based on when the next planet dump is (or was) due
    306     // If we are past this time already then round up to request time
    307     // Then add a randomisation of up to 3 hours
    308     planetTimestamp = (state == tileCurrent) ? (getPlanetTime(r) + apr_time_from_sec(PLANET_INTERVAL)) : getPlanetTime(r);
    309     holdoff = apr_time_from_sec(3 * 60 * 60) * (rand() / (RAND_MAX + 1.0));
    310     expires = MAX(r->request_time, planetTimestamp) + holdoff;
     310    /* Test if the tile we are serving is out of date, then set a low maxAge*/
     311    if (state == tileOld) {
     312        holdoff = (CACHE_DURATION_DIRTY /2) * (rand() / (RAND_MAX + 1.0));
     313        maxAge = CACHE_DURATION_DIRTY + holdoff;
     314    } else {
     315        // cache heuristic based on zoom level
     316        minCache = tile_configs->mincachetime[cmd->z];
     317        // Time to the next known complete rerender
     318        planetTimestamp = apr_time_sec( + getPlanetTime(r) + apr_time_from_sec(PLANET_INTERVAL) - r->request_time) ;
     319        // Time since the last render of this tile
     320        lastModified = apr_time_sec(r->request_time - finfo->mtime);
     321        // Add a random jitter of 3 hours to space out cache expiry
     322        holdoff = (3 * 60 * 60) * (rand() / (RAND_MAX + 1.0));
    311323
     324        maxAge = MAX(minCache, planetTimestamp);
     325        maxAge = MAX(maxAge,lastModified);
     326        maxAge += holdoff;
     327
     328        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
     329                        "caching heuristics: next planet render %ld; zoom level based %ld; last modified %ld\n",
     330                        planetTimestamp, minCache, lastModified);
     331    }
     332
     333    maxAge = MIN(maxAge, CACHE_DURATION_MAX);
     334
     335    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Setting tiles maxAge to %ld\n", maxAge);
     336
    312337    apr_table_mergen(t, "Cache-Control",
    313                      apr_psprintf(r->pool, "max-age=%" APR_TIME_T_FMT,
    314                      apr_time_sec(expires - r->request_time)));
     338                     apr_psprintf(r->pool, "max-age=%ld" APR_TIME_T_FMT,
     339                     maxAge));
    315340    timestr = apr_palloc(r->pool, APR_RFC822_DATE_LEN);
    316     apr_rfc822_date(timestr, expires);
     341    apr_rfc822_date(timestr, (apr_time_from_sec(maxAge) + r->request_time));
    317342    apr_table_setn(t, "Expires", timestr);
    318343}
    319344
    320 
    321345double get_load_avg(request_rec *r)
    322346{
    323347    double loadavg[1];
     
    565589
    566590static const char *add_tile_config(cmd_parms *cmd, void *mconfig, const char *baseuri, const char *name)
    567591{
     592        int i;
    568593    if (strlen(name) == 0) {
    569594        return "ConfigName value must not be null";
    570595    }
    571596
    572597    tile_server_conf *scfg = ap_get_module_config(cmd->server->module_config, &tile_module);
    573     tile_config_rec *tilecfg = apr_array_push(scfg->configs);   
     598    tile_config_rec *tilecfg = apr_array_push(scfg->configs);
    574599
    575600    strncpy(tilecfg->baseuri, baseuri, PATH_MAX-1);
    576601    tilecfg->baseuri[PATH_MAX-1] = 0;
    577602    strncpy(tilecfg->xmlname, name, XMLCONFIG_MAX-1);
    578603    tilecfg->xmlname[XMLCONFIG_MAX-1] = 0;
    579    
     604    for (i = 0; i < MAX_ZOOM; i++) {
     605        if (i < CACHE_LOW_ZOOM_LEVEL) {
     606            tilecfg->mincachetime[i] = CACHE_DURATION_LOWZOOM;
     607        } else if (i < CACHE_MEDIUM_ZOOM_LEVEL) {
     608            tilecfg->mincachetime[i] = CACHE_DURATION_MEDIUMZOOM;
     609        } else {
     610            tilecfg->mincachetime[i] = CACHE_DURATION_HIGHZOOM;
     611        }
     612    }
     613
    580614    return NULL;
    581615}
    582616