Skip to content

[7/N] feat(gateway): add request history lookups#346

Open
albertywu wants to merge 1 commit into
wua/request-list-apifrom
wua/request-history-api
Open

[7/N] feat(gateway): add request history lookups#346
albertywu wants to merge 1 commit into
wua/request-list-apifrom
wua/request-history-api

Conversation

@albertywu

@albertywu albertywu commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Summary

feat(gateway): add request history lookups

Test Plan

make fmt && make build && make test && make e2e-test

Local full-stack gRPC verification

  • Date: 2026-07-13
  • Commit: 245a0cbb94623f7a57e44d295f52e53657d3b13d
  • Started the clean local Gateway, Orchestrator, Runway, and MySQL stack with make local-submitqueue-start.
  • Called the real Gateway server with grpcurl using api/submitqueue/gateway/proto/gateway.proto.
  • Submitted the same pinned change twice. Request 1 landed; request 2 reached error as a duplicate of the in-flight request. This exercises successful and error projections.
Endpoint Verified behavior
StatusByID Returned the landed summary and an error summary containing lastError.
StatusByChangeID Returned both matching summaries, newest first.
List Returned both queue receipts over two pages with pageSize: 1.
HistoryByID Returned chronological histories ending in landed and error.
HistoryByChangeID Returned both histories in ascending sqid order and preserved terminal lastError.

Exact gRPC requests and stdout

Setup: Land request 1

RPC: uber.submitqueue.gateway.SubmitQueueGateway/Land

Request:

{"queue":"e2e-test-queue","change":{"uris":["github://uber/grpc-verification/pull/789/0123456789abcdef0123456789abcdef01234567"]},"strategy":"REBASE"}

STDOUT:

{
  "sqid": "e2e-test-queue/1"
}
Setup: Land request 2 with the same pinned change

RPC: uber.submitqueue.gateway.SubmitQueueGateway/Land

Request:

{"queue":"e2e-test-queue","change":{"uris":["github://uber/grpc-verification/pull/789/0123456789abcdef0123456789abcdef01234567"]},"strategy":"REBASE"}

STDOUT:

{
  "sqid": "e2e-test-queue/2"
}
StatusByID: successful request

RPC: uber.submitqueue.gateway.SubmitQueueGateway/StatusByID

Request:

{"sqid":"e2e-test-queue/1"}

STDOUT:

{
  "request": {
    "sqid": "e2e-test-queue/1",
    "queue": "e2e-test-queue",
    "changeUris": [
      "github://uber/grpc-verification/pull/789/0123456789abcdef0123456789abcdef01234567"
    ],
    "receivedAtMs": "1783981410120",
    "status": "landed",
    "metadata": {
      "batch_id": "e2e-test-queue/batch/1"
    }
  }
}
StatusByID: duplicate request

RPC: uber.submitqueue.gateway.SubmitQueueGateway/StatusByID

Request:

{"sqid":"e2e-test-queue/2"}

STDOUT:

{
  "request": {
    "sqid": "e2e-test-queue/2",
    "queue": "e2e-test-queue",
    "changeUris": [
      "github://uber/grpc-verification/pull/789/0123456789abcdef0123456789abcdef01234567"
    ],
    "receivedAtMs": "1783981410176",
    "status": "error",
    "lastError": "request e2e-test-queue/2 is a duplicate of in-flight request e2e-test-queue/1"
  }
}
StatusByChangeID

RPC: uber.submitqueue.gateway.SubmitQueueGateway/StatusByChangeID

Request:

{"changeId":"github://uber/grpc-verification/pull/789/0123456789abcdef0123456789abcdef01234567"}

STDOUT:

