Google Apps Script在50%的情况下会超时触发,但Console Run在100%的情况下有效



我正面临一个问题,我使用谷歌应用程序脚本自动化一些产品提要操作(解析XML,添加补充数据,转换到不同的格式:TSV, CSV, XML),等等。

当我直接运行脚本时,它100%的工作时间,我在使用它的6个月里没有遇到任何错误。然而,当在CEE时间的每天1点到5点之间设置自动时间触发器时,由于超出时间而导致的故障百分比几乎是50%(我知道间隔是1小时,但是在此间隔中安排了多个脚本会发生这种情况)。

我看了一遍脚本,到目前为止还没有找到任何解决方案,也没有发现任何其他类似的问题。

值得一提:

  • 项目链接到一个Google Cloud project,所以执行时间是30分钟。
  • XML源是一个电子表格,大约有16K行&
  • 源电子表格内容来自一个IMPORTRANGE(该架构是一个包含所有所需列的大提要和许多包含有意义列的IMPORTRANGE的小提要);自定义列名)。从这里开始,如果需要的话,我运行一个XML导出脚本,因为Google Drive不支持直接XML转换。XML转换脚本失败。
  • 脚本不抛出错误,只是在1800秒后超时。

我考虑不使用XML服务,并使用一些字符串连接来构建XML字符串,这应该会加快速度,但我有这个问题的脚本也解析初始XML,那里使用正则表达式解析可能会变得相当复杂,我宁愿理解我做错了什么从效率的角度来看。

我有一些编码经验,但不是很多与现代JS,也不是很多与谷歌应用程序脚本,所以任何提示/有意义的文章都是赞赏的。

转换成XML脚本(有问题的脚本之一)

function main(){
const ID = "";
var data = SpreadsheetApp.openById(ID).getDataRange().getValues();
var headers = [];
var root = XmlService.createElement('shop');
for (var j = 0; j < data.length; j++){
if(j == 0){
headers = data[j];
continue;
}
if(data[j][0] != ""){
var row = XmlService.createElement('shopitem')
for(var k = 0; k < data[0].length; k++){
if(headers[k].startsWith("P_")){
var vbl = XmlService.createElement("PARAM");
vbl.addContent(XmlService.createElement("PARAM_NAME").setText(headers[k].replace("P_", "")));
vbl.addContent(XmlService.createElement("PARAM_VAL").setText(data[j][k]));
}else{
var col = headers[k];
var type = data[j][k].constructor.name;
if(data[j][k].constructor.name == 'Date'){        
var vbl = XmlService.createElement(col).setText(data[j][k].toISOString().slice(0, 10));
}else{
var vbl = XmlService.createElement(col).setText(data[j][k])
}
}

row.addContent(vbl)
}

root.addContent(row) 

}
}  

var document = XmlService.createDocument(root);
var xml = XmlService.getPrettyFormat().format(document);


overwriteFile(new Utilities.newBlob(xml), "file-id")
}
function overwriteFile(blobOfNewContent,currentFileID) {
var currentFile;

currentFile = DriveApp.getFileById(currentFileID);    

if (currentFile) {//If there is a truthy value for the current file
Drive.Files.update({
title: currentFile.getName(), mimeType: currentFile.getMimeType()
}, currentFile.getId(), blobOfNewContent);
}
}

问题:

  1. 为什么每次控制台运行都工作,但时间触发器不工作?
  2. 可以做些什么来优化?

谢谢大家!

我试图将驱动器中的文件创建为新文件,而不是替换其内容,但这并没有导致错误率的提高,因此我认为问题在于调用XMLService API,但我不确定是否"绕过它/不使用它";

我研究了批量XML解析,以避免在for循环中使用api调用,但没有找到任何东西。

我的下一个选择是用regex/连接规则构造/解析XML作为字符串,但这感觉像是一个不太专业的替代方案,我不确定它是否能解决问题,因为我没能诊断出原因。

如果两次处理的数据量相同,我想不出有什么理由(也找不到有记录的理由)通过时间驱动的触发器运行时执行时间更长。

然而,这里有一些点可能有助于优化运行时性能:

  • 如果从源电子表格中获取的数据很大,您可能希望拆分范围值并处理每个"范围区域"。
  • 虽然表格和应用程序脚本可以处理相当数量的数据,这些都不是解决方案,也不建议它。你可以考虑使用合适的数据库或其他谷歌解决方案(如BigQuery或Firebase的Firestore)
  • 以编程方式创建另一个定时触发器,在一定时间后完成执行。
  • 或者,您可以使用此模板向Google报告此行为。

相关内容

最新更新