1. Redis 역할 두 가지

  1. 실행 요청 큐 (exec Q)
  2. 콜백 채널 (job_completed pub/sub)

2. 최종 구조

공통 전제

flowchart LR
subgraph whole arcitecture
    subgraph ClientSide["Client Side"]
            C["Client<br>사용자 / 다른 서비스"]
    end
    subgraph APIServer["API Server (FastAPI)"]
            A["Invoke API<br>POST /functions/{id}/invoke"]
            J["Jobs API<br>GET /jobs/{jobId}"]
            L["Redis Listener<br>(SUBSCRIBE job_completed)"]
            WMap["waiters[jobId] -> Future"]
    end
    subgraph Redis["Redis"]
            Q[("exec_queue<br>List/Stream")]
            CH(("job_completed<br>pub/sub channel"))
    end
    subgraph WorkerSide["Worker"]
            W["Exec Worker<br>consume exec_queue"]
    end
    subgraph Runtime["Function Runtime"]
            R["General Runner<br>(KNative Serving)"]
    end
    subgraph DB
            D[("Jobs DB")]
    end
        C -- sync/async invoke --> A
        C -- GET result --> J
        A -- push job --> Q
        W -- BRPOP / XREAD --> Q
        W -- execute --> R
        R -- result --> W
        W -- update status/result --> D
        W -- publish job_completed --> CH
        L -- receive events --> CH
        L -- resolve Future --> WMap
        J -- read job --> D
        A -- create job (PENDING) --> D
        A -- wait via Future --> WMap
end

Async 호출 플로우

  1. POST /functions/{id}/invoke
  2. Worker
  3. 클라이언트
sequenceDiagram
    autonumber
    participant C as Client
    participant A as API Server<br/>(FastAPI)
    participant D as Jobs DB
    participant Q as Redis exec_queue
    participant W as Exec Worker
    participant R as General Runner<br/>(KNative)
    participant CH as Redis job_completed

    C->>A: POST /functions/{id}/invoke
    A->>D: INSERT Job(PENDING, mode=async)
    A->>Q: LPUSH exec_queue {jobId, functionId, payload}
    A-->>C: 202 Accepted<br/>{ jobId }

    loop Worker consumes exec_queue
        W->>Q: BRPOP exec_queue
        Q-->>W: {jobId, functionId, payload}
        W->>D: UPDATE Job RUNNING
        W->>R: HTTP POST /run {payload}
        R-->>W: {result or error}
        alt success
            W->>D: UPDATE Job SUCCESS + result
            W->>CH: PUBLISH job_completed {jobId, status: SUCCESS}
        else failed
            W->>D: UPDATE Job FAILED + error
            W->>CH: PUBLISH job_completed {jobId, status: FAILED}
        end
    end

    C->>A: GET /jobs/{jobId}
    A->>D: SELECT Job
    D-->>A: {status, result, error}
    A-->>C: 200 OK {status, result, error}


Sync 호출 플로우 (여기서 Redis pub/sub이 중요)

  1. POST /functions/{id}/invoke
  2. Worker