
# Пробуждение по расписанию

Повторяющиеся окна пробуждения для сервера в режиме BLACKHOLE: платформа заранее, с запасом на загрузку, начинает поднимать сервер к заданному по cron-выражению моменту, а саму задачу запускает собственный cron внутри уже поднятой машины — платформа не читает и не выполняет код приложения.

**На вытесняемом тарифе подъём — best-effort, не гарантия.** Сервер такого типа поднимается по мере освобождения ёмкости — через очередь, — поэтому к моменту окна свободного места может не оказаться, и окно может быть пропущено. Ответ создания и обновления окна несёт поле `preemptibleAdvisoryCode: "PREEMPTIBLE_BEST_EFFORT"` именно для этого случая — см. [Создать окно](./wake-schedules/create.md). На невытесняемом тарифе подъём к самому моменту не гарантирован: загрузка машины может затянуться на несколько минут. Задачу, критичную ко времени, пишите так, чтобы после старта сервера она проверяла, не прошло ли время запуска, и выполнялась с опозданием, — или держите сервер в режиме «Всегда онлайн (24/7)».

**Деплой приложения окна и таймер сна не меняет.** Расписание пробуждения и таймер автоматического засыпания хранятся на платформе, а не в коде приложения, поэтому выкладка новой версии их не сбрасывает — окна продолжают действовать без дополнительных действий. Единственное, что деплой берёт из расписания, — часовой пояс окон: у отдельной виртуальной машины он попадает в переменную окружения `TZ`, когда все включённые окна объявлены в одном поясе. Подробности — [Полный деплой приложения](/docs/infra/deploy/deploy).

**Расписание меняет смысл настройки авто-сна «Никогда».** На вытесняемом тарифе можно совместить `sleepAfterMinutes: null` с расписанием: если у включённого и доступного расписания рассчитано следующее пробуждение, сервер после окна засыпает по платформенному таймауту — по умолчанию через 15 минут простоя. На невытесняемом тарифе текущие запросы создания и обновления окна при сохранённом `null` отклоняются. Платформенный таймаут после окна там действует только для уже существующей комбинации настроек. Явное числовое значение `sleepAfterMinutes` имеет приоритет и расписанием не сокращается. Когда действующих окон нет, `null` снова означает отсутствие авто-сна по бездействию. Отказ при `null` на невытесняемом тарифе к приложению в галактике не относится: тариф оно не выбирает, а наследует от галактики. Не относится он и к серверу в [режиме работы](/docs/infra/lifecycle/run-mode) `SCHEDULE`: сон у него объявлен расписанием.

Скоуп: `vibe:infra`

## Операции

- [Создать окно](./wake-schedules/create.md) — `POST /v1/infra/servers/:id/wake-schedules`
- [Список окон](./wake-schedules/list.md) — `GET /v1/infra/servers/:id/wake-schedules`
- [Обновить окно](./wake-schedules/update.md) — `PATCH /v1/infra/servers/:id/wake-schedules/:scheduleId`
- [Удалить окно](./wake-schedules/delete.md) — `DELETE /v1/infra/servers/:id/wake-schedules/:scheduleId`

## Сценарии

**Ночной отчёт по будням:**

1. [`POST /wake-schedules`](./wake-schedules/create.md) с `cronExpr: "0 9 * * 1-5"`, `timezone: "Europe/Moscow"`.
2. Ответ несёт `tzWarningCode: "SINGLE_ZONE"` — часовой пояс однозначен, и при следующем деплое отдельной виртуальной машины платформа сама передаст его в переменную окружения `TZ`.
3. Cron внутри сервера запускает задачу в 9:00 по московскому времени. Платформа начинает подъём заранее, с запасом на загрузку машины, но подъём к этому моменту не гарантирован ни на одном тарифе: загрузка машины может затянуться на несколько минут. Задачу, которая не должна пропускать запуск, пишите так, чтобы после старта сервера она проверяла, не прошло ли время запуска, и выполнялась с опозданием. На вытесняемом тарифе (ответ несёт `preemptibleAdvisoryCode: "PREEMPTIBLE_BEST_EFFORT"`) сервер поднимается по мере освобождения ёмкости, и при её нехватке окно может быть пропущено целиком.

**Несколько окон в разных часовых поясах:**

1. Создать окна с разными значениями `timezone` для одного сервера.
2. Ответ каждой мутации несёт `tzWarningCode: "MULTI_ZONE"` — платформа не проставляет `TZ` автоматически, когда окна расходятся по поясам. Пишите обработку времени в приложении в UTC.

**Galaxy-приложение — увеличенный запас на подъём:**

1. Для сервера `kind: "GALAXY_APP"` платформа сама закладывает увеличенный запас на подъём хоста, туннеля и контейнера. Своё значение `lead` нужно, только если приложению на загрузку требуется ещё больше времени: значение меньше платформенного запаса поднимается до него.
2. Сам хост галактики (`kind: "GALAXY"`) окна не принимает — расписание объявляется на конкретном приложении, платформа при необходимости поднимает и хост.

## Смотрите также

- [Инфраструктура](/docs/infra)
- [Что приходит в приложение](/docs/infra/app-runtime)
- [Жизненный цикл](/docs/infra/lifecycle)
- [Журнал изменений](/docs/changelog)
