I'm sending 5 requests to my Web App:
import requests
backodds = "3.00"
layteam = "Flamengo"
layodds = "1.50"
advantage = "25.55"
webAppsUrl = "https://script.google.com/macros/s/XXXX/exec"
for i in range(5):
requests.get(webAppsUrl + "?backteam=" + str(i) + "&backodds=" + backodds + "&layteam=" + layteam + "&layodds=" + layodds + "&advantage=" + advantage)
If I could wait for each of the requests to execute, I could just leave my Web App like this:
function doGet(e) {
const lock = LockService.getDocumentLock();
if (lock.tryLock(360000)) {
try {
var backteam = e.parameter.backteam;
var backodds = e.parameter.backodds;
var layteam = e.parameter.layteam;
var layodds = e.parameter.layodds;
var advantage = e.parameter.advantage;
Utilities.sleep(30000) // I swapped the tasks for a sleep just for testing
var second_sheet = SpreadsheetApp.openById('XXXXXXX');
var second_sheet_page = second_sheet.getSheetByName('STACKTEST');
var r = 1;
while (second_sheet_page.getRange(r, 1).getValue()) {
r++;
}
second_sheet_page.getRange(r, 1, 1, 5).setValues([[backteam,backodds,layteam,layodds,advantage]]);
} catch (e) {
//pass
} finally {
lock.releaseLock();
}
} else {
//pass
}
}
As I don't want to wait for each request to finish executing (because it takes more than 30 seconds each and I don't care what happens during and after the execution), I'm creating a trigger for each request:
var RECURRING_KEY = "recurring";
var ARGUMENTS_KEY = "arguments";
function setupTriggerArguments(trigger, functionArguments, recurring) {
var triggerUid = trigger.getUniqueId();
var triggerData = {};
triggerData[RECURRING_KEY] = recurring;
triggerData[ARGUMENTS_KEY] = functionArguments;
PropertiesService.getScriptProperties().setProperty(triggerUid, JSON.stringify(triggerData));
}
function handleTriggered(triggerUid) {
const lock = LockService.getDocumentLock();
if (lock.tryLock(360000)) {
var scriptProperties = PropertiesService.getScriptProperties();
var triggerData = JSON.parse(scriptProperties.getProperty(triggerUid));
var second_sheet = SpreadsheetApp.openById('XXXXXX');
var second_sheet_page = second_sheet.getSheetByName('StackOverflow');
var r = 1;
while (second_sheet_page.getRange(r, 1).getValue()) {
r++;
}
var to_sheet = [
[triggerData.arguments[0],triggerData.arguments[1],triggerData.arguments[2],triggerData.arguments[3],triggerData.arguments[4]]
];
Utilities.sleep(30000) // I swapped the tasks for a sleep just for testing
second_sheet_page.getRange(r, 1, to_sheet.length, to_sheet[0].length).setValues(to_sheet);
} else {
console.error("Timeout");
}
if (!triggerData[RECURRING_KEY]) {
deleteTriggerByUid(triggerUid);
}
return triggerData[ARGUMENTS_KEY];
}
function deleteTriggerArguments(triggerUid) {
PropertiesService.getScriptProperties().deleteProperty(triggerUid);
}
function deleteTriggerByUid(triggerUid) {
if (!ScriptApp.getProjectTriggers().some(function(trigger) {
if (trigger.getUniqueId() === triggerUid) {
ScriptApp.deleteTrigger(trigger);
return true;
}
return false;
})) {
console.error("Could not find trigger with id '%s'", triggerUid);
}
deleteTriggerArguments(triggerUid);
}
function deleteTrigger(trigger) {
ScriptApp.deleteTrigger(trigger);
deleteTriggerArguments(trigger.getUniqueId());
}
function doGet(e) {
var trigger = ScriptApp.newTrigger("triggerfunct").timeBased()
.after(1)
.create();
setupTriggerArguments(trigger, [e.parameter.backteam, e.parameter.backodds, e.parameter.layteam, e.parameter.layodds, e.parameter.advantage], false);
}
function triggerfunct(event) {
var functionArguments = handleTriggered(event.triggerUid);
console.info("Function arguments: %s", functionArguments);
}
But the current result, in addition to not respecting the sequence of the data sent, it is noticed that values are superimposed instead of being placed on different lines, even though I have placed a lock on the document so that this does not happen.
My expected result is this:
Is there a way to solve these problems?
My real need is to activate the code in GAS via requests
, but I don't want to wait for the end of each execution of the entire code so that the requests
has been completed.
In other words, I want to activate my code in GAS as many times as I want, generating a queue of executions if necessary, and go on with my life without worrying about how long it will take to execute.
Putting requests
in the background in Python using subprocess
for example I can't because it would continue to be executed and this significantly increases the monthly cost, so what I really need is a way to totally unlink the execution of the GAS with the request made.
To speed up the process I modified the code:
var second_sheet = SpreadsheetApp.openById('XXXXXXX');
var second_sheet_page = second_sheet.getSheetByName('STACKTEST');
var r = 1;
while (second_sheet_page.getRange(r, 1).getValue()) {
r++;
}
second_sheet_page.getRange(r, 1, 1, 5).setValues([[backteam,backodds,layteam,layodds,advantage]]);
To (Enable the Google Sheets API advanced service):
var sheet_id = 'XXXXXXX';
var sheet = SpreadsheetApp.openById(sheet_id);
var sheet_page = sheet.getSheetByName('STACKTEST');
var avals = Sheets.Spreadsheets.Values.get(sheet_id, 'STACKTEST!A1:A').values;
var r = avals.length + 1;
var to_sheet = [
[triggerData.arguments[0],triggerData.arguments[1],triggerData.arguments[2],triggerData.arguments[3],triggerData.arguments[4]]
];
sheet_page.getRange(r, 1, to_sheet.length, to_sheet[0].length).setValues(to_sheet);
Test reduce time
Using the first method when 12800 rows filled (so add the values in row 12801):
Timeout Error (exceeded the 6 minute runtime limit)
Using Google Sheets API:
804ms
Using the first method when 1000 rows filled (so add the values in row 1001):
3493ms
Using Google Sheets API:
833ms