src/graph_list.c: cachefile → cache_file
[collection4.git] / src / graph_list.c
index 1b10e25..b979672 100644 (file)
@@ -38,6 +38,7 @@
 
 #include "graph_list.h"
 #include "common.h"
+#include "data_provider.h"
 #include "filesystem.h"
 #include "graph.h"
 #include "graph_config.h"
@@ -54,7 +55,6 @@
  * Defines
  */
 #define UPDATE_INTERVAL 900
-#define CACHE_FILE "/tmp/collection4.json"
 
 /*
  * Global variables
@@ -209,6 +209,14 @@ static int gl_register_file (const graph_ident_t *file, /* {{{ */
   return (0);
 } /* }}} int gl_register_file */
 
+static int gl_register_ident (graph_ident_t *ident, /* {{{ */
+    __attribute__((unused)) void *user_data)
+{
+  /* TODO: Check for duplicates if multiple data providers are used. */
+
+  return (gl_register_file (ident, user_data));
+} /* }}} int gl_register_ident */
+
 static const char *get_part_from_param (const char *prim_key, /* {{{ */
     const char *sec_key)
 {
@@ -260,25 +268,36 @@ static int gl_update_cache (void) /* {{{ */
   int fd;
   yajl_gen handler;
   yajl_gen_config handler_config = { /* pretty = */ 1, /* indent = */ "  " };
+  const char *cache_file = graph_config_get_cache_file ();
   struct flock lock;
   struct stat statbuf;
   int status;
   size_t i;
 
   memset (&statbuf, 0, sizeof (statbuf));
-  status = stat (CACHE_FILE, &statbuf);
+  status = stat (cache_file, &statbuf);
   if (status == 0)
   {
     if (statbuf.st_mtime >= gl_last_update)
+      /* Not writing to cache because it's at least as new as our internal data */
       return (0);
   }
+  else
+  {
+    status = errno;
+    fprintf (stderr, "gl_update_cache: stat(2) failed with status %i\n",
+        status);
+    /* Continue writing the file if possible. */
+  }
 
-  fd = open (CACHE_FILE, O_WRONLY | O_TRUNC | O_CREAT,
+  fd = open (cache_file, O_WRONLY | O_TRUNC | O_CREAT,
       S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
   if (fd < 0)
   {
-    fprintf (stderr, "gl_update_cache: open(2) failed with status %i\n", errno);
-    return (errno);
+    status = errno;
+    fprintf (stderr, "gl_update_cache: open(2) failed with status %i\n",
+        status);
+    return (status);
   }
 
   memset (&lock, 0, sizeof (lock));
@@ -309,6 +328,9 @@ static int gl_update_cache (void) /* {{{ */
     return (-1);
   }
 
+  fprintf (stderr, "gl_update_cache: Start writing data\n");
+  fflush (stderr);
+
   yajl_gen_array_open (handler);
 
   for (i = 0; i < gl_active_num; i++)
@@ -322,14 +344,12 @@ static int gl_update_cache (void) /* {{{ */
   yajl_gen_free (handler);
   close (fd);
 
+  fprintf (stderr, "gl_update_cache: Finished writing data\n");
+  fflush (stderr);
+
   return (0);
 } /* }}} int gl_update_cache */
 
-static int gl_scan_directory (void)
-{
-  return (-1);
-} /* }}} int gl_scan_directory */
-
 /*
  * JSON parsing functions
  */
@@ -600,7 +620,7 @@ static int gl_read_cache (_Bool block) /* {{{ */
   int status;
   time_t now;
 
-  fd = open (CACHE_FILE, O_RDONLY);
+  fd = open (graph_config_get_cache_file (), O_RDONLY);
   if (fd < 0)
   {
     fprintf (stderr, "gl_read_cache: open(2) failed with status %i\n", errno);
@@ -656,15 +676,25 @@ static int gl_read_cache (_Bool block) /* {{{ */
 
   now = time (NULL);
 
-  if (statbuf.st_mtime <= gl_last_update)
+  if (block)
+  {
+    /* Read the file. No excuses. */
+  }
+  else if (statbuf.st_mtime <= gl_last_update)
   {
     /* Our current data is at least as new as the cache. Return. */
+    fprintf (stderr, "gl_read_cache: Not using cache because "
+        "the internal data is newer\n");
+    fflush (stderr);
     close (fd);
     return (0);
   }
   else if ((statbuf.st_mtime + UPDATE_INTERVAL) < now)
   {
-    /* We'll scan the directory anyway, so there is no need to parse the cache here. */
+    /* We'll scan the directory anyway, so there is no need to parse the cache
+     * here. */
+    fprintf (stderr, "gl_read_cache: Not using cache because it's too old\n");
+    fflush (stderr);
     close (fd);
     return (0);
   }
@@ -680,6 +710,9 @@ static int gl_read_cache (_Bool block) /* {{{ */
       /* alloc funcs = */ NULL,
       &context);
 
+  fprintf (stderr, "gl_read_cache: Start parsing data\n");
+  fflush (stderr);
+
   while (42)
   {
     ssize_t rd_status;
@@ -691,10 +724,11 @@ static int gl_read_cache (_Bool block) /* {{{ */
       if ((errno == EINTR) || (errno == EAGAIN))
         continue;
 
+      status = errno;
       fprintf (stderr, "gl_read_cache: read(2) failed with status %i\n",
-          errno);
+          status);
       close (fd);
-      return (errno);
+      return (status);
     }
     else if (rd_status == 0)
     {
@@ -709,10 +743,14 @@ static int gl_read_cache (_Bool block) /* {{{ */
     }
   }
 
-  fprintf (stderr, "gl_read_cache: Closing cache file and returning\n");
+  yajl_free (handle);
+
   gl_last_update = statbuf.st_mtime;
   close (fd);
 
+  fprintf (stderr, "gl_read_cache: Finished parsing data\n");
+  fflush (stderr);
+
   return (0);
 } /* }}} int gl_read_cache */
 
@@ -743,8 +781,8 @@ int gl_config_submit (void) /* {{{ */
   return (0);
 } /* }}} int graph_config_submit */
 
-int gl_graph_get_all (graph_callback_t callback, /* {{{ */
-    void *user_data)
+int gl_graph_get_all (_Bool include_dynamic, /* {{{ */
+    graph_callback_t callback, void *user_data)
 {
   size_t i;
 
@@ -762,6 +800,9 @@ int gl_graph_get_all (graph_callback_t callback, /* {{{ */
       return (status);
   }
 
+  if (!include_dynamic)
+    return (0);
+
   for (i = 0; i < gl_dynamic_num; i++)
   {
     int status;
@@ -1039,12 +1080,21 @@ int gl_update (_Bool request_served) /* {{{ */
   graph_read_config ();
 
   status = gl_read_cache (/* block = */ 1);
+  /* We have *something* to work with. Even if it's outdated, just get on with
+   * handling the request and take care of re-reading data later on. */
+  if ((status == 0) && !request_served)
+    return (0);
 
   if ((status != 0)
       || ((gl_last_update + UPDATE_INTERVAL) < now))
   {
-    status = fs_scan (/* callback = */ gl_register_file,
-        /* user data = */ NULL);
+    /* Clear state */
+    gl_clear_instances ();
+    gl_clear_hosts ();
+    gl_destroy (&gl_dynamic, &gl_dynamic_num);
+
+    data_provider_get_idents (gl_register_ident, /* user data = */ NULL);
+
     gl_last_update = now;
   }