[mapserver-commits] r13203 - in trunk/mapserver/mapcache: include lib

svn at osgeo.org svn at osgeo.org
Tue Mar 6 05:57:46 EST 2012


Author: tbonfort
Date: 2012-03-06 02:57:46 -0800 (Tue, 06 Mar 2012)
New Revision: 13203

Modified:
   trunk/mapserver/mapcache/include/mapcache.h
   trunk/mapserver/mapcache/lib/cache_disk.c
Log:
add configurable retries to disk cache (#4223)


Modified: trunk/mapserver/mapcache/include/mapcache.h
===================================================================
--- trunk/mapserver/mapcache/include/mapcache.h	2012-03-05 16:22:35 UTC (rev 13202)
+++ trunk/mapserver/mapcache/include/mapcache.h	2012-03-06 10:57:46 UTC (rev 13203)
@@ -381,6 +381,7 @@
     char *base_directory;
     char *filename_template;
     int symlink_blank;
+    int creation_retry;
 };
 
 #ifdef USE_TIFF

Modified: trunk/mapserver/mapcache/lib/cache_disk.c
===================================================================
--- trunk/mapserver/mapcache/lib/cache_disk.c	2012-03-05 16:22:35 UTC (rev 13202)
+++ trunk/mapserver/mapcache/lib/cache_disk.c	2012-03-06 10:57:46 UTC (rev 13203)
@@ -265,6 +265,8 @@
    apr_status_t ret;
    char errmsg[120];
    char *filename, *hackptr1, *hackptr2=NULL;
+   const int creation_retry = ((mapcache_cache_disk*)tile->tileset->cache)->creation_retry;
+
 #ifdef DEBUG
    /* all this should be checked at a higher level */
    if(!tile->encoded_data && !tile->raw_image) {
@@ -369,10 +371,32 @@
          } else {
             apr_file_close(f);
          }
-         if(symlink(blankname,filename) != 0) {
-            char *error = strerror(errno);
-            ctx->set_error(ctx, 500,  "failed to link tile %s to %s: %s",filename, blankname, error);
-            return; /* we could not create the file */
+
+         int retry_count_create_symlink = 0;
+         /*
+          * depending on configuration symlink creation will retry if it fails.
+          * this can happen on nfs mounted network storage.
+          * the solution is to create the containing directory again and retry the symlink creation.
+          */
+         while(symlink(blankname,filename) != 0) {
+            retry_count_create_symlink++;
+
+            if(retry_count_create_symlink > creation_retry) {
+               char *error = strerror(errno);
+               ctx->set_error(ctx, 500, "failed to link tile %s to %s: %s",filename, blankname, error);
+               return; /* we could not create the file */
+            }
+
+            *hackptr2 = '\0';
+
+            if(APR_SUCCESS != (ret = apr_dir_make_recursive(filename,APR_OS_DEFAULT,ctx->pool))) {
+               if(!APR_STATUS_IS_EEXIST(ret)) {
+                  ctx->set_error(ctx, 500, "failed to create symlink, can not create directory %s: %s",filename, apr_strerror(ret,errmsg,120));
+                  return; /* we could not create the file */
+               }
+            }
+
+            *hackptr2 = '/';
          }
 #ifdef DEBUG        
          ctx->log(ctx, MAPCACHE_DEBUG, "linked blank tile %s to %s",filename,blankname);
@@ -389,11 +413,33 @@
       GC_CHECK_ERROR(ctx);
    }
 
-   if((ret = apr_file_open(&f, filename,
+   int retry_count_create_file = 0;
+   /*
+    * depending on configuration file creation will retry if it fails.
+    * this can happen on nfs mounted network storage.
+    * the solution is to create the containing directory again and retry the file creation.
+    */
+   while((ret = apr_file_open(&f, filename,
          APR_FOPEN_CREATE|APR_FOPEN_WRITE|APR_FOPEN_BUFFERED|APR_FOPEN_BINARY,
          APR_OS_DEFAULT, ctx->pool)) != APR_SUCCESS) {
-      ctx->set_error(ctx, 500,  "failed to create file %s: %s",filename, apr_strerror(ret,errmsg,120));
-      return; /* we could not create the file */
+
+      retry_count_create_file++;
+
+      if(retry_count_create_file > creation_retry) {
+         ctx->set_error(ctx, 500, "failed to create file %s: %s",filename, apr_strerror(ret,errmsg,120));
+         return; /* we could not create the file */
+      }
+
+      *hackptr2 = '\0';
+
+      if(APR_SUCCESS != (ret = apr_dir_make_recursive(filename,APR_OS_DEFAULT,ctx->pool))) {
+         if(!APR_STATUS_IS_EEXIST(ret)) {
+            ctx->set_error(ctx, 500, "failed to create file, can not create directory %s: %s",filename, apr_strerror(ret,errmsg,120));
+            return; /* we could not create the file */
+         }
+      }
+
+      *hackptr2 = '/';
    }
 
    bytes = (apr_size_t)tile->encoded_data->size;
@@ -439,6 +485,10 @@
          dcache->filename_template = apr_pstrdup(ctx->pool,cur_node->txt);
       }
    }
+
+   if ((cur_node = ezxml_child(node,"creation_retry")) != NULL) {
+      dcache->creation_retry = atoi(cur_node->txt);
+   }
 }
 
 /**
@@ -465,6 +515,7 @@
       return NULL;
    }
    cache->symlink_blank = 0;
+   cache->creation_retry = 0;
    cache->cache.metadata = apr_table_make(ctx->pool,3);
    cache->cache.type = MAPCACHE_CACHE_DISK;
    cache->cache.tile_delete = _mapcache_cache_disk_delete;



More information about the mapserver-commits mailing list