{
  "requests": [
    {
      "sqid": "e2e-test-queue/2",
      "queue": "e2e-test-queue",
      "changeUris": [
        "github://uber/grpc-verification/pull/789/0123456789abcdef0123456789abcdef01234567"
      ],
      "receivedAtMs": "1783981410176",
      "status": "error",
      "lastError": "request e2e-test-queue/2 is a duplicate of in-flight request e2e-test-queue/1"
    },
    {
      "sqid": "e2e-test-queue/1",
      "queue": "e2e-test-queue",
      "changeUris": [
        "github://uber/grpc-verification/pull/789/0123456789abcdef0123456789abcdef01234567"
      ],
      "receivedAtMs": "1783981410120",
      "status": "landed",
      "metadata": {
        "batch_id": "e2e-test-queue/batch/1"
      }
    }
  ]
}
List: first page

RPC: uber.submitqueue.gateway.SubmitQueueGateway/List

Request:

{"queue":"e2e-test-queue","receivedAtOrAfterMs":1783981410120,"receivedBeforeMs":1783981410177,"pageSize":1}

STDOUT:

{
  "requests": [
    {
      "sqid": "e2e-test-queue/2",
      "queue": "e2e-test-queue",
      "changeUris": [
        "github://uber/grpc-verification/pull/789/0123456789abcdef0123456789abcdef01234567"
      ],
      "receivedAtMs": "1783981410176",
      "status": "error",
      "lastError": "request e2e-test-queue/2 is a duplicate of in-flight request e2e-test-queue/1"
    }
  ],
  "nextPageToken": "bGFzdF9yZWNlaXZlZF9hdF9tcz0xNzgzOTgxNDEwMTc2Jmxhc3RfcmVxdWVzdF9pZD1lMmUtdGVzdC1xdWV1ZSUyRjImcXVldWU9ZTJlLXRlc3QtcXVldWUmcmVjZWl2ZWRfYXRfb3JfYWZ0ZXJfbXM9MTc4Mzk4MTQxMDEyMCZyZWNlaXZlZF9iZWZvcmVfbXM9MTc4Mzk4MTQxMDE3Nw"
}
List: second page

RPC: uber.submitqueue.gateway.SubmitQueueGateway/List

Request:

{"queue":"e2e-test-queue","receivedAtOrAfterMs":1783981410120,"receivedBeforeMs":1783981410177,"pageSize":1,"pageToken":"bGFzdF9yZWNlaXZlZF9hdF9tcz0xNzgzOTgxNDEwMTc2Jmxhc3RfcmVxdWVzdF9pZD1lMmUtdGVzdC1xdWV1ZSUyRjImcXVldWU9ZTJlLXRlc3QtcXVldWUmcmVjZWl2ZWRfYXRfb3JfYWZ0ZXJfbXM9MTc4Mzk4MTQxMDEyMCZyZWNlaXZlZF9iZWZvcmVfbXM9MTc4Mzk4MTQxMDE3Nw"}

STDOUT:

{
  "requests": [
    {
      "sqid": "e2e-test-queue/1",
      "queue": "e2e-test-queue",
      "changeUris": [
        "github://uber/grpc-verification/pull/789/0123456789abcdef0123456789abcdef01234567"
      ],
      "receivedAtMs": "1783981410120",
      "status": "landed",
      "metadata": {
        "batch_id": "e2e-test-queue/batch/1"
      }
    }
  ]
}
HistoryByID: successful request

RPC: uber.submitqueue.gateway.SubmitQueueGateway/HistoryByID

Request:

{"sqid":"e2e-test-queue/1"}

STDOUT:

{
  "events": [
    {
      "timestampMs": "1783981410120",
      "status": "accepted"
    },
    {
      "timestampMs": "1783981410282",
      "status": "started"
    },
    {
      "timestampMs": "1783981410900",
      "status": "batched",
      "metadata": {
        "batch_id": "e2e-test-queue/batch/1"
      }
    },
    {
      "timestampMs": "1783981411102",
      "status": "scored",
      "metadata": {
        "batch_id": "e2e-test-queue/batch/1",
        "score": "0.7000"
      }
    },
    {
      "timestampMs": "1783981412404",
      "status": "landed",
      "metadata": {
        "batch_id": "e2e-test-queue/batch/1"
      }
    }
  ]
}
HistoryByID: duplicate request

