使用~7600项调用scriptDb.saveBatch会导致rateMax错误

时间:2014-04-03 12:41:49

标签: google-apps-script scriptdb

我正在开发应用脚本,以定期检查Web服务上的已修改项目。由于API调用耗时太长,我一直试图在ScriptDb中定期缓存一些数据。但是,尝试使用scriptDb.saveBatch更新数据始终会导致以下错误:

Service invoked too many times in a short time: scriptdb rateMax. Try Utilities.sleep(1000) between calls.

我的脚本正在查询ScriptDb并返回约7600条记录的结果集,修改这些记录,然后将所有内容保存回批处理中。考虑到Google提供的工具,我无法以任何方式考虑减少我所做的数据库调用次数。这对ScriptDb来说真的太过难以处理,还是有一些方法可以改进我的代码?

function getRootFolders() {
  var updateTimestamp = new Date().valueOf();

  var results = GetModifiedFolders(ROOT_FOLDER); //Returns results from an API call
  var data = results.data; //The actual data from the API, as an array
  var len = data.length;

  if (len > 0) {    
    //Get a collection of dbMaps from ScriptDb
    var maps = {}; //Store as an object for easy updating
    var getMaps = db.query({'type': 'baseFolder'}).limit(50000); //Returns 7621 items

    while (getMaps.hasNext()) {
      var map = getMaps.next();
      maps[map.boxId] = map;
    }

    //Iterate through the results
    for (i = 0; i < len; i++) {
      var item = data[i];  
      var map = maps[item.boxId]; //Try to retrive an existing dbMap
      if (map) { //If it exists, update the existing dbMap
        map.modified = item.modified;
        map.updateTimestamp = updateTimestamp;
      }
      else { //Otherwise, insert the result into the collection of dbMaps   
        item.type = 'baseFolder';
        item.updateTimestamp = updateTimestamp;   
        maps[item.boxId] = item;
      }
    }

    //Convert the object back to an array, and use that to save to ScriptDb
    var toSave = [];
    for (var prop in dbMaps) {
      toSave.push(dbMaps[prop]);
    }

    var mutations = db.saveBatch(toSave, false); //FAIL with scriptdb rateMax
    if (db.allOk(mutations)) {
      ( . . . )
    }
  }
}

修改

为了阻止这种情况的发生,我做了一些改变,但无济于事。我在打电话给saveBatch之前已经睡了几分钟,然后我会在多个较小的批次中保存,并在每个之间睡觉。

此时,我无法想象为什么我仍然会收到此rateMax错误。我错过了我的代码是否有问题,或者这是应用程序脚本中的错误?我认为这是我的错,但我无法看到它。

以下是我添加的内容:

//Retrieving data from the API takes ~1 minute

//Sleep for a while to avoid rateMax error
var waitUntil = updateTimestamp + 240000; //Wait until there's only 1 minute left in the 5 minute quota
var msToWait = waitUntil - (now.valueOf());
Utilities.sleep(msToWait); //Sleep for ~3 minutes

//Save in batches
var batchSize = 250;
var batch = [];
var i = 0;
for (var prop in maps) {
  batch.push(maps[prop]);
  i++;

  //When the batch reaches full size, save it
  if (i % batchSize == 0 || i == len) {
    Utilities.sleep(1000);
    var mutations = db.saveBatch(batch, false);
    if (!db.allOk(mutations)) {
      return false;
    }
    batch = [];
  }
}

1 个答案:

答案 0 :(得分:1)

将批次拆分成较小的部分。 不会影响代码,因为批次不是原子的。