Sobes.tech
Back to questions
Senior
4

Как реализовать обратную сторону — Inbox паттерн на стороне notification service? Как обеспечить идемпотентность обработки событий?

Companies where asked
ИП Ганус Александр Андреевич

Answer from AI

sobes.tech AI

Inbox паттерн в notification service используется для обеспечения идемпотентной обработки входящих событий. Идея в том, чтобы сохранять уникальные идентификаторы обработанных событий (например, eventId) в специальной таблице (Inbox), чтобы при повторном получении того же события его не обрабатывать повторно.

Реализация:

  1. При получении события проверяем, есть ли eventId в таблице Inbox.
  2. Если нет — обрабатываем событие, сохраняем eventId в Inbox.
  3. Если есть — пропускаем обработку.

Для обеспечения идемпотентности важно, чтобы запись eventId и обработка события были атомарными. В Go с использованием базы данных это можно сделать в рамках транзакции.

Пример на Go (упрощённо):

func ProcessEvent(db *sql.DB, event Event) error {
    tx, err := db.Begin()
    if err != nil {
        return err
    }
    defer tx.Rollback()

    var exists bool
    err = tx.QueryRow("SELECT EXISTS(SELECT 1 FROM inbox WHERE event_id = ?)", event.ID).Scan(&exists)
    if err != nil {
        return err
    }
    if exists {
        // Уже обработано
        return nil
    }

    // Обработка события
    err = handleEvent(tx, event)
    if err != nil {
        return err
    }

    // Запись eventId в Inbox
    _, err = tx.Exec("INSERT INTO inbox(event_id) VALUES(?)", event.ID)
    if err != nil {
        return err
    }

    return tx.Commit()
}

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

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