Как мы достигли предела возможностей Google Docs

Простым смертным иногда кажется, что компании вроде Google, Apple и Amazon — бесконечно сильные исполины. Они ежедневно таскают на своих плечах все свои сервисы, доступные практически каждому человеку на планете, а каждый пользователь, в свою очередь, имеет безграничный доступ к вычислительным ресурсам этих компаний.

Как мы достигли предела возможностей Google Docs

Отчасти это так. Тот же Google в секунду обрабатывает количество запросов, которое, кажется, у нормального человека в голове уложиться не может. И такой сервис у него (и не только у него) — не один.

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

Мы в «Собаке Павловой» начали строить дизайн-задачник на базе Google Spreadsheet. Мы смогли реализовать на них все, что хотели, оставаясь в парадигме No-code. Если не слышали — это когда продукт строится без кода и толп программистов, на специальных сервисах. Небольшие скрипты, написанные кодом, не в счет.

Всеядность и стабильность работы Таблиц нас настолько впечатлили, что особых проблем с масштабируемостью мы не ожидали. Но уже при первом массовом запуске студентов на обучение поняли, что зря. У всех иногда лапки, и у таблиц Google тоже.

Не IMPORTRANGEм единым

Часть конструкций в нашем задачнике живет благодаря возможности передавать данные из определенных ячеек и диапазонов из одной таблицы в другую — с помощью формулы IMPORTRANGE. Так мы раздаем содержимое задач в таблицы студентов, немного усложняем жизнь последователям Робин Гуда и собираем данные для статистики.

Когда нагрузка небольшая, задачники работают отлично: данные подтягиваются достаточно быстро, ничего не сбоит и вообще все максимально красиво. Но как только нагрузка увеличивается — начинается ой.

#REF!

Пока не будем вдаваться в подкапотные тонкости ошибки, расскажем о них позже. Но результат у нее очень интересный — если IMPORTRANGE не смог получить содержимое ячеек, на которые ссылается, то он ничего не вернет. Вообще. И руками повторно запустить отвалившуюся формулу не получится, вместо значения будет гордо красоваться пустая ячейка.

Вот такая
Вот такая

Чаще всего эти ошибки возникают точечно, и почти всегда помогает еще раз загрузить таблицу — данные подтянутся. Но иногда вылезают совсем интересные баги. Например, в формуле, которая ссылается на упавшую ячейку, появлялся #REF ! (как при удалении ячейки), убивая содержимое этой формулы. То есть вместо формулы появляется постоянное (текстовое) значение, которое нужно убирать вручную.

Возможные решения

  1. Оберните формулу в IFERROR(). Тогда при появлении ошибки Google попробует выполнить операцию повторно. Некоторые советуют провернуть эту операцию несколько раз.

  2. Ошибка напрямую зависит от размера таблиц и диапазона, который импортируется. Попробуйте удалить лишние строки и лишнее условное форматирование или уменьшить размер диапазона.

300 спартанцев

Опытным путем мы выяснили, что проблемы начинаются, когда в одной таблице появляется больше 300 формул с IMPORTRANGE на разные файлы. Есть подозрение, что проблема — в большом количестве обращений к таблицам из одного места. Похожих проблем, когда таблица обращается к меньшему количеству файлов, но несколько раз, мы не нашли. Но возможно, там тоже есть что-то подобное. Если ссылаться на один файл из разных мест — такая ошибка не появляется.

AppScripts

Часть автоматизации задачника выполняется на базе Google AppScripts — облачной песочницы с JS-based языком. Она позволяет работать с таблицами (и другими продуктами Google) вне их графической оболочки и автоматизировать рутинные процессы.

Хотя сервис очень мощный, на технические ограничения мы наткнулись практически сразу, как начали его использовать. Часть из них явно ввели намеренно, но некоторые — похожи на недоработки, и хочется надеяться, что когда-нибудь их поправят.

Тайминг

Скрипт выполняется только 30 минут. Иногда чуть больше, но мы списали это на погрешность времени запроса к файлам. Когда скрипт отработал полчаса — он просто останавливается, а в консоли появляется соответствующая ошибка. Если скрипт перезапустить, он начнет работу с начала. Возможности перезапустить скрипт и продолжить выполнение мы не нашли.

Это нужно, очевидно, чтоб убивать случайно запущенные бесконечные скрипты. Ну и чтобы не было соблазна писать на скриптах огромные программы. Так или иначе, ограничение приходится учитывать.

Интересно то, что и из этого правила есть исключение. Однажды скрипт проработал почти 44 минуты и даже успешно выполнился. Но он такой был один, поэтому мы решили, что ему просто повезло

