Workhorse 핸들러

롱 HTTP 요청은 Rails에서 효율적으로 처리하기 어렵습니다. 파일 업로드와 같은 경우 메모리를 비효율적으로 사용하거나, 타임아웃이 더 짧아져 전혀 처리할 수 없게 됩니다(Puma 서버의 60초 타임아웃과 같은 경우). Workhorse는 대량의 롱 HTTP 요청을 효율적으로 처리할 수 있습니다. Workhorse는 모든 HTTP 요청을 가로채고 변경하지 않고 전파하거나, 추가 로직을 수행하여 직접 처리하는 프록시로 작동합니다.

Injectors

sequenceDiagram participant Client participant Workhorse participant Rails Client->>+Workhorse: 요청 Workhorse->>+Rails: 요청을 그대로 전파 Rails-->>-Workhorse: 요청을 처리하기 위한 특별한 헤더 응답 Workhorse-->>Client: 응답

예시: Git 블롭 전송

sequenceDiagram participant Client participant Workhorse participant Rails participant Gitaly Client->>+Workhorse: 블롭을 위한 HTTP 요청 Workhorse->>+Rails: 요청을 그대로 전파 Rails-->>-Workhorse: git-blob:{인코딩된_데이터} 헤더와 함께 응답 Workhorse->>+Gitaly: BlobService.GetBlob gRPC 요청 Gitaly-->>-Workhorse: BlobService.GetBlob gRPC 응답 Workhorse-->>Client: 데이터 스트리밍

GitLab Rails가 요청을 처리하는 방법

Workhorse가 헤더를 처리하는 방법

예시: 파일 전송

sequenceDiagram participant Client participant Workhorse participant Rails participant Object Storage Client->>+Workhorse: 파일을 위한 HTTP 요청 Workhorse->>+Rails: 요청을 그대로 전파 Rails-->>-Workhorse: send-url:{인코딩된_데이터} 헤더와 함께 응답 Workhorse->>+Object Storage: 파일을 위한 요청 Object Storage-->>-Workhorse: 데이터 스트리밍 Workhorse-->>Client: 데이터 스트리밍

사전 승인된 요청

sequenceDiagram participant Client participant Workhorse participant Rails participant Object Storage Client->>+Workhorse: PUT /artifacts/uploads Note right of Rails: 원래 URL에 `/authorize`를 추가하여 Rails에 인증 확인을 요청 Workhorse->>+Rails: GET /artifacts/uploads/authorize Rails-->>-Workhorse: 성공적으로 승인됨 Client->>+Workhorse: 파일 내용 스트리밍 Workhorse->>+Object Storage: 파일 업로드 Object Storage-->>-Workhorse: 성공 Workhorse->>+Rails: 요청 완료 Note right of Rails: Workhorse가 데이터베이스 레코드를 생성하기 위해 원래 URL을 호출 Rails-->>-Workhorse: 성공적으로 완료됨 Workhorse-->>Client: 성공적으로 업로드됨

HTTP(S)를 통한 Git

Workhorse는 Git HTTP 프로토콜 요청을 처리함으로써 HTTP(S)를 통한 Git을 가속화합니다. 예를 들어, Git push/pull은 대량의 데이터를 제공해야 할 수 있으며, 이를 GitLab Rails을 통해 전송하지 않고, Workhorse는 GitLab Rails에 대한 권한 확인을 수행한 후에 Gitaly gRPC 요청을 직접 수행하고 Gitaly에서 데이터를 Git 클라이언트로 스트리밍합니다.

Git pull

sequenceDiagram participant Git on client participant Workhorse participant Rails participant Gitaly Note left of Git on client: git clone/fetch Git on client->>+Workhorse: GET /foo/bar.git/info/refs/?service=git-upload-pack Workhorse->>+Rails: GET Repositories::GitHttpController#info_refs Note right of Rails: 접근 확인/활동 로그 Rails-->>Workhorse: 200 OK, Gitlab::Workhorse.git_http_ok Workhorse->>+Gitaly: SmartHTTPService.InfoRefsUploadPack gRPC 요청 Gitaly -->>-Workhorse: SmartHTTPService.InfoRefsUploadPack gRPC 응답 Workhorse-->>-Git on client: info-refs 응답 전송 Git on client->>+Workhorse: GET /foo/bar.git/info/refs/?service=git-upload-pack Workhorse->>+Rails: GET Repositories::GitHttpController#git_receive_pack Note right of Rails: 접근 확인/통계 업데이트 Rails-->>Workhorse: 200 OK, Gitlab::Workhorse.git_http_ok Workhorse->>+Gitaly: SmartHTTPService.PostUploadPackWithSidechannel gRPC 요청 Gitaly -->>-Workhorse: SmartHTTPService.PostUploadPackWithSidechannel gRPC 응답 Workhorse-->>-Git on client: 응답 전송

Git push

sequenceDiagram participant Git on client participant Workhorse participant Rails participant Gitaly Note left of Git on client: git push Git on client->>+Workhorse: GET /foo/bar.git/info/refs/?service=git-receive-pack Workhorse->>+Rails: GET Repositories::GitHttpController#info_refs Note right of Rails: 액세스 확인/활동 기록 Rails-->>Workhorse: 200 OK, Gitlab::Workhorse.git_http_ok Workhorse->>+Gitaly: SmartHTTPService.InfoRefsReceivePack gRPC 요청 Gitaly -->>-Workhorse: SmartHTTPService.InfoRefsReceivePack gRPC 응답 Workhorse-->>-Git on client: info-refs 응답 전송 Git on client->>+Workhorse: GET /foo/bar.git/info/refs/?service=git-receive-pack Workhorse->>+Rails: GET Repositories::GitHttpController#git_receive_pack Note right of Rails: 액세스 확인/통계 업데이트 Rails-->>Workhorse: 200 OK, Gitlab::Workhorse.git_http_ok Workhorse->>+Gitaly: SmartHTTPService.PostReceivePackWithSidechannel gRPC 요청 Gitaly -->>-Workhorse: SmartHTTPService.PostReceivePackWithSidechannel gRPC 응답 Workhorse-->>-Git on client: 응답 전송