Testing parallel processing inline

One problem with running things from html service with google.script.run is that you don't have access to logging and execution log, so it's difficult to debug. I like to run my profile components inline first to make sure they work. Here's how you can simulate running this stuff from google.script.run in the context of a normal apps script.

This function takes your profile and executes the named function, and passes over the data just as would happen if it was called from google.script.run.

/** 
 * from a profile, emulates running it from the sidebar
 * @param {object} profile the profile
 * @param {data} the data to pass
 * @return {object} whatever the function would return
 */
function inLineTest (profile,data) {
  var evalable = profile.functionName + "(" + JSON.stringify(profile.options) + (data ? ("," + JSON.stringify(data)) : "") + ")";
  return eval(evalable);  
}

We can call that, passing each of the individual run profiles, and emulate passing the data from the previous stage just as happens when being orchestrated by the html service. Of course you can only run one thing at once, but this allows you to test all your profiles in a much more visible environment. 

function smallDbTest() {
  // i'll do properties
  var p = cUseful.clone(dbDataStoreParameters());

  // clear the sheet
  var d = inLineTest (dbAsyncClear (p.parameters, p.driver,p.clearProcess),null);

  // some test data
  var d = inLineTest (dbAsyncTestData (),null);

  // reduce
  var d = inLineTest (dbAsyncReduce(),[{results:d}]);

  // the tests
  var d = inLineTest (dbAsyncExecute (p.parameters,p.driver,0,1,p.process),[{results:d}]);

  // reduce
  var d = inLineTest (dbAsyncReduce(),[{results:d}]);
  
  // log
  var d = inLineTest (dbAsyncLog(p.driver),[{results:d}]);

}

Notice that I use functions to set up the profiles. I use exactly the same ones when running this for real. That way I can be sure I'm testing what I'm planning to use in real life. Here's the example for the reduce function. 

function dbAsyncReduce () {
  return {
    "name": "reduction",
    "functionName":"reduceTheResults",
    "debug":false,
    "options":{
    }
  };
}

Later on, when I run this for real, I put it all together like this


function dbAsyncProfiles(dbParameters, dbDriver, process, clearProcess) {
  
  var CHUNKS = 4;
  var profile = [];
  
  // clear the db
  var profileClear = [dbAsyncClear (dbParameters, dbDriver, clearProcess )];
  
 // get the test data
  var profileTest = [dbAsyncTestData ()];
  
  // reduce the test data
  var profileReduction = [dbAsyncReduce()];
    
  // get and process all the messages
  var profileSheets = [];
  for (var i =0; i <CHUNKS;i++ ) {
    profileSheets.push (dbAsyncExecute (dbParameters,dbDriver,i,CHUNKS,process));
  }
  
  //Log the results
  var profileLog= [dbAsyncLog (dbDriver)];

  profile.push(
    profileClear,
    profileTest,
    profileReduction,
    profileSheets,
    profileReduction,
    profileLog
  );
  
  return profile;
  
}


You may also find this post useful, if you have some unserializeable objects to deal with. How to pass non stringifyable objects to html service

For more on this topic, see Running things in parallel using HTML service. For more snippets like this see Google Apps Scripts snippets

For help and more information join our forum,follow the blog or follow me on twitter .

You want to learn Google Apps Script?

Learning Apps Script, (and transitioning from VBA) are covered comprehensively in my my book, Going Gas - from VBA to Apps script, available All formats are available now from O'Reilly,Amazon and all good bookshops. You can also read a preview on O'Reilly

If you prefer Video style learning I also have two courses available. also published by O'Reilly.
Google Apps Script for Developers and Google Apps Script for Beginners.




Comments