В некоторых сценариях вы можете захотеть не жестко кодировать тайм-ауты непосредственно на уровне HTTP-клиента внутри вашей функции AWS Lambda, а использовать общий контекст Go для всей функции и передавать его каждой операции, эффективно используя отмену контекста Go. Он поддерживается многими пакетами, включая стандартный HTTP-клиент Go или AWS SDK for Go.

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

Перейти к контексту. Отмена контекста

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

Результат вышеупомянутой программы будет следующим:

Get http://www.mocky.io/v2/5e369e393200006400ae3cb2?mocky-delay=5s: context deadline exceeded

Как использовать это в AWS Lambda?

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

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

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

Когда вы можете рассмотреть этот подход?

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

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