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:{encoded_data} 헤더를 포함한 응답
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:{encoded_data} 헤더를 포함한 응답
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 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
participant Workhorse
participant Rails
participant Gitaly
클라이언트의 Git의 왼쪽 Note: git clone/fetch
클라이언트의 Git->>+Workhorse: GET /foo/bar.git/info/refs/?service=git-upload-pack
Workhorse->>+Rails: GET Repositories::GitHttpController#info_refs
Rails의 오른쪽 Note: 접근 확인/활동 로깅
Rails-->>Workhorse: 200 OK, Gitlab::Workhorse.git_http_ok
Workhorse->>+Gitaly: SmartHTTPService.InfoRefsUploadPack gRPC 요청
Gitaly -->>-Workhorse: SmartHTTPService.InfoRefsUploadPack gRPC 응답
Workhorse-->>-클라이언트의 Git: info-refs 응답 전송
클라이언트의 Git->>+Workhorse: GET /foo/bar.git/info/refs/?service=git-upload-pack
Workhorse->>+Rails: GET Repositories::GitHttpController#git_receive_pack
Rails의 오른쪽 Note: 접근 확인/통계 업데이트
Rails-->>Workhorse: 200 OK, Gitlab::Workhorse.git_http_ok
Workhorse->>+Gitaly: SmartHTTPService.PostUploadPackWithSidechannel gRPC 요청
Gitaly -->>-Workhorse: SmartHTTPService.PostUploadPackWithSidechannel gRPC 응답
Workhorse-->>-클라이언트의 Git: 응답 전송
Git push
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
participant 클라이언트의 Git
participant Workhorse
participant Rails
participant Gitaly
클라이언트의 Git의 왼쪽 Note: git push
클라이언트의 Git->>+Workhorse: GET /foo/bar.git/info/refs/?service=git-receive-pack
Workhorse->>+Rails: GET Repositories::GitHttpController#info_refs
Rails의 오른쪽 Note: 접근 확인/활동 로깅
Rails-->>Workhorse: 200 OK, Gitlab::Workhorse.git_http_ok
Workhorse->>+Gitaly: SmartHTTPService.InfoRefsReceivePack gRPC 요청
Gitaly -->>-Workhorse: SmartHTTPService.InfoRefsReceivePack gRPC 응답
Workhorse-->>-클라이언트의 Git: info-refs 응답 전송
클라이언트의 Git->>+Workhorse: GET /foo/bar.git/info/refs/?service=git-receive-pack
Workhorse->>+Rails: GET Repositories::GitHttpController#git_receive_pack
Rails의 오른쪽 Note: 접근 확인/통계 업데이트
Rails-->>Workhorse: 200 OK, Gitlab::Workhorse.git_http_ok
Workhorse->>+Gitaly: SmartHTTPService.PostReceivePackWithSidechannel gRPC 요청
Gitaly -->>-Workhorse: SmartHTTPService.PostReceivePackWithSidechannel gRPC 응답
Workhorse-->>-클라이언트의 Git: 응답 전송