Перейти к основному содержанию

Обзор

API Twenty принимает 500 запросов в минуту на регистрацию приложения для запросов, которые приложение выполняет от своего имени: запусков без участия человека (cron, вебхуки, хуки установки) и клиентов, созданных с помощью runAs: 'application'. Бюджет является общим для всех рабочих пространств, в которых установлено приложение, а запросы сверх него отклоняются с кодом 429. Запросы, выполненные от имени пользователя, запустившего запуск, вместо этого учитываются в лимитах этого пользователя. Описанные ниже практики позволяют приложению оставаться в рамках этого бюджета по мере роста числа его установок и в пределах лимитов вызываемых им сервисов.
  • Распределяйте cron-задачи обхода с произвольной задержкой. Триггер cron запускается в каждой рабочей области в одну и ту же минуту, поэтому все установки одновременно расходуют общий бюджет. Пусть обработчик cron только ставит задачу в очередь с произвольным delayMs в большом окне, например в один час. Постановка задач в очередь также ограничена 2 000 в минуту на регистрацию приложения, а тик cron сверх этого лимита пропускается в остальных рабочих областях, поэтому делайте обход идемпотентным и позволяйте следующему тику наверстать упущенное.
src/logic-functions/enqueue-nightly-sweep.ts
При произвольной задержке в пределах одного часа те же запуски распределяются:
  • Пакетируйте триггеры событий базы данных. Массовая запись, например синхронизация почтового ящика, создаёт одно событие на запись — тысячи за считанные секунды, а один запуск на событие означает один запрос на запись. Установите batchMode: true, объявите updatedFields и сократите пакет до уникальных записей перед вызовом API. См. Пакетная обработка событий базы данных.
  • Выполняйте один запрос на пакет, а не на запись. Лимит учитывает запросы, а не записи: один createMany с upsert: true, содержащий 200 записей, — это один запрос, а 200 отдельных обновлений — это 200 запросов. Читайте с фильтрами in, а записывайте с помощью createMany или updateMany.
  • Объединяйте всплески в одну отложенную задачу. Когда события выявляют объём работы, превышающий само событие, постановка задачи в очередь для каждого события умножает её на размер всплеска. Поставьте в очередь одну задачу с delayMs и детерминированным jobId, включающим временное окно; очередь игнорирует идентификатор, который уже содержит. См. Выбор собственного идентификатора задачи.
  • Распределяйте fan-out с помощью delayMs. Задачи, поставленные в очередь без задержки, становятся доступными одновременно и расходуют бюджет в одну и ту же минуту. Сгруппируйте их в слоты на минуту и отложите следующую страницу на количество использованных слотов. См. Фоновые задачи.
  • Повторяйте запрос с 429 с отсрочкой или повторно ставьте его в очередь с задержкой. Клиентский SDK выдаёт исключение при любом ответе не из диапазона 2xx, а запуск, ожидающий внутри, расходует собственный тайм-аут. Повторяйте попытки с экспоненциальной отсрочкой и ограничением числа попыток либо передавайте работу обратно в очередь с задержкой.
  • Кэшируйте неизменяемые данные. Поиск при каждом событии требует запроса для значения, фиксированного во время подключения, например идентификатора или идентификатора команды. Сохраните его в хранилище ключей и значений при регистрации подключения.
  • Пакетируйте запросы к внешним API. У внешнего сервиса есть собственное ограничение частоты запросов, а у логической функции — тайм-аут, поэтому n запросов на запуск умножают оба показателя. Если поставщик предоставляет пакетную конечную точку, отправляйте один запрос для всего пакета вместо одного на запись и разбивайте пакет на части согласно максимальному размеру у поставщика.
  • Сделайте параметры по умолчанию редактируемыми пользователем. Значение, жёстко заданное в логической функции или в Workflows, например порог, размер пакета или параметр по умолчанию, подходит для одной рабочей области и требует нового релиза для каждой другой. Объявите его как переменную приложения со значением по умолчанию и считывайте её во время запуска, чтобы администраторы рабочей области могли настраивать её в настройках приложения. См. Конфигурация приложения.