Workhorse 핸들러

긴 HTTP 요청은 Rails에서 효율적으로 처리하기 어렵습니다. 이러한 요청은 메모리 효율적이지 않을 수 있으며(파일 업로드), 더 짧은 타임아웃으로 인해 불가능할 수도 있습니다 (예: Puma 서버의 60초 타임아웃). Workhorse는 대량의 긴 HTTP 요청을 효율적으로 처리할 수 있습니다. Workhorse는 모든 HTTP 요청을 가로채거나 추가 로직을 수행하여 변경 없이 전파하는 프록시로 작동합니다.

Injectors

%%{init: { "fontFamily": "GitLab Sans" }}%% sequenceDiagram participant Client participant Workhorse participant Rails Client->>+Workhorse: 요청 Workhorse->>+Rails: 요청 그대로 전파 Rails-->>-Workhorse: 요청 진행 방법에 대한 지시를 포함한 특수 헤더로 응답 Workhorse-->>Client: 응답

예: Git 블롭 보내기

%%{init: { "fontFamily": "GitLab Sans" }}%% 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가 헤더를 처리하는 방법

예: 파일 보내기

%%{init: { "fontFamily": "GitLab Sans" }}%% 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: 데이터 스트리밍

사전 승인된 요청

%%{init: { "fontFamily": "GitLab Sans" }}%% 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 Over HTTP(S)를 가속화하여 Git HTTP 프로토콜 요청을 처리합니다. 예를 들어, Git push/pull은 대량의 데이터를 제공해야 할 수 있습니다. 이를 GitLab Rails를 통해 전송하지 않도록 하기 위해, Workhorse는 GitLab Rails에 대한 권한 확인만 수행하고, 그 후에 Gitaly gRPC 요청을 직접 수행하여 데이터를 Gitaly에서 Git 클라이언트로 스트리밍합니다.

Git pull

%%{init: { "fontFamily": "GitLab Sans" }}%% 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

%%{init: { "fontFamily": "GitLab Sans" }}%% 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: 응답 전송