RPC: uber.submitqueue.gateway.SubmitQueueGateway/HistoryByID

Request:

{"sqid":"e2e-test-queue/2"}

STDOUT:

{
  "events": [
    {
      "timestampMs": "1783981410176",
      "status": "accepted"
    },
    {
      "timestampMs": "1783981410291",
      "status": "started"
    },
    {
      "timestampMs": "1783981410575",
      "status": "error",
      "lastError": "request e2e-test-queue/2 is a duplicate of in-flight request e2e-test-queue/1"
    }
  ]
}
HistoryByChangeID

RPC: uber.submitqueue.gateway.SubmitQueueGateway/HistoryByChangeID

Request:

{"changeId":"github://uber/grpc-verification/pull/789/0123456789abcdef0123456789abcdef01234567"}

STDOUT:

{
  "histories": [
    {
      "sqid": "e2e-test-queue/1",
      "events": [
        {
          "timestampMs": "1783981410120",
          "status": "accepted"
        },
        {
          "timestampMs": "1783981410282",
          "status": "started"
        },
        {
          "timestampMs": "1783981410900",
          "status": "batched",
          "metadata": {
            "batch_id": "e2e-test-queue/batch/1"
          }
        },
        {
          "timestampMs": "1783981411102",
          "status": "scored",
          "metadata": {
            "batch_id": "e2e-test-queue/batch/1",
            "score": "0.7000"
          }
        },
        {
          "timestampMs": "1783981412404",
          "status": "landed",
          "metadata": {
            "batch_id": "e2e-test-queue/batch/1"
          }
        }
      ]
    },
    {
      "sqid": "e2e-test-queue/2",
      "events": [
        {
          "timestampMs": "1783981410176",
          "status": "accepted"
        },
        {
          "timestampMs": "1783981410291",
          "status": "started"
        },
        {
          "timestampMs": "1783981410575",
          "status": "error",
          "lastError": "request e2e-test-queue/2 is a duplicate of in-flight request e2e-test-queue/1"
        }
      ]
    }
  ]
}

Issues

Stack

  1. [1/N] feat(storage): add request read-model stores #340
  2. [2/N] feat(gateway): persist request receipts on Land #341
  3. [3/N] feat(request): materialize request log status #342
  4. [4/N] feat(submitqueue): activate request status materialization #343
  5. [5/N] feat(gateway): add request status lookups #344
  6. [6/N] feat(gateway): add queue request listing #345
  7. @ [7/N] feat(gateway): add request history lookups #346

@albertywu albertywu changed the title feat(gateway): add request history lookups [7/N] feat(gateway): add request history lookups Jul 13, 2026
@albertywu albertywu marked this pull request as ready for review July 13, 2026 23:23
@albertywu albertywu requested review from a team, behinddwalls and sbalabanov as code owners July 13, 2026 23:23
@albertywu albertywu force-pushed the wua/request-list-api branch from 8ec34b2 to 58b2eca Compare July 15, 2026 02:51
@albertywu albertywu force-pushed the wua/request-history-api branch from 245a0cb to 25e5a88 Compare July 15, 2026 02:51
@albertywu albertywu marked this pull request as draft July 15, 2026 02:52
@albertywu albertywu force-pushed the wua/request-list-api branch from 58b2eca to df83074 Compare July 15, 2026 04:06
@albertywu albertywu force-pushed the wua/request-history-api branch from 25e5a88 to 19e6f6e Compare July 15, 2026 04:06
@albertywu albertywu marked this pull request as ready for review July 15, 2026 04:14
@albertywu albertywu force-pushed the wua/request-history-api branch from 19e6f6e to d60e77a Compare July 15, 2026 04:31
@albertywu albertywu force-pushed the wua/request-list-api branch from df83074 to 7cee179 Compare July 15, 2026 04:31
// Error message associated with the event. Empty when absent.
string last_error = 3;
// Display and debugging metadata associated with the event.
map<string, string> metadata = 4;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wondering if this would suffice to represent different metadata for different stages?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants