much better async handling
authorAndrew Tridgell <tridge@samba.org>
Sun, 10 Oct 2010 05:09:45 +0000 (16:09 +1100)
committerAndrew Tridgell <tridge@samba.org>
Sun, 10 Oct 2010 05:09:45 +0000 (16:09 +1100)
live/graphs.js
live/index.html

index 5cd2a41f33daa621f3f09a9ad1575cc5c0bfa3ff..27da373691d49aeb1a1fc140bcc6b8f813b4953d 100644 (file)
@@ -28,6 +28,27 @@ function graph_div(divname) {
   }
 }
 
+
+/* a global call queue */
+global_queue = new Array();
+
+function run_queue() {
+  var qe = global_queue[0];
+  qe.callback(qe.arg);
+  global_queue.shift();
+  if (global_queue.length > 0) {
+    setTimeout(run_queue, 10);    
+  }
+}
+
+function queue_call(callback, arg) {
+  global_queue.push( { callback: callback, arg : arg });
+  if (global_queue.length == 1) {
+    setTimeout(run_queue, 10);
+  }
+}
+
+
 /*
   date parser
  */
@@ -54,21 +75,21 @@ CSV_Cache = new Array();
 /*
   load a CSV file, returing column names and data via a callback
  */
-function load_CSV(d, filename, callback) {
+function load_CSV(filename, callback) {
 
   /* maybe its in the global cache? */
   if (CSV_Cache[filename] !== undefined) {
     if (CSV_Cache[filename].pending) {
       /* it might be pending */
       var q = CSV_Cache[filename].queue.length;
-      CSV_Cache[filename].queue[q] = {filename:filename, d:d, callback:callback};
+      CSV_Cache[filename].queue[q] = {filename:filename, callback:callback};
       return;
     }
-    d.filename = CSV_Cache[filename].filename;
-    d.labels   = CSV_Cache[filename].labels;
-    d.data     = CSV_Cache[filename].data;
-    writeDebug("cache hit: " + filename);
-    callback(d);
+
+    var d = { filename: CSV_Cache[filename].filename,
+             labels:   CSV_Cache[filename].labels.slice(0),
+             data:     CSV_Cache[filename].data.slice(0) };
+    queue_call(callback, d);
     return;
   }
 
@@ -102,18 +123,21 @@ function load_CSV(d, filename, callback) {
     CSV_Cache[caller.filename].filename = filename;
     CSV_Cache[caller.filename].labels   = labels;
     CSV_Cache[caller.filename].data     = data;
+
+    var d = { filename: CSV_Cache[filename].filename,
+             labels:   CSV_Cache[filename].labels.slice(0),
+             data:     CSV_Cache[filename].data.slice(0) };
+    queue_call(caller.callback, d);
+
+    /* fire off any pending callbacks */
     for (var q=0; q<CSV_Cache[caller.filename].queue.length; q++) {
-      CSV_Cache[caller.filename].queue[q].d.data = data;
-      CSV_Cache[caller.filename].queue[q].d.labels = labels;
-      CSV_Cache[caller.filename].queue[q].callback(CSV_Cache[caller.filename].queue[q].d);
+      var d = { filename: CSV_Cache[filename].filename,
+               labels:   CSV_Cache[filename].labels.slice(0),
+               data:     CSV_Cache[filename].data.slice(0) };
+      queue_call(CSV_Cache[caller.filename].queue[q].callback, d);
     }
     CSV_Cache[caller.filename].pending = false;
     CSV_Cache[caller.filename].queue   = null;
-
-    caller.ret.filename = caller.filename;
-    caller.ret.labels   = labels;
-    caller.ret.data     = data;
-    caller.callback(caller.ret);
   }
 
   /* make the async request for the file */
@@ -121,7 +145,6 @@ function load_CSV(d, filename, callback) {
   caller.r = new XMLHttpRequest();
   caller.callback = callback;
   caller.load_CSV_callback = load_CSV_callback;
-  caller.ret = d;
   caller.filename = filename;
 
   /* check the status when that returns */
@@ -191,14 +214,14 @@ function in_array(a, v) {
 function get_csv_data(filenames, columns, callback) {
   var caller = new Object();
   caller.d = new Array();
-  caller.columns = columns;
-  caller.filenames = filenames;
+  caller.columns = columns.slice(0);
+  caller.filenames = filenames.slice(0);
   caller.callback = callback;
 
   /* initially blank data - we can tell a load has completed when it
      is filled in */
-  for (var i=0; i<filenames.length; i++) {
-    caller.d[i] = { filename: filenames[i], labels: null, data: null};
+  for (var i=0; i<caller.filenames.length; i++) {
+    caller.d[i] = { filename: caller.filenames[i], labels: null, data: null};
   }
 
   /* process one loaded CSV, mapping the data for
@@ -231,8 +254,9 @@ function get_csv_data(filenames, columns, callback) {
     d.labels = labels;
 
     for (var f=0; f<caller.filenames.length; f++) { 
-      if (d.filename == caller.filenames[f]) {
-       caller.d[f] = { filename: d.filename, labels: d.labels, data: d.data };
+      if (d.filename == caller.d[f].filename) {
+       caller.d[f].labels = labels;
+       caller.d[f].data = data;
       }
     }
 
@@ -244,14 +268,12 @@ function get_csv_data(filenames, columns, callback) {
     }
 
     /* they are all loaded - make the callback */
-    caller.callback(caller.d);
+    queue_call(caller.callback, caller.d);
   }
 
-  caller.process_one_csv = process_one_csv;
-
   /* start the loading */
-  for (var i=0; i<filenames.length; i++) {
-    load_CSV(caller.d[i], filenames[i], caller.process_one_csv);
+  for (var i=0; i<caller.filenames.length; i++) {
+    load_CSV(caller.filenames[i], process_one_csv);
   }
 }
 
@@ -285,8 +307,8 @@ function graph_csv_files_func(divname, filenames, columns, func1, func2, attrs)
   /* load the csv files */
   var caller = new Object();
   caller.divname   = divname;
-  caller.filenames = filenames;
-  caller.columns   = columns;
+  caller.filenames = filenames.slice(0);
+  caller.columns   = columns.slice(0);
   caller.func1     = func1;
   caller.func2     = func2;
   caller.attrs     = attrs;
@@ -381,10 +403,8 @@ function graph_csv_files_func(divname, filenames, columns, func1, func2, attrs)
     }
   }
 
-  caller.loaded_callback = loaded_callback;
-
   graph_div(divname);
-  get_csv_data(filenames, columns, caller.loaded_callback);
+  get_csv_data(caller.filenames, caller.columns, loaded_callback);
 }
 
 
@@ -410,7 +430,7 @@ function sum(v) {
   graph one column from a set of CSV files
  */
 function graph_csv_files(divname, filenames, column, attrs) {
-  return graph_csv_files_func(divname, filenames, [ column ], null, null, attrs);
+  return graph_csv_files_func(divname, filenames, [column], null, null, attrs);
 }
 
 /*
@@ -435,6 +455,7 @@ function show_graphs() {
                       "Pac",
                       { includeZero: true });
 
+
   heading(3, "AC Power from each inverter (W)");
 
   graph_csv_files("AC Power", 
@@ -524,10 +545,6 @@ function show_graphs() {
   in_redraw = true;
 }
 
-function redraw_graphs() {
-  return false;
-}
-
 function set_date(e) {
   var dp = datePickerController.getDatePicker("pvdate");
   pvdate = dp.date;
index 91f5e8ed7f3d3a57e05f5142fbd54247f1f8d275..9be4a488b682df93f34fa069c3f63c534263b575 100755 (executable)
@@ -20,7 +20,7 @@
 <body>
 <h1>Daily Inverter Data</h1>
 
-<form id="dateForm" method="get" onsubmit="return redraw_graphs();" action="">
+<form id="dateForm" method="get" onsubmit="return false;" action="">
     <fieldset>
       <p><input type="text" class="w8em format-d-m-y highlight-days-67
       range-high-today range-low-2010-10-09" name="pvdate" id="pvdate" value="" maxlength="10" /></p>