При этом похоже, что он запустился дважды в одно выполнение
При этом похоже, что он запустился дважды в одно выполнение

Вариант решения

Если очень сильно заморочиться, то можно сохранять в служебной таблице текущее состояние скрипта. При запуске проверять, что он уже сделал, и запускать с нужного места.

Неравномерность выполнения

Чтобы уложиться в ограничение по времени выполнения, приходится делать пробные запуски и оценивать время выполнения скрипта. Сложность в том, что запросы к файлам и дальнейшая работа с ними занимают разное время. Один запрос может выполняться с вилкой в 1 секунду. Иногда (видимо, при большой нагрузке на сервер) бывает и больше, но это исключение. Получается, что 500 запросов к документам могут выполняться как 250 секунд, так и 750.

<p>Между выполнениями интервал 1 час</p>

Между выполнениями интервал 1 час

Вдобавок скорость загрузки данных из документа зависит от его объема. В случае с таблицами — размер таблиц, объем данных и дополнительные данные таблиц (правила, скрипты и т.д.). В задачнике студенческие таблицы одинаковые по размеру, а объем данных меняется в рамках погрешности. Но это стоит учитывать, если вы работаете с разноплановыми документами.

Возможные решения

  1. Старайтесь держать документы в актуальности и порядке. Удаляйте лишние данные и пустые строки.

  2. Сделайте 3-5 тестовых прогона скрипта, добавьте к среднему времени выполнения 30%. Этого должно хватить на случай сбоев на стороне Google.

  3. Если скрипт выполняется дольше 30 минут — попробуйте разделить данные на несколько скриптов или используйте промежуточные таблицы.
  4. Проведите ревью кода и постарайтесь уменьшить число повторяющихся запросов к документам.

Отваливается и тут

Выше мы уже рассказывали при ошибке importrange вместо формулы подставляется #REF !. Немного покопались в мануалах и нашли там возможность на AppScripts написать собственную формулу. Заподозрили, что формулы встроенные тоже работают на скриптах. Но эта мысль скорее для фанатов теории заговора.

Так или иначе, иногда скрипт просто отваливается посреди выполнения. Объясняет свое поведение двумя причинами:

  • «Сервису "Таблицы" недоступен документ “ID таблицы”»

  • «Слишком много одновременных вызовов: Таблицы»
Так
Так
Или так
Или так

Обе ошибки появляются настолько рандомно, что найти их причину невозможно. У нас параллельно запущено пять скриптов для разных потоков студентов, и, возможно, иногда это вызывает вторую ошибку. Но в 95% выполнений все проходит отлично при тех же вводных. Первая ошибка — вообще загадка.

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

  • мы рисковали бы создать бесконечный цикл;

  • у нас все еще ограничение по времени выполнения скрипта, в которое мы укладываемся впритык.

Варианты решения

Никаких. Просто жаловаться на Google в профильных ветках и учитывать эти особенности при разработке нагруженных скриптов.

Тонкая работа

Самый редкий кейс — в AppScripts при работе с таблицами нельзя удалить правило условного форматирования. Можно создать, изменить, применить к диапазону. Удалить — нет. А так как у нас на форматировании построена немалая часть задачника, получилось особенно больно.

Похожая история и с правилами проверки данных, но там еще хуже — их нельзя даже редактировать. Только танец с бубном в виде создания изменяемой копии правила.

Вариант решения

Удалите из правила все диапазоны, для которых оно применяется. Плюсы: правило больше не будет применяться. Минусы: вы намусорили в таблице.

Вместо титров

No-code в нашем случае отлично показал себя. Он кратно удешевляет создание MVP и первых версий продуктов и позволяет любому члену команды создавать новые фичи. Но это не волшебная таблетка, которая все сделает за вас, и технические проблемы все равно придется решать вручную.

Уверены, ограничений и недоработок у Google кратно больше. Уверены, что часть наших проблем уже кто-то решил. Уверены, что с оставшимися вполне можно жить.

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

1717
16 комментариев

мыши плакали, кололись, но продолжали грызть кактус

7

чем больше будут накатывать на этот нон-код, создавая вавилонские башни, тем сильнее будет обратным откат:)

6

Ору с комента ))))

Комментарий недоступен

Авторы решили использовать неподходящий инструмент, стоящий небольшие деньги, для большого заработка

Причём ограничения на используемые функции явно описаны в документации

Конец немного предсказуем. Причём есть попытки подать конец как несовершенство инструмента, а не странную логику авторов

9

Комментарий недоступен

3

Делал в sheets таблицу для личного пользования, так вот там было около 50 запросов "importxml" - пользоваться было нереально, эти запросы тупили при каждом входе.

1