Bypass script execution timeout, programmatically

Does your script exceed maximum execution time? Here's a solution to automatically bypass that.

Bypass script execution timeout, programmatically
an app script junkie's worst nightmare:
script "exceeded maximum execution time"

problem statement

Execution Timeout
Execution Timeout

as per google's quotas for its apps script services, the script runtime can vary either between 6 mins. per execution  - if you're on an unpaid account - or 30 mins., if on paid. normally, 6 mins. is sufficient to run typical automations for everyday life but at times, there are instances where you may want the script to run a longer time, depending on the tasks it is executing (i.e. if the count of tasks are high) and/or the amount of information its processing.

either way, the only non-tech solution to this was to re-run the script over and again, until such time that all tasks are completed; however, this brings up a number of challenges, a few of what i've experienced are as follows -

  • starts from beginning: obviously, this depends heavily on the structure of the code but nonetheless, there is currently no way that the script would automatically know where it last stopped (owing to an execution timeout) and to having commenced from there on a re-run.
  • overwrites or repeats data: again, depending on the architecture of the code, if you're appending data to either a doc, sheet or someplace else, you'd be required to maintain a marker or "run a check" to assess what-was-last, before writing data to said system.
  • manual: notwithstanding my immense respect towards the divine human intervention 🙄, there's but always a chance of human error in manually having to first check where to begin and reassess what has to be done.

architecture

after scouring through the internet for its various solutions on the matter, i've combined my solution that reflects 2 key aspects -

1. detection

  • check elapsed time: create a seperate function which returns the difference between now (as in, when the script calls this function) and from when the script started to execute, owing to the original function
  • break before hitting threshold: this is the key; in order to successfully exit the script before it hits it's mandated timeout limit, you'd need to set a threshold that's well before when the script ought to terminate automatically

2. evasion

  • spawn a time-based trigger before killing (break;) the script
  • kill all triggers after the end of final execution

codebase

// var today = new Date();
// 'today' is declard in the original script

function isTimeUp(today) {
  var now = new Date();
  return now.getTime() - today.getTime() > 30000;
  // 30000 = 30 seconds; this is the threshold limit
  // you are free to setup your own threshold limit
}
the threshold detection & comparison module
function firstFunction() {
    var today = new Date();    
    for (var i = 0; i < something.length; i++) {
        // check if the script has exceeded threshold
        if (isTimeUp(today)) {
            // schedule a trigger for a different function
            ScriptApp.newTrigger("repeatFunction")
                .timeBased()
                .everyMinutes(1)
                .create();
            break;
        }
    }
}

function repeatFunction() {
    for (/* condition */) {
        // do stuff; maybe not everything from firstFunction()
        if (/* test condition that defines the last action */) {
            var triggers = ScriptApp.getProjectTriggers();
            for (var i = 0; i < triggers.length; i++) {
                // delete all triggers
                ScriptApp.deleteTrigger(triggers[i]);
            }
            break;
        } 
    }
}
the evasion and automation module

note that doing so will create time based repetitions (sort of a cron-job, if you will) that you could monitor via the apps script developer hub.