Skip to content

아키텍처

trigger-dispatcher 개요

trigger-dispatcher는 EventBridge Scheduler → Core API → SQS 파이프라인을 수행하는 단일 Lambda 함수입니다. 트리거 타입별로 서로 다른 SQS 큐에 메시지를 라우팅하여, 각 소비자 서비스가 독립적으로 이벤트를 처리할 수 있게 합니다.

이벤트 처리 흐름

정보

EventBridge Scheduler는 Lambda를 비동기(async) 호출합니다. Lambda 실패 시 최대 2회 자동 재시도됩니다.

입력 이벤트

EventBridge Scheduler가 Lambda에 전달하는 payload:

json
{
  "trigger_eid": "string (EID)",
  "trigger_type": "string (트리거 타입)"
}

트리거 타입 라우팅 테이블

Lambda는 trigger_type에 따라 메시지를 전송할 SQS 큐를 결정합니다.

트리거 타입대상 큐소비자설명
loop.confirmed.day_beforeSQS_ASSISTANT_QUEUE_URLtruloop-assistant확정된 룹 전날 알림
loop.confirmed.morning_ofSQS_ASSISTANT_QUEUE_URLtruloop-assistant확정된 룹 당일 아침 알림

주의

알 수 없는 trigger_type이 들어오면 ValueError를 발생시켜 Lambda를 실패 처리합니다. 새 트리거 타입 추가 시 TRIGGER_TYPE_ROUTES 딕셔너리에 등록이 필요합니다.

Phase 2 계획 (코드 주석 기반)

향후 truloop-core가 직접 처리하는 트리거 타입이 추가될 예정입니다. Core 전용 SQS 큐(SQS_CORE_QUEUE_URL)로 라우팅하는 형태가 될 것입니다.

python
# Phase 2: Core가 처리하는 타입은 Core 큐로
# "loop.status.reminder": os.environ["SQS_CORE_QUEUE_URL"],

Core API 연동

Lambda는 truloop-core의 Internal API를 호출합니다. 인증은 Bearer API Key 방식입니다.

호출 엔드포인트

MethodPath설명
GET/triggers/{trigger_eid}/targets트리거 대상 사용자 그룹 조회 (페이지네이션)
POST/triggers/{trigger_eid}/complete트리거 디스패치 완료 통보

페이지네이션

대상 조회 API는 커서 기반 페이지네이션을 사용합니다.

파라미터타입기본값설명
sizeinteger50페이지당 그룹 수
cursorstring-다음 페이지 커서

응답 구조:

json
{
  "target_groups": [
    {
      "context": { },
      "user_eids": ["user_eid_1", "user_eid_2"]
    }
  ],
  "has_next": true,
  "next_cursor": "string"
}

SQS 메시지 포맷

target_group이 하나의 SQS 메시지로 변환됩니다.

json
{
  "event_id": "{trigger_eid}:{cursor}:{group_index}",
  "trigger_eid": "string",
  "trigger_type": "loop.confirmed.day_before",
  "context": { },
  "target_user_eids": ["user_eid_1", "user_eid_2"]
}

event_id{trigger_eid}:{cursor}:{group_index} 형태로 구성되어 메시지를 고유하게 식별합니다.

에러 처리

상황동작결과
Core API 404 (트리거 삭제됨)로그 후 정상 반환{status: "skipped", reason: "deleted"}
Core API 기타 HTTP 에러예외 전파Lambda 실패 → 비동기 재시도 (최대 2회)
네트워크/타임아웃 에러예외 전파Lambda 실패 → 비동기 재시도 (최대 2회)
알 수 없는 trigger_typeValueError 발생Lambda 실패 → 비동기 재시도 (최대 2회)

정보

Core API 호출 타임아웃은 30초입니다. Lambda 전체 타임아웃은 **300초(5분)**로, 대량 페이지네이션에도 충분한 여유가 있습니다.

핸들러 코드

python
def handler(event, context):
    """EventBridge Schedule이 직접 호출. event = TriggerScheduleInput."""
    trigger_eid = event["trigger_eid"]
    trigger_type = event["trigger_type"]

    queue_url = TRIGGER_TYPE_ROUTES.get(trigger_type)
    if not queue_url:
        raise ValueError(f"Unknown trigger type: {trigger_type}")

    cursor = None
    group_index = 0

    try:
        while True:
            params = {"size": "50"}
            if cursor:
                params["cursor"] = cursor

            result = _core_get(f"/triggers/{trigger_eid}/targets", params)

            for group in result["target_groups"]:
                event_id = f"{trigger_eid}:{cursor or 'start'}:{group_index}"
                sqs.send_message(
                    QueueUrl=queue_url,
                    MessageBody=json.dumps({
                        "event_id": event_id,
                        "trigger_eid": trigger_eid,
                        "trigger_type": trigger_type,
                        "context": group["context"],
                        "target_user_eids": group["user_eids"],
                    }),
                )
                group_index += 1

            if not result["has_next"]:
                break
            cursor = result["next_cursor"]

        _core_post(f"/triggers/{trigger_eid}/complete")
    except HTTPError as e:
        if e.code == 404:
            return {"status": "skipped", "reason": "deleted"}
        raise

    return {"status": "dispatched", "messages_sent": group_index}

변경 이력

날짜내용
2026-03-11최초 작성 — trigger-dispatcher 아키텍처 문서