From 05c63ce73106665554117f51590bba74badb840b Mon Sep 17 00:00:00 2001 From: Albert Wu Date: Thu, 28 May 2026 20:25:22 -0700 Subject: [PATCH] feat(gateway): add Status RPC to look up request status by sqid Adds a read-only Status RPC to the gateway that returns the current customer-friendly status of a previously submitted request, reconciled from the append-only request log via core/request.GetCurrentStateFromRequestLog. Status is a free-form string (statuses can be added without breaking clients); unknown sqids map to a typed RequestNotFoundError (user error) and empty sqids to ErrInvalidRequest. Named "Status" to match the gateway's short RPC naming (Ping, Land, Status). Changes: - gateway/proto/gateway.proto: Status RPC, StatusRequest/StatusResponse, and RequestNotFoundError messages (regenerated protopb) - gateway/controller/status.go: StatusController + tests - example/server/gateway/main.go: wire controller (reuses existing RequestLogStore) Validation: - Unit tests: bazel test //gateway/controller:controller_test (PASS) - Integration (local stack): make local-gateway-start PORT=$(docker port submitqueue-gateway-service-1 8080 | head -1 | cut -d: -f2) # method is registered grpcurl -plaintext localhost:$PORT list uber.submitqueue.gateway.SubmitQueueGateway -> Land, Ping, Status # seed a request grpcurl -plaintext -d '{"queue":"test-queue","change":{"uris":["github://uber/submitqueue/pull/123/c3a4d5e6f7890123456789abcdef0123456789ab"]}}' \ localhost:$PORT uber.submitqueue.gateway.SubmitQueueGateway/Land -> { "sqid": "test-queue/1" } # happy path grpcurl -plaintext -d '{"sqid":"test-queue/1"}' \ localhost:$PORT uber.submitqueue.gateway.SubmitQueueGateway/Status -> { "status": "accepted" } # unknown sqid grpcurl -plaintext -d '{"sqid":"test-queue/999"}' \ localhost:$PORT uber.submitqueue.gateway.SubmitQueueGateway/Status -> ERROR: request not found for sqid "test-queue/999" # empty sqid grpcurl -plaintext -d '{"sqid":""}' \ localhost:$PORT uber.submitqueue.gateway.SubmitQueueGateway/Status -> ERROR: StatusController requires the request to have a sqid specified: invalid request Co-authored-by: Cursor --- example/server/gateway/main.go | 16 +- gateway/controller/BUILD.bazel | 4 + gateway/controller/status.go | 97 +++++++++++ gateway/controller/status_test.go | 116 +++++++++++++ gateway/proto/gateway.proto | 30 ++++ gateway/protopb/gateway.pb.go | 255 +++++++++++++++++++++++++--- gateway/protopb/gateway.pb.yarpc.go | 127 ++++++++++---- gateway/protopb/gateway_grpc.pb.go | 60 ++++++- 8 files changed, 639 insertions(+), 66 deletions(-) create mode 100644 gateway/controller/status.go create mode 100644 gateway/controller/status_test.go diff --git a/example/server/gateway/main.go b/example/server/gateway/main.go index 5088bd19..52be614f 100644 --- a/example/server/gateway/main.go +++ b/example/server/gateway/main.go @@ -43,8 +43,9 @@ import ( // GatewayServer wraps the controller and implements the gRPC service interface type GatewayServer struct { pb.UnimplementedSubmitQueueGatewayServer - pingController *controller.PingController - landController *controller.LandController + pingController *controller.PingController + landController *controller.LandController + statusController *controller.StatusController } // Ping delegates to the controller @@ -57,6 +58,11 @@ func (s *GatewayServer) Land(ctx context.Context, req *pb.LandRequest) (*pb.Land return s.landController.Land(ctx, req) } +// Status delegates to the controller +func (s *GatewayServer) Status(ctx context.Context, req *pb.StatusRequest) (*pb.StatusResponse, error) { + return s.statusController.Status(ctx, req) +} + func main() { code := 0 if err := run(); err != nil { @@ -190,9 +196,11 @@ func run() error { // Create controllers and wrap them for gRPC pingController := controller.NewPingController(logger, scope) landController := controller.NewLandController(logger.Sugar(), scope, cnt, requestLogStore, queueConfigs, registry) + statusController := controller.NewStatusController(logger.Sugar(), scope, requestLogStore) gatewayServer := &GatewayServer{ - pingController: pingController, - landController: landController, + pingController: pingController, + landController: landController, + statusController: statusController, } pb.RegisterSubmitQueueGatewayServer(grpcServer, gatewayServer) diff --git a/gateway/controller/BUILD.bazel b/gateway/controller/BUILD.bazel index c2eb99db..b66d43b8 100644 --- a/gateway/controller/BUILD.bazel +++ b/gateway/controller/BUILD.bazel @@ -5,6 +5,7 @@ go_library( srcs = [ "land.go", "ping.go", + "status.go", ], importpath = "github.com/uber/submitqueue/gateway/controller", visibility = ["//visibility:public"], @@ -12,6 +13,7 @@ go_library( "//core/consumer", "//core/errs", "//core/metrics", + "//core/request", "//entity", "//entity/queue", "//extension/counter", @@ -28,6 +30,7 @@ go_test( srcs = [ "land_test.go", "ping_test.go", + "status_test.go", ], embed = [":controller"], deps = [ @@ -39,6 +42,7 @@ go_test( "//extension/queue/mock", "//extension/queueconfig", "//extension/queueconfig/mock", + "//extension/storage", "//extension/storage/mock", "//gateway/protopb", "@com_github_stretchr_testify//assert", diff --git a/gateway/controller/status.go b/gateway/controller/status.go new file mode 100644 index 00000000..d28407db --- /dev/null +++ b/gateway/controller/status.go @@ -0,0 +1,97 @@ +// Copyright (c) 2025 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package controller + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/uber-go/tally/v4" + "github.com/uber/submitqueue/core/errs" + "github.com/uber/submitqueue/core/request" + "github.com/uber/submitqueue/extension/storage" + pb "github.com/uber/submitqueue/gateway/protopb" + "go.uber.org/zap" +) + +// RequestNotFoundError indicates that no request log records exist for the +// requested sqid. Either the sqid is wrong or the request has not been +// accepted yet. +type RequestNotFoundError struct { + Sqid string +} + +// Error implements the error interface. +func (e *RequestNotFoundError) Error() string { + return fmt.Sprintf("request not found for sqid %q", e.Sqid) +} + +// IsRequestNotFound returns true if any error in the chain is a +// *RequestNotFoundError. +func IsRequestNotFound(err error) bool { + var target *RequestNotFoundError + return errors.As(err, &target) +} + +// StatusController handles request status business logic for the gateway. +type StatusController struct { + logger *zap.SugaredLogger + metricsScope tally.Scope + requestLogStore storage.RequestLogStore +} + +// NewStatusController creates a new instance of the gateway status controller. +func NewStatusController(logger *zap.SugaredLogger, scope tally.Scope, requestLogStore storage.RequestLogStore) *StatusController { + return &StatusController{ + logger: logger, + metricsScope: scope, + requestLogStore: requestLogStore, + } +} + +// Status returns the current reconciled status of a request identified by its sqid. +func (c *StatusController) Status(ctx context.Context, req *pb.StatusRequest) (*pb.StatusResponse, error) { + start := time.Now() + defer func() { + c.metricsScope.Timer("status_latency").Record(time.Since(start)) + }() + + c.metricsScope.Counter("status_count").Inc(1) + + if req.Sqid == "" { + return nil, fmt.Errorf("StatusController requires the request to have a sqid specified: %w", ErrInvalidRequest) + } + + state, err := request.GetCurrentStateFromRequestLog(ctx, c.requestLogStore, req.Sqid) + if err != nil { + if storage.IsNotFound(err) { + return nil, errs.NewUserError(&RequestNotFoundError{Sqid: req.Sqid}) + } + return nil, fmt.Errorf("StatusController failed to get current state for sqid=%s: %w", req.Sqid, err) + } + + c.logger.Debugw("request status retrieved", + "sqid", req.Sqid, + "status", string(state.Status), + ) + + return &pb.StatusResponse{ + Status: string(state.Status), + LastError: state.LastError, + Metadata: state.Metadata, + }, nil +} diff --git a/gateway/controller/status_test.go b/gateway/controller/status_test.go new file mode 100644 index 00000000..50aabd19 --- /dev/null +++ b/gateway/controller/status_test.go @@ -0,0 +1,116 @@ +// Copyright (c) 2025 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package controller + +import ( + "context" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/uber-go/tally/v4" + "github.com/uber/submitqueue/core/errs" + "github.com/uber/submitqueue/entity" + "github.com/uber/submitqueue/extension/storage" + storagemock "github.com/uber/submitqueue/extension/storage/mock" + pb "github.com/uber/submitqueue/gateway/protopb" + "go.uber.org/mock/gomock" + "go.uber.org/zap" +) + +func TestStatus_ReturnsCurrentState(t *testing.T) { + ctrl := gomock.NewController(t) + + store := storagemock.NewMockRequestLogStore(ctrl) + store.EXPECT().List(gomock.Any(), "test-queue/1").Return([]entity.RequestLog{ + {RequestID: "test-queue/1", TimestampMs: 100, Status: entity.RequestStatusAccepted}, + {RequestID: "test-queue/1", TimestampMs: 200, Status: entity.RequestStatusValidating, LastError: "boom", Metadata: map[string]string{"k": "v"}}, + }, nil) + + controller := NewStatusController(zap.NewNop().Sugar(), tally.NoopScope, store) + + resp, err := controller.Status(context.Background(), &pb.StatusRequest{Sqid: "test-queue/1"}) + + require.NoError(t, err) + assert.Equal(t, string(entity.RequestStatusValidating), resp.Status) + assert.Equal(t, "boom", resp.LastError) + assert.Equal(t, map[string]string{"k": "v"}, resp.Metadata) +} + +func TestStatus_Errors(t *testing.T) { + tests := []struct { + name string + sqid string + setupStore func(*storagemock.MockRequestLogStore) + wantInvalid bool + wantNotFound bool + wantUserError bool + }{ + { + name: "empty sqid is an invalid request", + sqid: "", + wantInvalid: true, + wantUserError: true, + }, + { + name: "unknown sqid maps to not found", + sqid: "missing/1", + setupStore: func(s *storagemock.MockRequestLogStore) { + s.EXPECT().List(gomock.Any(), "missing/1").Return(nil, storage.ErrNotFound) + }, + wantNotFound: true, + wantUserError: true, + }, + { + name: "store failure propagates as infra error", + sqid: "test-queue/1", + setupStore: func(s *storagemock.MockRequestLogStore) { + s.EXPECT().List(gomock.Any(), "test-queue/1").Return(nil, fmt.Errorf("log backend down")) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + store := storagemock.NewMockRequestLogStore(ctrl) + if tt.setupStore != nil { + tt.setupStore(store) + } + + controller := NewStatusController(zap.NewNop().Sugar(), tally.NoopScope, store) + + _, err := controller.Status(context.Background(), &pb.StatusRequest{Sqid: tt.sqid}) + + require.Error(t, err) + // IsRequestNotFound is a precise type check; IsInvalidRequest matches any + // user error (see errs.userError.Is), so only assert it where it is the + // defining classification. + assert.Equal(t, tt.wantNotFound, IsRequestNotFound(err)) + assert.Equal(t, tt.wantUserError, errs.IsUserError(err)) + assert.False(t, errs.IsRetryable(err)) + if tt.wantInvalid { + assert.True(t, IsInvalidRequest(err)) + } + + if tt.wantNotFound { + var typed *RequestNotFoundError + require.ErrorAs(t, err, &typed) + assert.Equal(t, tt.sqid, typed.Sqid) + } + }) + } +} diff --git a/gateway/proto/gateway.proto b/gateway/proto/gateway.proto index 26d1a257..0b191e90 100644 --- a/gateway/proto/gateway.proto +++ b/gateway/proto/gateway.proto @@ -92,6 +92,24 @@ message LandResponse { string sqid = 1; } +// StatusRequest defines a request to look up the current status of a previously submitted request. +message StatusRequest { + // Globally unique identifier for the request, as returned by Land in the LandResponse. + string sqid = 1; +} + +// StatusResponse defines the response to a status request. +// The status is eventually consistent with the request store; it might take some time to converge, typically no more than a few seconds. +message StatusResponse { + // Current customer-friendly status of the request (e.g. "accepted", "validating", "landed", "error"). + // Status is a free-form string because the system may introduce new statuses without breaking existing clients. + string status = 1; + // Last error message associated with the current status. Empty string if there is no error. + string last_error = 2; + // Free-form key-value metadata associated with the current status, for display or debugging purposes. Empty if none. + map metadata = 3; +} + // *************** // Error messages, returned as `google.rpc.Status` messages. // *************** @@ -110,6 +128,14 @@ message UnrecognizedQueueError { string queue = 2; } +// RequestNotFoundError is returned when no request is found for the given sqid. Typically this indicates a typo in the sqid or that the request has not been accepted yet. +message RequestNotFoundError { + // Free text error message describing the error. + Error error = 1; + // The sqid that was not found. + string sqid = 2; +} + // *************** // Service definitions. // *************** @@ -122,4 +148,8 @@ service SubmitQueueGateway { // Land lands a set of code changes into a target branch, performing the necessary validations across all other changes in the queue. // The processing is asynchronous and returns a LandResponse immediately. The land request is processed in the background. rpc Land(LandRequest) returns (LandResponse) {} + + // Status returns the current status of a previously submitted request, identified by its sqid. + // The status is eventually consistent with the request store and reconciled from the append-only request log. + rpc Status(StatusRequest) returns (StatusResponse) {} } diff --git a/gateway/protopb/gateway.pb.go b/gateway/protopb/gateway.pb.go index 30bc6348..b457b053 100644 --- a/gateway/protopb/gateway.pb.go +++ b/gateway/protopb/gateway.pb.go @@ -1,3 +1,17 @@ +// Copyright (c) 2025 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.10 @@ -370,6 +384,118 @@ func (x *LandResponse) GetSqid() string { return "" } +// StatusRequest defines a request to look up the current status of a previously submitted request. +type StatusRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Globally unique identifier for the request, as returned by Land in the LandResponse. + Sqid string `protobuf:"bytes,1,opt,name=sqid,proto3" json:"sqid,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StatusRequest) Reset() { + *x = StatusRequest{} + mi := &file_gateway_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StatusRequest) ProtoMessage() {} + +func (x *StatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_gateway_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StatusRequest.ProtoReflect.Descriptor instead. +func (*StatusRequest) Descriptor() ([]byte, []int) { + return file_gateway_proto_rawDescGZIP(), []int{5} +} + +func (x *StatusRequest) GetSqid() string { + if x != nil { + return x.Sqid + } + return "" +} + +// StatusResponse defines the response to a status request. +// The status is eventually consistent with the request store; it might take some time to converge, typically no more than a few seconds. +type StatusResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Current customer-friendly status of the request (e.g. "accepted", "validating", "landed", "error"). + // Status is a free-form string because the system may introduce new statuses without breaking existing clients. + Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + // Last error message associated with the current status. Empty string if there is no error. + LastError string `protobuf:"bytes,2,opt,name=last_error,json=lastError,proto3" json:"last_error,omitempty"` + // Free-form key-value metadata associated with the current status, for display or debugging purposes. Empty if none. + Metadata map[string]string `protobuf:"bytes,3,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StatusResponse) Reset() { + *x = StatusResponse{} + mi := &file_gateway_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StatusResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StatusResponse) ProtoMessage() {} + +func (x *StatusResponse) ProtoReflect() protoreflect.Message { + mi := &file_gateway_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StatusResponse.ProtoReflect.Descriptor instead. +func (*StatusResponse) Descriptor() ([]byte, []int) { + return file_gateway_proto_rawDescGZIP(), []int{6} +} + +func (x *StatusResponse) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *StatusResponse) GetLastError() string { + if x != nil { + return x.LastError + } + return "" +} + +func (x *StatusResponse) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + // Generic error with metadata. Each custom error type should extend this message. type Error struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -381,7 +507,7 @@ type Error struct { func (x *Error) Reset() { *x = Error{} - mi := &file_gateway_proto_msgTypes[5] + mi := &file_gateway_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -393,7 +519,7 @@ func (x *Error) String() string { func (*Error) ProtoMessage() {} func (x *Error) ProtoReflect() protoreflect.Message { - mi := &file_gateway_proto_msgTypes[5] + mi := &file_gateway_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -406,7 +532,7 @@ func (x *Error) ProtoReflect() protoreflect.Message { // Deprecated: Use Error.ProtoReflect.Descriptor instead. func (*Error) Descriptor() ([]byte, []int) { - return file_gateway_proto_rawDescGZIP(), []int{5} + return file_gateway_proto_rawDescGZIP(), []int{7} } func (x *Error) GetMessage() string { @@ -429,7 +555,7 @@ type UnrecognizedQueueError struct { func (x *UnrecognizedQueueError) Reset() { *x = UnrecognizedQueueError{} - mi := &file_gateway_proto_msgTypes[6] + mi := &file_gateway_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -441,7 +567,7 @@ func (x *UnrecognizedQueueError) String() string { func (*UnrecognizedQueueError) ProtoMessage() {} func (x *UnrecognizedQueueError) ProtoReflect() protoreflect.Message { - mi := &file_gateway_proto_msgTypes[6] + mi := &file_gateway_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -454,7 +580,7 @@ func (x *UnrecognizedQueueError) ProtoReflect() protoreflect.Message { // Deprecated: Use UnrecognizedQueueError.ProtoReflect.Descriptor instead. func (*UnrecognizedQueueError) Descriptor() ([]byte, []int) { - return file_gateway_proto_rawDescGZIP(), []int{6} + return file_gateway_proto_rawDescGZIP(), []int{8} } func (x *UnrecognizedQueueError) GetError() *Error { @@ -471,6 +597,61 @@ func (x *UnrecognizedQueueError) GetQueue() string { return "" } +// RequestNotFoundError is returned when no request is found for the given sqid. Typically this indicates a typo in the sqid or that the request has not been accepted yet. +type RequestNotFoundError struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Free text error message describing the error. + Error *Error `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + // The sqid that was not found. + Sqid string `protobuf:"bytes,2,opt,name=sqid,proto3" json:"sqid,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RequestNotFoundError) Reset() { + *x = RequestNotFoundError{} + mi := &file_gateway_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RequestNotFoundError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestNotFoundError) ProtoMessage() {} + +func (x *RequestNotFoundError) ProtoReflect() protoreflect.Message { + mi := &file_gateway_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestNotFoundError.ProtoReflect.Descriptor instead. +func (*RequestNotFoundError) Descriptor() ([]byte, []int) { + return file_gateway_proto_rawDescGZIP(), []int{9} +} + +func (x *RequestNotFoundError) GetError() *Error { + if x != nil { + return x.Error + } + return nil +} + +func (x *RequestNotFoundError) GetSqid() string { + if x != nil { + return x.Sqid + } + return "" +} + var File_gateway_proto protoreflect.FileDescriptor const file_gateway_proto_rawDesc = "" + @@ -490,21 +671,35 @@ const file_gateway_proto_rawDesc = "" + "\x06change\x18\x02 \x01(\v2 .uber.submitqueue.gateway.ChangeR\x06change\x12>\n" + "\bstrategy\x18\x04 \x01(\x0e2\".uber.submitqueue.gateway.StrategyR\bstrategy\"\"\n" + "\fLandResponse\x12\x12\n" + - "\x04sqid\x18\x01 \x01(\tR\x04sqid\"!\n" + + "\x04sqid\x18\x01 \x01(\tR\x04sqid\"#\n" + + "\rStatusRequest\x12\x12\n" + + "\x04sqid\x18\x01 \x01(\tR\x04sqid\"\xd8\x01\n" + + "\x0eStatusResponse\x12\x16\n" + + "\x06status\x18\x01 \x01(\tR\x06status\x12\x1d\n" + + "\n" + + "last_error\x18\x02 \x01(\tR\tlastError\x12R\n" + + "\bmetadata\x18\x03 \x03(\v26.uber.submitqueue.gateway.StatusResponse.MetadataEntryR\bmetadata\x1a;\n" + + "\rMetadataEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"!\n" + "\x05Error\x12\x18\n" + "\amessage\x18\x01 \x01(\tR\amessage\"e\n" + "\x16UnrecognizedQueueError\x125\n" + "\x05error\x18\x01 \x01(\v2\x1f.uber.submitqueue.gateway.ErrorR\x05error\x12\x14\n" + - "\x05queue\x18\x02 \x01(\tR\x05queue*A\n" + + "\x05queue\x18\x02 \x01(\tR\x05queue\"a\n" + + "\x14RequestNotFoundError\x125\n" + + "\x05error\x18\x01 \x01(\v2\x1f.uber.submitqueue.gateway.ErrorR\x05error\x12\x12\n" + + "\x04sqid\x18\x02 \x01(\tR\x04sqid*A\n" + "\bStrategy\x12\v\n" + "\aDEFAULT\x10\x00\x12\n" + "\n" + "\x06REBASE\x10\x01\x12\x11\n" + "\rSQUASH_REBASE\x10\x02\x12\t\n" + - "\x05MERGE\x10\x032\xc6\x01\n" + + "\x05MERGE\x10\x032\xa5\x02\n" + "\x12SubmitQueueGateway\x12W\n" + "\x04Ping\x12%.uber.submitqueue.gateway.PingRequest\x1a&.uber.submitqueue.gateway.PingResponse\"\x00\x12W\n" + - "\x04Land\x12%.uber.submitqueue.gateway.LandRequest\x1a&.uber.submitqueue.gateway.LandResponse\"\x00B[\n" + + "\x04Land\x12%.uber.submitqueue.gateway.LandRequest\x1a&.uber.submitqueue.gateway.LandResponse\"\x00\x12]\n" + + "\x06Status\x12'.uber.submitqueue.gateway.StatusRequest\x1a(.uber.submitqueue.gateway.StatusResponse\"\x00B[\n" + "\x1ccom.uber.submitqueue.gatewayB\fGatewayProtoP\x01Z+github.com/uber/submitqueue/gateway/protopbb\x06proto3" var ( @@ -520,7 +715,7 @@ func file_gateway_proto_rawDescGZIP() []byte { } var file_gateway_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_gateway_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_gateway_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_gateway_proto_goTypes = []any{ (Strategy)(0), // 0: uber.submitqueue.gateway.Strategy (*PingRequest)(nil), // 1: uber.submitqueue.gateway.PingRequest @@ -528,22 +723,30 @@ var file_gateway_proto_goTypes = []any{ (*Change)(nil), // 3: uber.submitqueue.gateway.Change (*LandRequest)(nil), // 4: uber.submitqueue.gateway.LandRequest (*LandResponse)(nil), // 5: uber.submitqueue.gateway.LandResponse - (*Error)(nil), // 6: uber.submitqueue.gateway.Error - (*UnrecognizedQueueError)(nil), // 7: uber.submitqueue.gateway.UnrecognizedQueueError + (*StatusRequest)(nil), // 6: uber.submitqueue.gateway.StatusRequest + (*StatusResponse)(nil), // 7: uber.submitqueue.gateway.StatusResponse + (*Error)(nil), // 8: uber.submitqueue.gateway.Error + (*UnrecognizedQueueError)(nil), // 9: uber.submitqueue.gateway.UnrecognizedQueueError + (*RequestNotFoundError)(nil), // 10: uber.submitqueue.gateway.RequestNotFoundError + nil, // 11: uber.submitqueue.gateway.StatusResponse.MetadataEntry } var file_gateway_proto_depIdxs = []int32{ - 3, // 0: uber.submitqueue.gateway.LandRequest.change:type_name -> uber.submitqueue.gateway.Change - 0, // 1: uber.submitqueue.gateway.LandRequest.strategy:type_name -> uber.submitqueue.gateway.Strategy - 6, // 2: uber.submitqueue.gateway.UnrecognizedQueueError.error:type_name -> uber.submitqueue.gateway.Error - 1, // 3: uber.submitqueue.gateway.SubmitQueueGateway.Ping:input_type -> uber.submitqueue.gateway.PingRequest - 4, // 4: uber.submitqueue.gateway.SubmitQueueGateway.Land:input_type -> uber.submitqueue.gateway.LandRequest - 2, // 5: uber.submitqueue.gateway.SubmitQueueGateway.Ping:output_type -> uber.submitqueue.gateway.PingResponse - 5, // 6: uber.submitqueue.gateway.SubmitQueueGateway.Land:output_type -> uber.submitqueue.gateway.LandResponse - 5, // [5:7] is the sub-list for method output_type - 3, // [3:5] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 3, // 0: uber.submitqueue.gateway.LandRequest.change:type_name -> uber.submitqueue.gateway.Change + 0, // 1: uber.submitqueue.gateway.LandRequest.strategy:type_name -> uber.submitqueue.gateway.Strategy + 11, // 2: uber.submitqueue.gateway.StatusResponse.metadata:type_name -> uber.submitqueue.gateway.StatusResponse.MetadataEntry + 8, // 3: uber.submitqueue.gateway.UnrecognizedQueueError.error:type_name -> uber.submitqueue.gateway.Error + 8, // 4: uber.submitqueue.gateway.RequestNotFoundError.error:type_name -> uber.submitqueue.gateway.Error + 1, // 5: uber.submitqueue.gateway.SubmitQueueGateway.Ping:input_type -> uber.submitqueue.gateway.PingRequest + 4, // 6: uber.submitqueue.gateway.SubmitQueueGateway.Land:input_type -> uber.submitqueue.gateway.LandRequest + 6, // 7: uber.submitqueue.gateway.SubmitQueueGateway.Status:input_type -> uber.submitqueue.gateway.StatusRequest + 2, // 8: uber.submitqueue.gateway.SubmitQueueGateway.Ping:output_type -> uber.submitqueue.gateway.PingResponse + 5, // 9: uber.submitqueue.gateway.SubmitQueueGateway.Land:output_type -> uber.submitqueue.gateway.LandResponse + 7, // 10: uber.submitqueue.gateway.SubmitQueueGateway.Status:output_type -> uber.submitqueue.gateway.StatusResponse + 8, // [8:11] is the sub-list for method output_type + 5, // [5:8] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name } func init() { file_gateway_proto_init() } @@ -557,7 +760,7 @@ func file_gateway_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_gateway_proto_rawDesc), len(file_gateway_proto_rawDesc)), NumEnums: 1, - NumMessages: 7, + NumMessages: 11, NumExtensions: 0, NumServices: 1, }, diff --git a/gateway/protopb/gateway.pb.yarpc.go b/gateway/protopb/gateway.pb.yarpc.go index c3ba2343..5d660969 100644 --- a/gateway/protopb/gateway.pb.yarpc.go +++ b/gateway/protopb/gateway.pb.yarpc.go @@ -24,6 +24,7 @@ var _ = ioutil.NopCloser type SubmitQueueGatewayYARPCClient interface { Ping(context.Context, *PingRequest, ...yarpc.CallOption) (*PingResponse, error) Land(context.Context, *LandRequest, ...yarpc.CallOption) (*LandResponse, error) + Status(context.Context, *StatusRequest, ...yarpc.CallOption) (*StatusResponse, error) } func newSubmitQueueGatewayYARPCClient(clientConfig transport.ClientConfig, anyResolver jsonpb.AnyResolver, options ...protobuf.ClientOption) SubmitQueueGatewayYARPCClient { @@ -46,6 +47,7 @@ func NewSubmitQueueGatewayYARPCClient(clientConfig transport.ClientConfig, optio type SubmitQueueGatewayYARPCServer interface { Ping(context.Context, *PingRequest) (*PingResponse, error) Land(context.Context, *LandRequest) (*LandResponse, error) + Status(context.Context, *StatusRequest) (*StatusResponse, error) } type buildSubmitQueueGatewayYARPCProceduresParams struct { @@ -79,6 +81,16 @@ func buildSubmitQueueGatewayYARPCProcedures(params buildSubmitQueueGatewayYARPCP }, ), }, + { + MethodName: "Status", + Handler: protobuf.NewUnaryHandler( + protobuf.UnaryHandlerParams{ + Handle: handler.Status, + NewRequest: newSubmitQueueGatewayServiceStatusYARPCRequest, + AnyResolver: params.AnyResolver, + }, + ), + }, }, OnewayHandlerParams: []protobuf.BuildProceduresOnewayHandlerParams{}, StreamHandlerParams: []protobuf.BuildProceduresStreamHandlerParams{}, @@ -221,6 +233,18 @@ func (c *_SubmitQueueGatewayYARPCCaller) Land(ctx context.Context, request *Land return response, err } +func (c *_SubmitQueueGatewayYARPCCaller) Status(ctx context.Context, request *StatusRequest, options ...yarpc.CallOption) (*StatusResponse, error) { + responseMessage, err := c.streamClient.Call(ctx, "Status", request, newSubmitQueueGatewayServiceStatusYARPCResponse, options...) + if responseMessage == nil { + return nil, err + } + response, ok := responseMessage.(*StatusResponse) + if !ok { + return nil, protobuf.CastError(emptySubmitQueueGatewayServiceStatusYARPCResponse, responseMessage) + } + return response, err +} + type _SubmitQueueGatewayYARPCHandler struct { server SubmitQueueGatewayYARPCServer } @@ -257,6 +281,22 @@ func (h *_SubmitQueueGatewayYARPCHandler) Land(ctx context.Context, requestMessa return response, err } +func (h *_SubmitQueueGatewayYARPCHandler) Status(ctx context.Context, requestMessage proto.Message) (proto.Message, error) { + var request *StatusRequest + var ok bool + if requestMessage != nil { + request, ok = requestMessage.(*StatusRequest) + if !ok { + return nil, protobuf.CastError(emptySubmitQueueGatewayServiceStatusYARPCRequest, requestMessage) + } + } + response, err := h.server.Status(ctx, request) + if response == nil { + return nil, err + } + return response, err +} + func newSubmitQueueGatewayServicePingYARPCRequest() proto.Message { return &PingRequest{} } @@ -273,46 +313,65 @@ func newSubmitQueueGatewayServiceLandYARPCResponse() proto.Message { return &LandResponse{} } +func newSubmitQueueGatewayServiceStatusYARPCRequest() proto.Message { + return &StatusRequest{} +} + +func newSubmitQueueGatewayServiceStatusYARPCResponse() proto.Message { + return &StatusResponse{} +} + var ( - emptySubmitQueueGatewayServicePingYARPCRequest = &PingRequest{} - emptySubmitQueueGatewayServicePingYARPCResponse = &PingResponse{} - emptySubmitQueueGatewayServiceLandYARPCRequest = &LandRequest{} - emptySubmitQueueGatewayServiceLandYARPCResponse = &LandResponse{} + emptySubmitQueueGatewayServicePingYARPCRequest = &PingRequest{} + emptySubmitQueueGatewayServicePingYARPCResponse = &PingResponse{} + emptySubmitQueueGatewayServiceLandYARPCRequest = &LandRequest{} + emptySubmitQueueGatewayServiceLandYARPCResponse = &LandResponse{} + emptySubmitQueueGatewayServiceStatusYARPCRequest = &StatusRequest{} + emptySubmitQueueGatewayServiceStatusYARPCResponse = &StatusResponse{} ) var yarpcFileDescriptorClosuref1a937782ebbded5 = [][]byte{ // gateway.proto []byte{ - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x53, 0x4d, 0x8f, 0xd3, 0x30, - 0x10, 0x5d, 0xf7, 0x6b, 0xdb, 0x49, 0x17, 0x15, 0x0b, 0xa1, 0x68, 0x55, 0x89, 0xae, 0x25, 0xa0, - 0x02, 0x29, 0x95, 0x8a, 0x90, 0x38, 0x21, 0xb5, 0x10, 0x96, 0xc3, 0x82, 0xba, 0x0e, 0x15, 0x12, - 0x1c, 0x56, 0x4e, 0x3a, 0x4a, 0x73, 0x48, 0xd2, 0xda, 0x0e, 0x68, 0xb9, 0xf3, 0x33, 0xf8, 0x3b, - 0xfc, 0x2e, 0x14, 0xc7, 0xdd, 0xcd, 0x25, 0xe5, 0x36, 0x1e, 0xbf, 0x37, 0xf3, 0xe6, 0x79, 0x0c, - 0x67, 0xb1, 0xd0, 0xf8, 0x53, 0xdc, 0x7a, 0x3b, 0x99, 0xeb, 0x9c, 0xba, 0x45, 0x88, 0xd2, 0x53, - 0x45, 0x98, 0x26, 0x7a, 0x5f, 0x60, 0x81, 0x9e, 0xbd, 0x67, 0xcf, 0xc1, 0x59, 0x25, 0x59, 0xcc, - 0x71, 0x5f, 0xa0, 0xd2, 0xd4, 0x85, 0xd3, 0x14, 0x95, 0x12, 0x31, 0xba, 0x64, 0x42, 0xa6, 0x03, - 0x7e, 0x38, 0xb2, 0xdf, 0x04, 0x86, 0x15, 0x52, 0xed, 0xf2, 0x4c, 0x61, 0x33, 0x94, 0x5e, 0xc0, - 0x50, 0xa1, 0xfc, 0x91, 0x44, 0x78, 0x93, 0x89, 0x14, 0xdd, 0x96, 0xb9, 0x76, 0x6c, 0xee, 0xb3, - 0x48, 0x91, 0x8e, 0x61, 0xa0, 0x93, 0x14, 0x95, 0x16, 0xe9, 0xce, 0x6d, 0x4f, 0xc8, 0xb4, 0xcd, - 0xef, 0x13, 0xf4, 0x1c, 0xfa, 0xdb, 0x5c, 0x69, 0x43, 0xee, 0x18, 0xf2, 0xdd, 0x99, 0x8d, 0xa1, - 0xf7, 0x6e, 0x2b, 0xb2, 0x18, 0x29, 0x85, 0x4e, 0x21, 0x13, 0xe5, 0x92, 0x49, 0x7b, 0x3a, 0xe0, - 0x26, 0x66, 0x7f, 0x08, 0x38, 0x57, 0x22, 0xdb, 0x1c, 0xe6, 0x79, 0x04, 0x5d, 0x33, 0xaf, 0x95, - 0x58, 0x1d, 0xe8, 0x1b, 0xe8, 0x45, 0xa6, 0x86, 0x91, 0xe6, 0xcc, 0x27, 0x5e, 0x93, 0x3f, 0x5e, - 0xd5, 0x8b, 0x5b, 0x3c, 0x7d, 0x0b, 0x7d, 0xa5, 0xa5, 0xd0, 0x18, 0xdf, 0x1a, 0x65, 0x0f, 0xe6, - 0xac, 0x99, 0x1b, 0x58, 0x24, 0xbf, 0xe3, 0x30, 0x06, 0xc3, 0x4a, 0x9e, 0x35, 0x91, 0x42, 0x47, - 0xed, 0x93, 0x8d, 0x95, 0x67, 0x62, 0x76, 0x01, 0x5d, 0x5f, 0xca, 0x5c, 0x1e, 0x79, 0x0c, 0x84, - 0xc7, 0xeb, 0x4c, 0x62, 0x94, 0xc7, 0x59, 0xf2, 0x0b, 0x37, 0xd7, 0x65, 0xdb, 0x8a, 0xf3, 0x1a, - 0xba, 0x58, 0x06, 0x86, 0xe1, 0xcc, 0x9f, 0x34, 0xab, 0x33, 0x78, 0x5e, 0xa1, 0xef, 0x7d, 0x6a, - 0xd5, 0x7c, 0x7a, 0xb1, 0x80, 0xfe, 0x61, 0x06, 0xea, 0xc0, 0xe9, 0x7b, 0xff, 0xc3, 0x62, 0x7d, - 0xf5, 0x65, 0x74, 0x42, 0x01, 0x7a, 0xdc, 0x5f, 0x2e, 0x02, 0x7f, 0x44, 0xe8, 0x43, 0x38, 0x0b, - 0xae, 0xd7, 0x8b, 0xe0, 0xe3, 0x8d, 0x4d, 0xb5, 0xe8, 0x00, 0xba, 0x9f, 0x7c, 0x7e, 0xe9, 0x8f, - 0xda, 0xf3, 0xbf, 0x04, 0x68, 0x60, 0xba, 0x1b, 0x91, 0x97, 0x55, 0x73, 0xfa, 0x15, 0x3a, 0xe5, - 0x32, 0xd1, 0xa7, 0xcd, 0xfa, 0x6a, 0x6b, 0x79, 0xfe, 0xec, 0x7f, 0xb0, 0xca, 0x4e, 0x76, 0x52, - 0x16, 0x2e, 0x0d, 0x3e, 0x56, 0xb8, 0xb6, 0x1f, 0xc7, 0x0a, 0xd7, 0xdf, 0x89, 0x9d, 0x2c, 0xbf, - 0xc3, 0x38, 0xca, 0xd3, 0x46, 0xf8, 0x72, 0x68, 0x47, 0x5b, 0x95, 0x1f, 0x6e, 0x45, 0xbe, 0xbd, - 0x8c, 0x13, 0xbd, 0x2d, 0x42, 0x2f, 0xca, 0xd3, 0x59, 0x49, 0x9a, 0xd5, 0x48, 0x33, 0x4b, 0x9a, - 0x99, 0xdf, 0xb9, 0x0b, 0xc3, 0x9e, 0x09, 0x5e, 0xfd, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x8e, 0x7d, - 0xf5, 0x79, 0xb7, 0x03, 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0xe1, 0x6b, 0xd3, 0x40, + 0x14, 0x6f, 0x92, 0x36, 0x6b, 0x5f, 0xda, 0x51, 0x8f, 0x31, 0xc2, 0x98, 0xd8, 0x9d, 0xe8, 0x8a, + 0x42, 0x0a, 0x15, 0x65, 0x28, 0x08, 0x9d, 0x66, 0xf3, 0xc3, 0x36, 0xb6, 0xc4, 0x21, 0x28, 0x32, + 0xae, 0xed, 0x91, 0x05, 0x97, 0xa4, 0xcd, 0x5d, 0x26, 0xf5, 0xbb, 0x7f, 0x86, 0x1f, 0xfd, 0x9f, + 0xfc, 0x73, 0x24, 0x77, 0x97, 0x36, 0x82, 0xe9, 0x04, 0xbf, 0xdd, 0x7b, 0xf9, 0xfd, 0xde, 0xfb, + 0xbd, 0x7b, 0xbf, 0x0b, 0x74, 0x02, 0xc2, 0xe9, 0x57, 0xb2, 0x70, 0x66, 0x69, 0xc2, 0x13, 0x64, + 0x67, 0x63, 0x9a, 0x3a, 0x2c, 0x1b, 0x47, 0x21, 0x9f, 0x67, 0x34, 0xa3, 0x8e, 0xfa, 0x8e, 0xf7, + 0xc1, 0x3a, 0x0f, 0xe3, 0xc0, 0xa3, 0xf3, 0x8c, 0x32, 0x8e, 0x6c, 0xd8, 0x88, 0x28, 0x63, 0x24, + 0xa0, 0xb6, 0xd6, 0xd3, 0xfa, 0x2d, 0xaf, 0x08, 0xf1, 0x77, 0x0d, 0xda, 0x12, 0xc9, 0x66, 0x49, + 0xcc, 0x68, 0x35, 0x14, 0xed, 0x41, 0x9b, 0xd1, 0xf4, 0x36, 0x9c, 0xd0, 0xab, 0x98, 0x44, 0xd4, + 0xd6, 0xc5, 0x67, 0x4b, 0xe5, 0xce, 0x48, 0x44, 0xd1, 0x2e, 0xb4, 0x78, 0x18, 0x51, 0xc6, 0x49, + 0x34, 0xb3, 0x8d, 0x9e, 0xd6, 0x37, 0xbc, 0x55, 0x02, 0xed, 0x40, 0xf3, 0x3a, 0x61, 0x5c, 0x90, + 0xeb, 0x82, 0xbc, 0x8c, 0xf1, 0x2e, 0x98, 0x6f, 0xae, 0x49, 0x1c, 0x50, 0x84, 0xa0, 0x9e, 0xa5, + 0x21, 0xb3, 0xb5, 0x9e, 0xd1, 0x6f, 0x79, 0xe2, 0x8c, 0x7f, 0x68, 0x60, 0x9d, 0x90, 0x78, 0x5a, + 0xcc, 0xb3, 0x05, 0x0d, 0x31, 0xaf, 0x92, 0x28, 0x03, 0x74, 0x00, 0xe6, 0x44, 0xd4, 0x10, 0xd2, + 0xac, 0x61, 0xcf, 0xa9, 0xba, 0x1f, 0x47, 0xf6, 0xf2, 0x14, 0x1e, 0xbd, 0x86, 0x26, 0xe3, 0x29, + 0xe1, 0x34, 0x58, 0x08, 0x65, 0x9b, 0x43, 0x5c, 0xcd, 0xf5, 0x15, 0xd2, 0x5b, 0x72, 0x30, 0x86, + 0xb6, 0x94, 0xa7, 0x2e, 0x11, 0x41, 0x9d, 0xcd, 0xc3, 0xa9, 0x92, 0x27, 0xce, 0xf8, 0x21, 0x74, + 0x7c, 0x4e, 0x78, 0xc6, 0x8a, 0x21, 0xfe, 0x06, 0xfa, 0xa5, 0xc1, 0x66, 0x81, 0x52, 0xb5, 0xb6, + 0xc1, 0x64, 0x22, 0xa3, 0x80, 0x2a, 0x42, 0xf7, 0x01, 0x6e, 0x08, 0xe3, 0x57, 0x34, 0x4d, 0x93, + 0x54, 0x2d, 0xa3, 0x95, 0x67, 0xdc, 0x3c, 0x81, 0x3c, 0x68, 0x46, 0x94, 0x93, 0x29, 0xe1, 0xc4, + 0x36, 0x7a, 0x46, 0xdf, 0x1a, 0xbe, 0x58, 0x37, 0x52, 0xb9, 0xa5, 0x73, 0xaa, 0x88, 0x6e, 0xcc, + 0xd3, 0x85, 0xb7, 0xac, 0xb3, 0xf3, 0x0a, 0x3a, 0x7f, 0x7c, 0x42, 0x5d, 0x30, 0xbe, 0xd0, 0x85, + 0x12, 0x96, 0x1f, 0xf3, 0xcd, 0xdc, 0x92, 0x9b, 0xac, 0x70, 0x87, 0x0c, 0x5e, 0xea, 0x07, 0x1a, + 0xde, 0x83, 0x86, 0x54, 0x56, 0x6d, 0x46, 0x0a, 0xdb, 0x97, 0x71, 0x4a, 0x27, 0x49, 0x10, 0x87, + 0xdf, 0xe8, 0xf4, 0x22, 0xd7, 0x28, 0x39, 0xcf, 0xa1, 0x21, 0xe7, 0xd4, 0xc4, 0x66, 0x1f, 0x54, + 0x8f, 0x22, 0xf0, 0x9e, 0x44, 0xaf, 0x7c, 0xa2, 0x97, 0x7c, 0x82, 0x09, 0x6c, 0xa9, 0x1d, 0x9c, + 0x25, 0xfc, 0x28, 0xc9, 0xe2, 0xe9, 0x7f, 0x35, 0x29, 0xf6, 0xa8, 0xaf, 0xf6, 0xf8, 0x64, 0x04, + 0xcd, 0xc2, 0x26, 0xc8, 0x82, 0x8d, 0xb7, 0xee, 0xd1, 0xe8, 0xf2, 0xe4, 0x7d, 0xb7, 0x86, 0x00, + 0x4c, 0xcf, 0x3d, 0x1c, 0xf9, 0x6e, 0x57, 0x43, 0xf7, 0xa0, 0xe3, 0x5f, 0x5c, 0x8e, 0xfc, 0x77, + 0x57, 0x2a, 0xa5, 0xa3, 0x16, 0x34, 0x4e, 0x5d, 0xef, 0xd8, 0xed, 0x1a, 0xc3, 0x9f, 0x3a, 0x20, + 0x5f, 0xf4, 0x16, 0xf7, 0x70, 0x2c, 0x5b, 0xa3, 0x0f, 0x50, 0xcf, 0xdf, 0x2b, 0x7a, 0x54, 0xad, + 0xae, 0xf4, 0xf2, 0x77, 0x1e, 0xdf, 0x05, 0x93, 0x2b, 0xc7, 0xb5, 0xbc, 0x70, 0xee, 0xe1, 0x75, + 0x85, 0x4b, 0x4f, 0x70, 0x5d, 0xe1, 0xf2, 0x53, 0xc0, 0x35, 0xf4, 0x19, 0x4c, 0xe9, 0x2f, 0xb4, + 0x7f, 0xb7, 0x03, 0x65, 0xf1, 0xfe, 0xbf, 0x5a, 0x15, 0xd7, 0x0e, 0x3f, 0xc1, 0xee, 0x24, 0x89, + 0x2a, 0x09, 0x87, 0x6d, 0x75, 0x73, 0xe7, 0xf9, 0x2f, 0xf3, 0x5c, 0xfb, 0xf8, 0x34, 0x08, 0xf9, + 0x75, 0x36, 0x76, 0x26, 0x49, 0x34, 0xc8, 0x49, 0x83, 0x12, 0x69, 0xa0, 0x48, 0x03, 0xf1, 0x7f, + 0x9d, 0x8d, 0xc7, 0xa6, 0x38, 0x3c, 0xfb, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xe4, 0xd1, 0x9a, 0x74, + 0x79, 0x05, 0x00, 0x00, }, } diff --git a/gateway/protopb/gateway_grpc.pb.go b/gateway/protopb/gateway_grpc.pb.go index 6ab82364..5e2cb594 100644 --- a/gateway/protopb/gateway_grpc.pb.go +++ b/gateway/protopb/gateway_grpc.pb.go @@ -1,3 +1,17 @@ +// Copyright (c) 2025 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.5.1 @@ -20,8 +34,9 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - SubmitQueueGateway_Ping_FullMethodName = "/uber.submitqueue.gateway.SubmitQueueGateway/Ping" - SubmitQueueGateway_Land_FullMethodName = "/uber.submitqueue.gateway.SubmitQueueGateway/Land" + SubmitQueueGateway_Ping_FullMethodName = "/uber.submitqueue.gateway.SubmitQueueGateway/Ping" + SubmitQueueGateway_Land_FullMethodName = "/uber.submitqueue.gateway.SubmitQueueGateway/Land" + SubmitQueueGateway_Status_FullMethodName = "/uber.submitqueue.gateway.SubmitQueueGateway/Status" ) // SubmitQueueGatewayClient is the client API for SubmitQueueGateway service. @@ -35,6 +50,9 @@ type SubmitQueueGatewayClient interface { // Land lands a set of code changes into a target branch, performing the necessary validations across all other changes in the queue. // The processing is asynchronous and returns a LandResponse immediately. The land request is processed in the background. Land(ctx context.Context, in *LandRequest, opts ...grpc.CallOption) (*LandResponse, error) + // Status returns the current status of a previously submitted request, identified by its sqid. + // The status is eventually consistent with the request store and reconciled from the append-only request log. + Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) } type submitQueueGatewayClient struct { @@ -65,6 +83,16 @@ func (c *submitQueueGatewayClient) Land(ctx context.Context, in *LandRequest, op return out, nil } +func (c *submitQueueGatewayClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(StatusResponse) + err := c.cc.Invoke(ctx, SubmitQueueGateway_Status_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // SubmitQueueGatewayServer is the server API for SubmitQueueGateway service. // All implementations must embed UnimplementedSubmitQueueGatewayServer // for forward compatibility. @@ -76,6 +104,9 @@ type SubmitQueueGatewayServer interface { // Land lands a set of code changes into a target branch, performing the necessary validations across all other changes in the queue. // The processing is asynchronous and returns a LandResponse immediately. The land request is processed in the background. Land(context.Context, *LandRequest) (*LandResponse, error) + // Status returns the current status of a previously submitted request, identified by its sqid. + // The status is eventually consistent with the request store and reconciled from the append-only request log. + Status(context.Context, *StatusRequest) (*StatusResponse, error) mustEmbedUnimplementedSubmitQueueGatewayServer() } @@ -92,6 +123,9 @@ func (UnimplementedSubmitQueueGatewayServer) Ping(context.Context, *PingRequest) func (UnimplementedSubmitQueueGatewayServer) Land(context.Context, *LandRequest) (*LandResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Land not implemented") } +func (UnimplementedSubmitQueueGatewayServer) Status(context.Context, *StatusRequest) (*StatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Status not implemented") +} func (UnimplementedSubmitQueueGatewayServer) mustEmbedUnimplementedSubmitQueueGatewayServer() {} func (UnimplementedSubmitQueueGatewayServer) testEmbeddedByValue() {} @@ -149,6 +183,24 @@ func _SubmitQueueGateway_Land_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _SubmitQueueGateway_Status_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SubmitQueueGatewayServer).Status(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SubmitQueueGateway_Status_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SubmitQueueGatewayServer).Status(ctx, req.(*StatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + // SubmitQueueGateway_ServiceDesc is the grpc.ServiceDesc for SubmitQueueGateway service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -164,6 +216,10 @@ var SubmitQueueGateway_ServiceDesc = grpc.ServiceDesc{ MethodName: "Land", Handler: _SubmitQueueGateway_Land_Handler, }, + { + MethodName: "Status", + Handler: _SubmitQueueGateway_Status_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "gateway.proto",