Skip to content

OPS-2: Distributed lock для фоновых джоб (ShedLock) #95

Description

@ii-reviewer

Цель: при горизонтальном масштабировании фоновые задачи (снятие протухших резервов, периодический пересчёт low-stock) должны выполняться ровно на одном инстансе, а не на каждом.
Зависимость: — (эффективен при >1 реплики, см. OPS-6).

Что сделать

  • Подключить ShedLock (shedlock-spring + провайдер: JDBC или Redis), включить @EnableSchedulerLock(defaultLockAtMostFor = "PT5M").
  • Создать минимум одну реальную @Scheduled джобу (например, пересчёт списка low-stock или снятие протухших резервов) и навесить:
    @Scheduled(cron = "0 */5 * * * *")
    @SchedulerLock(name = "recalcLowStock", lockAtLeastFor = "PT1M", lockAtMostFor = "PT4M")
    void recalc() { ... }
  • Для JDBC-провайдера — миграция таблицы shedlock(name, lock_until, locked_at, locked_by).
  • Стретч: продумать идемпотентность джобы (повторный прогон не ломает данные) и leader-only выполнение. НЕ давать готовую джобу целиком — только каркас и места блокировки.

Acceptance criteria

  • При двух инстансах джоба за тик отрабатывает только на одном (видно по логам/locked_by).
  • Запись блокировки появляется в таблице/Redis с корректным lock_until.
  • Падение инстанса-держателя не блокирует джобу дольше lockAtMostFor.
  • Повторный запуск джобы не дублирует эффект (идемпотентность).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions