Help us learn about your current experience with the documentation. Take the survey.

Workhorse 处理程序

在 Rails 中高效处理长时间运行的 HTTP 请求很困难。 这些请求要么内存效率低下(文件上传),要么由于超时时间较短而根本无法处理 (例如,Puma 服务器的超时时间为 60 秒)。 Workhorse 可以高效处理大量长时间运行的 HTTP 请求。 Workhorse 充当代理,拦截所有 HTTP 请求,要么直接转发而不做修改, 要么通过执行额外的逻辑自行处理。

注入器

%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
    participant Client
    participant Workhorse
    participant Rails

    Client->>+Workhorse: Request
    Workhorse->>+Rails: Propagate the request as-is
    Rails-->>-Workhorse: Respond with a special header that contains instructions for proceeding with the request
    Workhorse-->>-Client: Response

示例:发送 Git blob

%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
    participant Client
    participant Workhorse
    participant Rails
    participant Gitaly

    Client->>+Workhorse: HTTP Request for a blob
    Workhorse->>+Rails: Propagate the request as-is
    Rails-->>-Workhorse: Respond with a git-blob:{encoded_data} header
    Workhorse->>+Gitaly: BlobService.GetBlob gRPC request
    Gitaly-->>-Workhorse: BlobService.GetBlob gRPC request
    Workhorse-->>-Client: Stream the data

GitLab Rails 如何处理请求

Workhorse 如何处理头部

示例:发送文件

%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
    participant Client
    participant Workhorse
    participant Rails
    participant Object Storage

    Client->>+Workhorse: HTTP Request for a file
    Workhorse->>+Rails: Propagate the request as-is
    Rails-->>-Workhorse: Respond with a send-url:{encoded_data} header
    Workhorse->>+Object Storage: Request for a file
    Object Storage-->>-Workhorse: Stream the data
    Workhorse-->>-Client: Stream the data

预授权请求

%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
    participant Client
    participant Workhorse
    participant Rails
    participant Object Storage

    Client->>+Workhorse: PUT /artifacts/uploads
    Note right of Rails: Append `/authorize` to the original URL and call Rails for an Auth check
    Workhorse->>+Rails: GET /artifacts/uploads/authorize
    Rails-->>-Workhorse: Authorized successfully

    Client->>+Workhorse: Stream the file content
    Workhorse->>+Object Storage: Upload the file
    Object Storage-->>-Workhorse: Success

    Workhorse->>+Rails: Finalize the request
    Note right of Rails: Workhorse calls the original URL to create a database record
    Rails-->>-Workhorse: Finalized successfully
    Workhorse-->>-Client: Uploaded successfully

Git over HTTP(S)

Workhorse 通过处理 Git HTTP protocol 请求来加速 Git over HTTP(S)。例如,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: Access check/Log activity
Rails-->>Workhorse: 200 OK, Gitlab::Workhorse.git_http_ok
Workhorse->>+Gitaly: SmartHTTPService.InfoRefsUploadPack gRPC request
Gitaly -->>-Workhorse: SmartHTTPService.InfoRefsUploadPack gRPC response
Workhorse-->>-Git on client: send info-refs response
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: Access check/Update statistics
Rails-->>Workhorse: 200 OK, Gitlab::Workhorse.git_http_ok
Workhorse->>+Gitaly: SmartHTTPService.PostUploadPackWithSidechannel gRPC request
Gitaly -->>-Workhorse: SmartHTTPService.PostUploadPackWithSidechannel gRPC response
Workhorse-->>-Git on client: send response

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: Access check/Log activity
Rails-->>Workhorse: 200 OK, Gitlab::Workhorse.git_http_ok
Workhorse->>+Gitaly: SmartHTTPService.InfoRefsReceivePack gRPC request
Gitaly -->>-Workhorse: SmartHTTPService.InfoRefsReceivePack gRPC response
Workhorse-->>-Git on client: send info-refs response
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: Access check/Update statistics
Rails-->>Workhorse: 200 OK, Gitlab::Workhorse.git_http_ok
Workhorse->>+Gitaly: SmartHTTPService.PostReceivePackWithSidechannel gRPC request
Gitaly -->>-Workhorse: SmartHTTPService.PostReceivePackWithSidechannel gRPC response
Workhorse-->>-Git on client: send response