Запускать несколько скриптов по порядку - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть 5 версий нижеприведенного скрипта в моем проекте, которые извлекаются из Google Analytics (каждая из которых тянет группу страниц). В настоящее время я должен запускать каждый из них вручную и хотел бы, чтобы они запускались по порядку. Я настроил его таким образом, чтобы обойти 6-минутный лимит времени.

Есть ли способ запустить первый, и после завершения есть триггер со сценарием, который указывает на следующий сценарий для автоматического запуска?

function main3() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  for (var i = 1; i < 32; i++) {      
    var istring = i.toString();
    var sheetName = istring;
    var istring1 = "a" + ((i+1).toString());
    var sheet = spreadsheet.getSheetByName(sheetName);
    //sheet.clearContents();  
  }
  for (var j = 27; j < 40; j++) {
    var jstring = j.toString();
    var jstring1 = "d" + ((j+1).toString());
    var ss = SpreadsheetApp.openById("..."); 
    var sheet2 = ss.getSheetByName('GA ID & SS KEY');
    var sheet1 = ss.getSheetByName('Dates');
    var allRows = sheet1.getRange(2, 1, 31).getValues();  
    var timeZone = ss.getSpreadsheetTimeZone();
    var tableId = sheet2.getRange(jstring1).getValue();
    //var lastRow = 2;           
    for (var i = 1; i < 32; i++) {    
      var istring = i.toString();
      var sheetName = istring;
      var istring1 = "a" + ((i+1).toString());
      var sheet = spreadsheet.getSheetByName(sheetName);
      var startDate1 = Utilities.formatDate(allRows[i-1][0], timeZone, "YYYY-MM-dd");
      var endDate1 =  startDate1;
      var lastRow = sheet.getLastRow();
      if (lastRow == 0) {
        lastRow = 2;
      } else {
        lastRow = lastRow + 1;
      }
      var metrics = ['ga:pageviews,ga:uniquePageviews,ga:users,ga:newUsers,ga:entrances'];
      var options = {
        'dimensions': 'ga:hostname,ga:pagePath,ga:dimension3,ga:date',
        'filters': 'ga:dimension3==commerce',
        'sort': '-ga:pageviews',
        //'segment': '',
        'samplingLevel': 'HIGHER_PRECISION',
        'max-results': '10000'
      }      
      var report = gaGet(tableId, startDate1, endDate1, metrics, options);
      if (report.rows !== undefined) {    
        Logger.log(report.rows.length);
        var data = report.rows;
        var writeRange = sheet.getRange(lastRow, 1, data.length, data[0].length) 
        writeRange.setValues(data);
      }
    }
  }
}

function gaGet3(tableId, startDate1, endDate1, metrics, options) {
  // Apply standard options
  options = options || {};
  options['max-results'] = options['max-results'] || '10000';  
  for (var i = 0; i < 5; i++) {
    try {
      return Analytics.Data.Ga.get(tableId, startDate1, endDate1, metrics, options); 
    } catch (err) {      
      if (err.message.indexOf('a server error occurred') > -1) {
        Logger.log('Backend Error');        
        Utilities.sleep(2 * 60 * 1000);
      } else if (err.message.indexOf('User Rate') > -1) {
        Logger.log('Rate Limit Error');        
        Utilities.sleep(1000 * Math.pow((i + 1), 2));
      } else if (err.message.indexOf('too many concurrent connections') > -1) {
        Logger.log('Concurrent Connections Error');        
        Utilities.sleep(1000 * Math.pow((i + 1), 2));
      } else {
        Logger.log(err);
        throw err;
      }
    }
  }
  throw 'Error. Max retries reached';
}

Ответы [ 2 ]

0 голосов
/ 12 ноября 2019

Я думаю, что лучший способ обойти 6-минутный лимит времени - это создать синхронизирующий триггер в конце каждой функции, который вызывает следующую функцию через определенное время.

Метод дляуведомление здесь после (durationMilliseconds) . Благодаря этому вы можете запускать любую функцию, указанную вами, по прошествии указанного вами количества миллисекунд.

Например, если у нас было три функции, выполнение которых занимает более 6 минут, если вы запускаете их одну за другой,Вы можете сделать что-нибудь в следующих строках:

function myFunction1() {
  // Whatever myFunction1 does
  ScriptApp.newTrigger("myFunction2")
  .timeBased()
  .after(1000) // This fires the second function 1 second after the first one ends. Change this time according to your preferences
  .create();
}

function myFunction2() {
  // Whatever myFunction2 does
  ScriptApp.newTrigger("myFunction3")
  .timeBased()
  .after(1000) // This fires the third function 1 second after the second one ends. Change this time according to your preferences
  .create();
}

function myFunction3() {
  // Whatever myFunction3 does
}

Другой способ - использовать API скриптов приложений до запускать различные функции удаленно, но это сложнееОбходной путь.

Использование библиотек не вариант, так как время выполнения, соответствующее библиотекам, считается частью исходного сценария, из которого эти библиотеки вызываются.

ИКонечно, прежде чем использовать триггеры, первое, что нужно сделать, - это повысить эффективность вашего кода, чтобы его выполнение заняло менее 6 минут.

Надеюсь, это поможет.

0 голосов
/ 09 ноября 2019

Я просмотрел ваш код и думаю, вы могли бы сильно упростить его. Например, первый цикл в коде ничего не делает, поэтому вы можете удалить это. Кроме того, код получит пользу от более опытного программиста. Вероятно, это может быть треть от размера. Однако реальная проблема заключается в том, что похоже на то, что вы вызываете отчет из Analytics.data.ga, и вы, вероятно, не можете его контролировать, и, судя по виду вашей второй функции, у вас возникли проблемы с его быстрым вызовом. Поэтому я был бы склонен запускать его из пятиминутного таймера и сохранять индекс, который работает с 1 по 31, в PropertiesService делать это поздно ночью, а ваши отчеты ждут вас утром. Если эти отчеты важны для вас, я бы порекомендовал вам нанять кого-нибудь, чтобы помочь вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...