From ed19fa2d7d70e48d95ab4da2d59cbbfefed23549 Mon Sep 17 00:00:00 2001 From: Jack Kleeman Date: Sat, 6 Jul 2024 11:00:58 +0100 Subject: [PATCH 01/13] Update to restate 1.0 --- README.md | 2 - proto/buf.yaml => buf.yaml | 2 - descriptor.binpb | Bin 99760 -> 0 bytes example/checkout.go | 6 +- example/ticket_service.go | 18 +- example/user_session.go | 32 +- generate.go | 1 - generated/proto/discovery/discovery.pb.go | 288 +-- generated/proto/dynrpc/dynrpc.pb.go | 362 ---- generated/proto/javascript/javascript.pb.go | 263 +-- generated/proto/protocol/protocol.pb.go | 1915 ++++++++++++++----- generated/proto/services/services.pb.go | 1151 ----------- go.mod | 9 +- go.sum | 8 +- handler.go | 58 +- internal/discovery.go | 57 + internal/dynrpc.binbp | Bin 78311 -> 0 bytes internal/dynrpc.go | 109 -- internal/dynrpc_test.go | 23 - internal/state/call.go | 93 +- internal/state/state.go | 68 +- internal/state/sys.go | 78 +- internal/wire/wire.go | 88 +- proto/buf.lock | 8 - proto/discovery/discovery.proto | 54 +- proto/dynrpc/dynrpc.proto | 47 - proto/javascript/javascript.proto | 14 - proto/protocol/protocol.proto | 250 ++- proto/services/services.proto | 186 -- router.go | 167 +- server/restate.go | 169 +- 31 files changed, 2218 insertions(+), 3308 deletions(-) rename proto/buf.yaml => buf.yaml (64%) delete mode 100644 descriptor.binpb delete mode 100644 generated/proto/dynrpc/dynrpc.pb.go delete mode 100644 generated/proto/services/services.pb.go create mode 100644 internal/discovery.go delete mode 100644 internal/dynrpc.binbp delete mode 100644 internal/dynrpc.go delete mode 100644 internal/dynrpc_test.go delete mode 100644 proto/buf.lock delete mode 100644 proto/dynrpc/dynrpc.proto delete mode 100644 proto/services/services.proto diff --git a/README.md b/README.md index dcee3b4..2e0c1dc 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ [![Go Reference](https://pkg.go.dev/badge/github.com/restatedev/sdk-go.svg)](https://pkg.go.dev/github.com/restatedev/sdk-go) [![Go](https://github.com/restatedev/sdk-go/actions/workflows/test.yaml/badge.svg)](https://github.com/restatedev/sdk-go/actions/workflows/test.yaml) -> This only works with Restate version 0.8 - # Restate Go SDK [Restate](https://restate.dev/) is a system for easily building resilient applications using *distributed durable async/await*. This repository contains the Restate SDK for writing services in **Golang**. diff --git a/proto/buf.yaml b/buf.yaml similarity index 64% rename from proto/buf.yaml rename to buf.yaml index 9f6773a..1a51945 100644 --- a/proto/buf.yaml +++ b/buf.yaml @@ -1,6 +1,4 @@ version: v1 -deps: - - buf.build/restatedev/proto breaking: use: - FILE diff --git a/descriptor.binpb b/descriptor.binpb deleted file mode 100644 index 19b01b969c781ae5eac014a059b82ca288fa5b97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 99760 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 F{~x>C4HW<Y diff --git a/example/checkout.go b/example/checkout.go index 784a898..5d18d5d 100644 --- a/example/checkout.go +++ b/example/checkout.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/google/uuid" - "github.com/restatedev/sdk-go" + restate "github.com/restatedev/sdk-go" "github.com/rs/zerolog/log" ) @@ -58,6 +58,6 @@ func payment(ctx restate.Context, request PaymentRequest) (response PaymentRespo } var ( - Checkout = restate.NewUnKeyedRouter(). - Handler("checkout", restate.NewUnKeyedHandler(payment)) + Checkout = restate.NewServiceRouter(). + Handler("checkout", restate.NewServiceHandler(payment)) ) diff --git a/example/ticket_service.go b/example/ticket_service.go index 4f10a14..15db39a 100644 --- a/example/ticket_service.go +++ b/example/ticket_service.go @@ -3,7 +3,7 @@ package main import ( "errors" - "github.com/restatedev/sdk-go" + restate "github.com/restatedev/sdk-go" "github.com/rs/zerolog/log" ) @@ -15,7 +15,7 @@ const ( TicketSold TicketStatus = 2 ) -func reserve(ctx restate.Context, ticketId string, _ restate.Void) (bool, error) { +func reserve(ctx restate.ObjectContext, _ restate.Void) (bool, error) { status, err := restate.GetAs[TicketStatus](ctx, "status") if err != nil && !errors.Is(err, restate.ErrKeyNotFound) { return false, err @@ -28,7 +28,8 @@ func reserve(ctx restate.Context, ticketId string, _ restate.Void) (bool, error) return false, nil } -func unreserve(ctx restate.Context, ticketId string, _ restate.Void) (void restate.Void, err error) { +func unreserve(ctx restate.ObjectContext, _ restate.Void) (void restate.Void, err error) { + ticketId := ctx.Key() log.Info().Str("ticket", ticketId).Msg("un-reserving ticket") status, err := restate.GetAs[TicketStatus](ctx, "status") if err != nil && !errors.Is(err, restate.ErrKeyNotFound) { @@ -42,7 +43,8 @@ func unreserve(ctx restate.Context, ticketId string, _ restate.Void) (void resta return void, nil } -func markAsSold(ctx restate.Context, ticketId string, _ restate.Void) (void restate.Void, err error) { +func markAsSold(ctx restate.ObjectContext, _ restate.Void) (void restate.Void, err error) { + ticketId := ctx.Key() log.Info().Str("ticket", ticketId).Msg("mark ticket as sold") status, err := restate.GetAs[TicketStatus](ctx, "status") @@ -58,8 +60,8 @@ func markAsSold(ctx restate.Context, ticketId string, _ restate.Void) (void rest } var ( - TicketService = restate.NewKeyedRouter(). - Handler("reserve", restate.NewKeyedHandler(reserve)). - Handler("unreserve", restate.NewKeyedHandler(unreserve)). - Handler("markAsSold", restate.NewKeyedHandler(markAsSold)) + TicketService = restate.NewObjectRouter(). + Handler("reserve", restate.NewObjectHandler(reserve)). + Handler("unreserve", restate.NewObjectHandler(unreserve)). + Handler("markAsSold", restate.NewObjectHandler(markAsSold)) ) diff --git a/example/user_session.go b/example/user_session.go index b20a002..cffe2d7 100644 --- a/example/user_session.go +++ b/example/user_session.go @@ -5,14 +5,15 @@ import ( "slices" "time" - "github.com/restatedev/sdk-go" + restate "github.com/restatedev/sdk-go" "github.com/rs/zerolog/log" ) -func addTicket(ctx restate.Context, userId, ticketId string) (bool, error) { +func addTicket(ctx restate.ObjectContext, ticketId string) (bool, error) { + userId := ctx.Key() var success bool - if err := ctx.Service(TicketServiceName).Method("reserve").Do(ticketId, userId, &success); err != nil { + if err := ctx.Object(TicketServiceName, ticketId).Method("reserve").Do(userId, &success); err != nil { return false, err } @@ -33,14 +34,14 @@ func addTicket(ctx restate.Context, userId, ticketId string) (bool, error) { return false, err } - if err := ctx.Service(UserSessionServiceName).Method("expireTicket").Send(userId, ticketId, 15*time.Minute); err != nil { + if err := ctx.Object(UserSessionServiceName, ticketId).Method("expireTicket").Send(ticketId, 15*time.Minute); err != nil { return false, err } return true, nil } -func expireTicket(ctx restate.Context, _, ticketId string) (void restate.Void, err error) { +func expireTicket(ctx restate.ObjectContext, ticketId string) (void restate.Void, err error) { tickets, err := restate.GetAs[[]string](ctx, "tickets") if err != nil && !errors.Is(err, restate.ErrKeyNotFound) { return void, err @@ -62,10 +63,11 @@ func expireTicket(ctx restate.Context, _, ticketId string) (void restate.Void, e return void, err } - return void, ctx.Service(TicketServiceName).Method("unreserve").Send(ticketId, nil, 0) + return void, ctx.Object(TicketServiceName, ticketId).Method("unreserve").Send(nil, 0) } -func checkout(ctx restate.Context, userId string, _ restate.Void) (bool, error) { +func checkout(ctx restate.ObjectContext, _ restate.Void) (bool, error) { + userId := ctx.Key() tickets, err := restate.GetAs[[]string](ctx, "tickets") if err != nil && !errors.Is(err, restate.ErrKeyNotFound) { return false, err @@ -78,17 +80,17 @@ func checkout(ctx restate.Context, userId string, _ restate.Void) (bool, error) } var response PaymentResponse - if err := ctx.Service(CheckoutServiceName). + if err := ctx.Object(CheckoutServiceName, ""). Method("checkout"). - Do("", PaymentRequest{UserID: userId, Tickets: tickets}, &response); err != nil { + Do(PaymentRequest{UserID: userId, Tickets: tickets}, &response); err != nil { return false, err } log.Info().Str("id", response.ID).Int("price", response.Price).Msg("payment details") - call := ctx.Service(TicketServiceName).Method("markAsSold") for _, ticket := range tickets { - if err := call.Send(ticket, nil, 0); err != nil { + call := ctx.Object(ticket, TicketServiceName).Method("markAsSold") + if err := call.Send(nil, 0); err != nil { return false, err } } @@ -97,8 +99,8 @@ func checkout(ctx restate.Context, userId string, _ restate.Void) (bool, error) } var ( - UserSession = restate.NewKeyedRouter(). - Handler("addTicket", restate.NewKeyedHandler(addTicket)). - Handler("expireTicket", restate.NewKeyedHandler(expireTicket)). - Handler("checkout", restate.NewKeyedHandler(checkout)) + UserSession = restate.NewObjectRouter(). + Handler("addTicket", restate.NewObjectHandler(addTicket)). + Handler("expireTicket", restate.NewObjectHandler(expireTicket)). + Handler("checkout", restate.NewObjectHandler(checkout)) ) diff --git a/generate.go b/generate.go index 9b71019..49ec25d 100644 --- a/generate.go +++ b/generate.go @@ -1,4 +1,3 @@ package restate //go:generate buf generate -//go:generate buf build --as-file-descriptor-set -o internal/dynrpc.binbp proto/dynrpc/dynrpc.proto diff --git a/generated/proto/discovery/discovery.pb.go b/generated/proto/discovery/discovery.pb.go index 78c496a..ffcf939 100644 --- a/generated/proto/discovery/discovery.pb.go +++ b/generated/proto/discovery/discovery.pb.go @@ -1,16 +1,15 @@ +// Copyright (c) 2024 - Restate Software, Inc., Restate GmbH // -// Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH -// -// This file is part of the Restate SDK for Node.js/TypeScript, -// which is released under the MIT license. +// This file is part of the Restate service protocol, which is +// released under the MIT license. // // You can find a copy of the license in file LICENSE in the root // directory of this repository or package, or at -// https://github.com/restatedev/sdk-typescript/blob/main/LICENSE +// https://github.com/restatedev/service-protocol/blob/main/LICENSE // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 +// protoc-gen-go v1.26.0 // protoc (unknown) // source: proto/discovery/discovery.proto @@ -19,7 +18,6 @@ package discovery import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - descriptorpb "google.golang.org/protobuf/types/descriptorpb" reflect "reflect" sync "sync" ) @@ -31,176 +29,54 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type ProtocolMode int32 +// Service discovery protocol version. +type ServiceDiscoveryProtocolVersion int32 const ( - // protolint:disable:next ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH - ProtocolMode_BIDI_STREAM ProtocolMode = 0 - ProtocolMode_REQUEST_RESPONSE ProtocolMode = 1 + ServiceDiscoveryProtocolVersion_SERVICE_DISCOVERY_PROTOCOL_VERSION_UNSPECIFIED ServiceDiscoveryProtocolVersion = 0 + // initial service discovery protocol version using endpoint_manifest_schema.json + ServiceDiscoveryProtocolVersion_V1 ServiceDiscoveryProtocolVersion = 1 ) -// Enum value maps for ProtocolMode. +// Enum value maps for ServiceDiscoveryProtocolVersion. var ( - ProtocolMode_name = map[int32]string{ - 0: "BIDI_STREAM", - 1: "REQUEST_RESPONSE", + ServiceDiscoveryProtocolVersion_name = map[int32]string{ + 0: "SERVICE_DISCOVERY_PROTOCOL_VERSION_UNSPECIFIED", + 1: "V1", } - ProtocolMode_value = map[string]int32{ - "BIDI_STREAM": 0, - "REQUEST_RESPONSE": 1, + ServiceDiscoveryProtocolVersion_value = map[string]int32{ + "SERVICE_DISCOVERY_PROTOCOL_VERSION_UNSPECIFIED": 0, + "V1": 1, } ) -func (x ProtocolMode) Enum() *ProtocolMode { - p := new(ProtocolMode) +func (x ServiceDiscoveryProtocolVersion) Enum() *ServiceDiscoveryProtocolVersion { + p := new(ServiceDiscoveryProtocolVersion) *p = x return p } -func (x ProtocolMode) String() string { +func (x ServiceDiscoveryProtocolVersion) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (ProtocolMode) Descriptor() protoreflect.EnumDescriptor { +func (ServiceDiscoveryProtocolVersion) Descriptor() protoreflect.EnumDescriptor { return file_proto_discovery_discovery_proto_enumTypes[0].Descriptor() } -func (ProtocolMode) Type() protoreflect.EnumType { +func (ServiceDiscoveryProtocolVersion) Type() protoreflect.EnumType { return &file_proto_discovery_discovery_proto_enumTypes[0] } -func (x ProtocolMode) Number() protoreflect.EnumNumber { +func (x ServiceDiscoveryProtocolVersion) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } -// Deprecated: Use ProtocolMode.Descriptor instead. -func (ProtocolMode) EnumDescriptor() ([]byte, []int) { +// Deprecated: Use ServiceDiscoveryProtocolVersion.Descriptor instead. +func (ServiceDiscoveryProtocolVersion) EnumDescriptor() ([]byte, []int) { return file_proto_discovery_discovery_proto_rawDescGZIP(), []int{0} } -type ServiceDiscoveryRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *ServiceDiscoveryRequest) Reset() { - *x = ServiceDiscoveryRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_discovery_discovery_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ServiceDiscoveryRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ServiceDiscoveryRequest) ProtoMessage() {} - -func (x *ServiceDiscoveryRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_discovery_discovery_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ServiceDiscoveryRequest.ProtoReflect.Descriptor instead. -func (*ServiceDiscoveryRequest) Descriptor() ([]byte, []int) { - return file_proto_discovery_discovery_proto_rawDescGZIP(), []int{0} -} - -type ServiceDiscoveryResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // List of all proto files used to define the services, including the - // dependencies. - Files *descriptorpb.FileDescriptorSet `protobuf:"bytes,1,opt,name=files,proto3" json:"files,omitempty"` - // List of services to register. This might be a subset of services defined in - // files. - Services []string `protobuf:"bytes,2,rep,name=services,proto3" json:"services,omitempty"` - // Service-protocol version negotiation - MinProtocolVersion uint32 `protobuf:"varint,3,opt,name=min_protocol_version,json=minProtocolVersion,proto3" json:"min_protocol_version,omitempty"` - MaxProtocolVersion uint32 `protobuf:"varint,4,opt,name=max_protocol_version,json=maxProtocolVersion,proto3" json:"max_protocol_version,omitempty"` - // Protocol mode negotiation - ProtocolMode ProtocolMode `protobuf:"varint,5,opt,name=protocol_mode,json=protocolMode,proto3,enum=dev.restate.service.discovery.ProtocolMode" json:"protocol_mode,omitempty"` -} - -func (x *ServiceDiscoveryResponse) Reset() { - *x = ServiceDiscoveryResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_discovery_discovery_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ServiceDiscoveryResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ServiceDiscoveryResponse) ProtoMessage() {} - -func (x *ServiceDiscoveryResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_discovery_discovery_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ServiceDiscoveryResponse.ProtoReflect.Descriptor instead. -func (*ServiceDiscoveryResponse) Descriptor() ([]byte, []int) { - return file_proto_discovery_discovery_proto_rawDescGZIP(), []int{1} -} - -func (x *ServiceDiscoveryResponse) GetFiles() *descriptorpb.FileDescriptorSet { - if x != nil { - return x.Files - } - return nil -} - -func (x *ServiceDiscoveryResponse) GetServices() []string { - if x != nil { - return x.Services - } - return nil -} - -func (x *ServiceDiscoveryResponse) GetMinProtocolVersion() uint32 { - if x != nil { - return x.MinProtocolVersion - } - return 0 -} - -func (x *ServiceDiscoveryResponse) GetMaxProtocolVersion() uint32 { - if x != nil { - return x.MaxProtocolVersion - } - return 0 -} - -func (x *ServiceDiscoveryResponse) GetProtocolMode() ProtocolMode { - if x != nil { - return x.ProtocolMode - } - return ProtocolMode_BIDI_STREAM -} - var File_proto_discovery_discovery_proto protoreflect.FileDescriptor var file_proto_discovery_discovery_proto_rawDesc = []byte{ @@ -208,50 +84,29 @@ var file_proto_discovery_discovery_proto_rawDesc = []byte{ 0x79, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, - 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0x19, 0x0a, 0x17, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x69, 0x73, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa6, 0x02, - 0x0a, 0x18, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x05, 0x66, 0x69, - 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, - 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x52, 0x05, 0x66, - 0x69, 0x6c, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x12, 0x30, 0x0a, 0x14, 0x6d, 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, - 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, - 0x6d, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x12, 0x6d, 0x61, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, - 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x64, 0x65, - 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2e, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x4d, 0x6f, 0x64, 0x65, 0x2a, 0x35, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x42, 0x49, 0x44, 0x49, 0x5f, 0x53, - 0x54, 0x52, 0x45, 0x41, 0x4d, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45, 0x51, 0x55, 0x45, - 0x53, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, 0x45, 0x10, 0x01, 0x42, 0x8c, 0x02, - 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x79, 0x42, 0x0e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x6d, 0x75, 0x68, 0x61, 0x6d, 0x61, 0x64, 0x61, 0x7a, 0x6d, 0x79, 0x2f, 0x72, 0x65, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2d, 0x73, 0x64, 0x6b, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x65, 0x6e, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x64, 0x69, 0x73, - 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0xa2, 0x02, 0x04, 0x44, 0x52, 0x53, 0x44, 0xaa, 0x02, 0x1d, - 0x44, 0x65, 0x76, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0xca, 0x02, 0x1d, - 0x44, 0x65, 0x76, 0x5c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x5c, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0xe2, 0x02, 0x29, - 0x44, 0x65, 0x76, 0x5c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x53, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x5c, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x44, 0x65, 0x76, 0x3a, - 0x3a, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x3a, 0x3a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x3a, 0x3a, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x2a, 0x5d, 0x0a, 0x1f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x2e, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x44, + 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, + 0x4c, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x56, 0x31, 0x10, 0x01, 0x42, + 0x83, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x64, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x79, 0x42, 0x0e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x64, 0x65, 0x76, 0x2f, 0x73, + 0x64, 0x6b, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0xa2, + 0x02, 0x04, 0x44, 0x52, 0x53, 0x44, 0xaa, 0x02, 0x1d, 0x44, 0x65, 0x76, 0x2e, 0x52, 0x65, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x44, 0x69, 0x73, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0xca, 0x02, 0x1d, 0x44, 0x65, 0x76, 0x5c, 0x52, 0x65, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x44, 0x69, 0x73, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0xe2, 0x02, 0x29, 0x44, 0x65, 0x76, 0x5c, 0x52, 0x65, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x44, 0x69, 0x73, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0xea, 0x02, 0x20, 0x44, 0x65, 0x76, 0x3a, 0x3a, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x3a, 0x3a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x3a, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -267,21 +122,15 @@ func file_proto_discovery_discovery_proto_rawDescGZIP() []byte { } var file_proto_discovery_discovery_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_proto_discovery_discovery_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_proto_discovery_discovery_proto_goTypes = []interface{}{ - (ProtocolMode)(0), // 0: dev.restate.service.discovery.ProtocolMode - (*ServiceDiscoveryRequest)(nil), // 1: dev.restate.service.discovery.ServiceDiscoveryRequest - (*ServiceDiscoveryResponse)(nil), // 2: dev.restate.service.discovery.ServiceDiscoveryResponse - (*descriptorpb.FileDescriptorSet)(nil), // 3: google.protobuf.FileDescriptorSet + (ServiceDiscoveryProtocolVersion)(0), // 0: dev.restate.service.discovery.ServiceDiscoveryProtocolVersion } var file_proto_discovery_discovery_proto_depIdxs = []int32{ - 3, // 0: dev.restate.service.discovery.ServiceDiscoveryResponse.files:type_name -> google.protobuf.FileDescriptorSet - 0, // 1: dev.restate.service.discovery.ServiceDiscoveryResponse.protocol_mode:type_name -> dev.restate.service.discovery.ProtocolMode - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_proto_discovery_discovery_proto_init() } @@ -289,46 +138,19 @@ func file_proto_discovery_discovery_proto_init() { if File_proto_discovery_discovery_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_proto_discovery_discovery_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ServiceDiscoveryRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_discovery_discovery_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ServiceDiscoveryResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_discovery_discovery_proto_rawDesc, NumEnums: 1, - NumMessages: 2, + NumMessages: 0, NumExtensions: 0, NumServices: 0, }, GoTypes: file_proto_discovery_discovery_proto_goTypes, DependencyIndexes: file_proto_discovery_discovery_proto_depIdxs, EnumInfos: file_proto_discovery_discovery_proto_enumTypes, - MessageInfos: file_proto_discovery_discovery_proto_msgTypes, }.Build() File_proto_discovery_discovery_proto = out.File file_proto_discovery_discovery_proto_rawDesc = nil diff --git a/generated/proto/dynrpc/dynrpc.pb.go b/generated/proto/dynrpc/dynrpc.pb.go deleted file mode 100644 index 5c4a4f6..0000000 --- a/generated/proto/dynrpc/dynrpc.pb.go +++ /dev/null @@ -1,362 +0,0 @@ -// -// Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH -// -// This file is part of the Restate SDK for Node.js/TypeScript, -// which is released under the MIT license. -// -// You can find a copy of the license in file LICENSE in the root -// directory of this repository or package, or at -// https://github.com/restatedev/sdk-typescript/blob/main/LICENSE - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc (unknown) -// source: proto/dynrpc/dynrpc.proto - -package dynrpc - -import ( - _ "github.com/restatedev/sdk-go/generated/dev/restate" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - emptypb "google.golang.org/protobuf/types/known/emptypb" - structpb "google.golang.org/protobuf/types/known/structpb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type KeyedEvent struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"` - Attributes map[string]string `protobuf:"bytes,15,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *KeyedEvent) Reset() { - *x = KeyedEvent{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_dynrpc_dynrpc_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *KeyedEvent) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*KeyedEvent) ProtoMessage() {} - -func (x *KeyedEvent) ProtoReflect() protoreflect.Message { - mi := &file_proto_dynrpc_dynrpc_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use KeyedEvent.ProtoReflect.Descriptor instead. -func (*KeyedEvent) Descriptor() ([]byte, []int) { - return file_proto_dynrpc_dynrpc_proto_rawDescGZIP(), []int{0} -} - -func (x *KeyedEvent) GetKey() string { - if x != nil { - return x.Key - } - return "" -} - -func (x *KeyedEvent) GetPayload() []byte { - if x != nil { - return x.Payload - } - return nil -} - -func (x *KeyedEvent) GetAttributes() map[string]string { - if x != nil { - return x.Attributes - } - return nil -} - -type RpcRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Request *structpb.Value `protobuf:"bytes,2,opt,name=request,proto3" json:"request,omitempty"` - // internal: see src/utils/assumptions.ts - SenderAssumes int32 `protobuf:"varint,101,opt,name=sender_assumes,json=senderAssumes,proto3" json:"sender_assumes,omitempty"` -} - -func (x *RpcRequest) Reset() { - *x = RpcRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_dynrpc_dynrpc_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RpcRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RpcRequest) ProtoMessage() {} - -func (x *RpcRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_dynrpc_dynrpc_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RpcRequest.ProtoReflect.Descriptor instead. -func (*RpcRequest) Descriptor() ([]byte, []int) { - return file_proto_dynrpc_dynrpc_proto_rawDescGZIP(), []int{1} -} - -func (x *RpcRequest) GetKey() string { - if x != nil { - return x.Key - } - return "" -} - -func (x *RpcRequest) GetRequest() *structpb.Value { - if x != nil { - return x.Request - } - return nil -} - -func (x *RpcRequest) GetSenderAssumes() int32 { - if x != nil { - return x.SenderAssumes - } - return 0 -} - -type RpcResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Response *structpb.Value `protobuf:"bytes,1,opt,name=response,proto3" json:"response,omitempty"` -} - -func (x *RpcResponse) Reset() { - *x = RpcResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_dynrpc_dynrpc_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RpcResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RpcResponse) ProtoMessage() {} - -func (x *RpcResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_dynrpc_dynrpc_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RpcResponse.ProtoReflect.Descriptor instead. -func (*RpcResponse) Descriptor() ([]byte, []int) { - return file_proto_dynrpc_dynrpc_proto_rawDescGZIP(), []int{2} -} - -func (x *RpcResponse) GetResponse() *structpb.Value { - if x != nil { - return x.Response - } - return nil -} - -var File_proto_dynrpc_dynrpc_proto protoreflect.FileDescriptor - -var file_proto_dynrpc_dynrpc_proto_rawDesc = []byte{ - 0x0a, 0x19, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x64, 0x79, 0x6e, 0x72, 0x70, 0x63, 0x2f, 0x64, - 0x79, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x64, 0x65, 0x76, - 0x2f, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x65, 0x78, 0x74, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc6, 0x01, - 0x0a, 0x0a, 0x4b, 0x65, 0x79, 0x65, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0x90, 0x82, 0x19, 0x00, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x04, 0x90, 0x82, 0x19, 0x01, 0x52, 0x07, 0x70, 0x61, 0x79, - 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x41, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x4b, 0x65, 0x79, 0x65, 0x64, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x04, 0x90, 0x82, 0x19, 0x02, 0x52, 0x0a, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x7d, 0x0a, 0x0a, 0x52, 0x70, 0x63, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x04, 0x90, 0x82, 0x19, 0x00, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x07, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, - 0x0a, 0x0e, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x73, - 0x18, 0x65, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x41, 0x73, - 0x73, 0x75, 0x6d, 0x65, 0x73, 0x22, 0x41, 0x0a, 0x0b, 0x52, 0x70, 0x63, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x69, 0x0a, 0x0b, 0x52, 0x70, 0x63, 0x45, - 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x12, - 0x0b, 0x2e, 0x52, 0x70, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, 0x2e, 0x52, - 0x70, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x06, - 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x12, 0x0b, 0x2e, 0x4b, 0x65, 0x79, 0x65, 0x64, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x1a, 0x04, 0x90, - 0x82, 0x19, 0x01, 0x32, 0x3f, 0x0a, 0x12, 0x55, 0x6e, 0x6b, 0x65, 0x79, 0x65, 0x64, 0x52, 0x70, - 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x04, 0x63, 0x61, 0x6c, - 0x6c, 0x12, 0x0b, 0x2e, 0x52, 0x70, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0c, - 0x2e, 0x52, 0x70, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x1a, 0x04, - 0x90, 0x82, 0x19, 0x00, 0x42, 0x4d, 0x42, 0x0b, 0x44, 0x79, 0x6e, 0x72, 0x70, 0x63, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x6d, 0x75, 0x68, 0x61, 0x6d, 0x61, 0x64, 0x61, 0x7a, 0x6d, 0x79, 0x2f, 0x72, 0x65, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2d, 0x73, 0x64, 0x6b, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x65, 0x6e, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x64, 0x79, 0x6e, - 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_proto_dynrpc_dynrpc_proto_rawDescOnce sync.Once - file_proto_dynrpc_dynrpc_proto_rawDescData = file_proto_dynrpc_dynrpc_proto_rawDesc -) - -func file_proto_dynrpc_dynrpc_proto_rawDescGZIP() []byte { - file_proto_dynrpc_dynrpc_proto_rawDescOnce.Do(func() { - file_proto_dynrpc_dynrpc_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_dynrpc_dynrpc_proto_rawDescData) - }) - return file_proto_dynrpc_dynrpc_proto_rawDescData -} - -var file_proto_dynrpc_dynrpc_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_proto_dynrpc_dynrpc_proto_goTypes = []interface{}{ - (*KeyedEvent)(nil), // 0: KeyedEvent - (*RpcRequest)(nil), // 1: RpcRequest - (*RpcResponse)(nil), // 2: RpcResponse - nil, // 3: KeyedEvent.AttributesEntry - (*structpb.Value)(nil), // 4: google.protobuf.Value - (*emptypb.Empty)(nil), // 5: google.protobuf.Empty -} -var file_proto_dynrpc_dynrpc_proto_depIdxs = []int32{ - 3, // 0: KeyedEvent.attributes:type_name -> KeyedEvent.AttributesEntry - 4, // 1: RpcRequest.request:type_name -> google.protobuf.Value - 4, // 2: RpcResponse.response:type_name -> google.protobuf.Value - 1, // 3: RpcEndpoint.call:input_type -> RpcRequest - 0, // 4: RpcEndpoint.handle:input_type -> KeyedEvent - 1, // 5: UnkeyedRpcEndpoint.call:input_type -> RpcRequest - 2, // 6: RpcEndpoint.call:output_type -> RpcResponse - 5, // 7: RpcEndpoint.handle:output_type -> google.protobuf.Empty - 2, // 8: UnkeyedRpcEndpoint.call:output_type -> RpcResponse - 6, // [6:9] is the sub-list for method output_type - 3, // [3:6] 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 -} - -func init() { file_proto_dynrpc_dynrpc_proto_init() } -func file_proto_dynrpc_dynrpc_proto_init() { - if File_proto_dynrpc_dynrpc_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_dynrpc_dynrpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KeyedEvent); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_dynrpc_dynrpc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RpcRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_dynrpc_dynrpc_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RpcResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_dynrpc_dynrpc_proto_rawDesc, - NumEnums: 0, - NumMessages: 4, - NumExtensions: 0, - NumServices: 2, - }, - GoTypes: file_proto_dynrpc_dynrpc_proto_goTypes, - DependencyIndexes: file_proto_dynrpc_dynrpc_proto_depIdxs, - MessageInfos: file_proto_dynrpc_dynrpc_proto_msgTypes, - }.Build() - File_proto_dynrpc_dynrpc_proto = out.File - file_proto_dynrpc_dynrpc_proto_rawDesc = nil - file_proto_dynrpc_dynrpc_proto_goTypes = nil - file_proto_dynrpc_dynrpc_proto_depIdxs = nil -} diff --git a/generated/proto/javascript/javascript.pb.go b/generated/proto/javascript/javascript.pb.go index 1cb551c..114ee38 100644 --- a/generated/proto/javascript/javascript.pb.go +++ b/generated/proto/javascript/javascript.pb.go @@ -10,14 +10,14 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 +// protoc-gen-go v1.26.0 // protoc (unknown) // source: proto/javascript/javascript.proto package javascript import ( - protocol "github.com/restatedev/sdk-go/generated/proto/protocol" + _ "github.com/restatedev/sdk-go/generated/proto/protocol" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -31,144 +31,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type FailureWithTerminal struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Failure *protocol.Failure `protobuf:"bytes,1,opt,name=failure,proto3" json:"failure,omitempty"` - Terminal bool `protobuf:"varint,2,opt,name=terminal,proto3" json:"terminal,omitempty"` -} - -func (x *FailureWithTerminal) Reset() { - *x = FailureWithTerminal{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_javascript_javascript_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *FailureWithTerminal) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*FailureWithTerminal) ProtoMessage() {} - -func (x *FailureWithTerminal) ProtoReflect() protoreflect.Message { - mi := &file_proto_javascript_javascript_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use FailureWithTerminal.ProtoReflect.Descriptor instead. -func (*FailureWithTerminal) Descriptor() ([]byte, []int) { - return file_proto_javascript_javascript_proto_rawDescGZIP(), []int{0} -} - -func (x *FailureWithTerminal) GetFailure() *protocol.Failure { - if x != nil { - return x.Failure - } - return nil -} - -func (x *FailureWithTerminal) GetTerminal() bool { - if x != nil { - return x.Terminal - } - return false -} - -// Type: 0xFC00 + 1 -// Flag: RequiresRuntimeAck -type SideEffectEntryMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Result: - // - // *SideEffectEntryMessage_Value - // *SideEffectEntryMessage_Failure - Result isSideEffectEntryMessage_Result `protobuf_oneof:"result"` -} - -func (x *SideEffectEntryMessage) Reset() { - *x = SideEffectEntryMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_javascript_javascript_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SideEffectEntryMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SideEffectEntryMessage) ProtoMessage() {} - -func (x *SideEffectEntryMessage) ProtoReflect() protoreflect.Message { - mi := &file_proto_javascript_javascript_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SideEffectEntryMessage.ProtoReflect.Descriptor instead. -func (*SideEffectEntryMessage) Descriptor() ([]byte, []int) { - return file_proto_javascript_javascript_proto_rawDescGZIP(), []int{1} -} - -func (m *SideEffectEntryMessage) GetResult() isSideEffectEntryMessage_Result { - if m != nil { - return m.Result - } - return nil -} - -func (x *SideEffectEntryMessage) GetValue() []byte { - if x, ok := x.GetResult().(*SideEffectEntryMessage_Value); ok { - return x.Value - } - return nil -} - -func (x *SideEffectEntryMessage) GetFailure() *FailureWithTerminal { - if x, ok := x.GetResult().(*SideEffectEntryMessage_Failure); ok { - return x.Failure - } - return nil -} - -type isSideEffectEntryMessage_Result interface { - isSideEffectEntryMessage_Result() -} - -type SideEffectEntryMessage_Value struct { - Value []byte `protobuf:"bytes,14,opt,name=value,proto3,oneof"` -} - -type SideEffectEntryMessage_Failure struct { - Failure *FailureWithTerminal `protobuf:"bytes,15,opt,name=failure,proto3,oneof"` -} - -func (*SideEffectEntryMessage_Value) isSideEffectEntryMessage_Result() {} - -func (*SideEffectEntryMessage_Failure) isSideEffectEntryMessage_Result() {} - // Type: 0xFC00 + 2 type CombinatorEntryMessage struct { state protoimpl.MessageState @@ -182,7 +44,7 @@ type CombinatorEntryMessage struct { func (x *CombinatorEntryMessage) Reset() { *x = CombinatorEntryMessage{} if protoimpl.UnsafeEnabled { - mi := &file_proto_javascript_javascript_proto_msgTypes[2] + mi := &file_proto_javascript_javascript_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -195,7 +57,7 @@ func (x *CombinatorEntryMessage) String() string { func (*CombinatorEntryMessage) ProtoMessage() {} func (x *CombinatorEntryMessage) ProtoReflect() protoreflect.Message { - mi := &file_proto_javascript_javascript_proto_msgTypes[2] + mi := &file_proto_javascript_javascript_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -208,7 +70,7 @@ func (x *CombinatorEntryMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use CombinatorEntryMessage.ProtoReflect.Descriptor instead. func (*CombinatorEntryMessage) Descriptor() ([]byte, []int) { - return file_proto_javascript_javascript_proto_rawDescGZIP(), []int{2} + return file_proto_javascript_javascript_proto_rawDescGZIP(), []int{0} } func (x *CombinatorEntryMessage) GetCombinatorId() int32 { @@ -233,47 +95,31 @@ var file_proto_javascript_javascript_proto_rawDesc = []byte{ 0x6f, 0x74, 0x6f, 0x12, 0x1a, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x1a, 0x1d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x72, - 0x0a, 0x13, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x57, 0x69, 0x74, 0x68, 0x54, 0x65, 0x72, - 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x12, 0x3f, 0x0a, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x52, 0x07, 0x66, - 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, - 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, - 0x61, 0x6c, 0x22, 0x87, 0x01, 0x0a, 0x16, 0x53, 0x69, 0x64, 0x65, 0x45, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4b, 0x0a, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, - 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x57, 0x69, 0x74, 0x68, 0x54, - 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x48, 0x00, 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, - 0x72, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x71, 0x0a, 0x16, - 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, - 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x63, - 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x15, 0x6a, - 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x5f, 0x6f, - 0x72, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x52, 0x13, 0x6a, 0x6f, 0x75, 0x72, - 0x6e, 0x61, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x42, - 0xff, 0x01, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x42, 0x0f, 0x4a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x6d, 0x75, 0x68, 0x61, 0x6d, 0x61, 0x64, 0x61, 0x7a, 0x6d, 0x79, 0x2f, 0x72, 0x65, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2d, 0x73, 0x64, 0x6b, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x65, 0x6e, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6a, 0x61, 0x76, - 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0xa2, 0x02, 0x04, 0x44, 0x52, 0x53, 0x4a, 0xaa, 0x02, - 0x1a, 0x44, 0x65, 0x76, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x64, 0x6b, - 0x2e, 0x4a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0xca, 0x02, 0x1a, 0x44, 0x65, - 0x76, 0x5c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x53, 0x64, 0x6b, 0x5c, 0x4a, 0x61, - 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0xe2, 0x02, 0x26, 0x44, 0x65, 0x76, 0x5c, 0x52, - 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x53, 0x64, 0x6b, 0x5c, 0x4a, 0x61, 0x76, 0x61, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0xea, 0x02, 0x1d, 0x44, 0x65, 0x76, 0x3a, 0x3a, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x3a, 0x3a, 0x53, 0x64, 0x6b, 0x3a, 0x3a, 0x4a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x71, + 0x0a, 0x16, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x62, + 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x0c, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x32, 0x0a, + 0x15, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x05, 0x52, 0x13, 0x6a, 0x6f, + 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x4f, 0x72, 0x64, 0x65, + 0x72, 0x42, 0xf6, 0x01, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x64, 0x6b, 0x2e, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x42, 0x0f, 0x4a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x64, 0x65, 0x76, 0x2f, 0x73, + 0x64, 0x6b, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0xa2, 0x02, 0x04, 0x44, 0x52, 0x53, 0x4a, 0xaa, 0x02, 0x1a, 0x44, 0x65, 0x76, 0x2e, 0x52, 0x65, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x64, 0x6b, 0x2e, 0x4a, 0x61, 0x76, 0x61, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0xca, 0x02, 0x1a, 0x44, 0x65, 0x76, 0x5c, 0x52, 0x65, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x5c, 0x53, 0x64, 0x6b, 0x5c, 0x4a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0xe2, 0x02, 0x26, 0x44, 0x65, 0x76, 0x5c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, + 0x53, 0x64, 0x6b, 0x5c, 0x4a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1d, 0x44, 0x65, 0x76, + 0x3a, 0x3a, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x3a, 0x3a, 0x53, 0x64, 0x6b, 0x3a, 0x3a, + 0x4a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -288,21 +134,16 @@ func file_proto_javascript_javascript_proto_rawDescGZIP() []byte { return file_proto_javascript_javascript_proto_rawDescData } -var file_proto_javascript_javascript_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_proto_javascript_javascript_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_proto_javascript_javascript_proto_goTypes = []interface{}{ - (*FailureWithTerminal)(nil), // 0: dev.restate.sdk.javascript.FailureWithTerminal - (*SideEffectEntryMessage)(nil), // 1: dev.restate.sdk.javascript.SideEffectEntryMessage - (*CombinatorEntryMessage)(nil), // 2: dev.restate.sdk.javascript.CombinatorEntryMessage - (*protocol.Failure)(nil), // 3: dev.restate.service.protocol.Failure + (*CombinatorEntryMessage)(nil), // 0: dev.restate.sdk.javascript.CombinatorEntryMessage } var file_proto_javascript_javascript_proto_depIdxs = []int32{ - 3, // 0: dev.restate.sdk.javascript.FailureWithTerminal.failure:type_name -> dev.restate.service.protocol.Failure - 0, // 1: dev.restate.sdk.javascript.SideEffectEntryMessage.failure:type_name -> dev.restate.sdk.javascript.FailureWithTerminal - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } func init() { file_proto_javascript_javascript_proto_init() } @@ -312,30 +153,6 @@ func file_proto_javascript_javascript_proto_init() { } if !protoimpl.UnsafeEnabled { file_proto_javascript_javascript_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FailureWithTerminal); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_javascript_javascript_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SideEffectEntryMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_javascript_javascript_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CombinatorEntryMessage); i { case 0: return &v.state @@ -348,17 +165,13 @@ func file_proto_javascript_javascript_proto_init() { } } } - file_proto_javascript_javascript_proto_msgTypes[1].OneofWrappers = []interface{}{ - (*SideEffectEntryMessage_Value)(nil), - (*SideEffectEntryMessage_Failure)(nil), - } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_javascript_javascript_proto_rawDesc, NumEnums: 0, - NumMessages: 3, + NumMessages: 1, NumExtensions: 0, NumServices: 0, }, diff --git a/generated/proto/protocol/protocol.pb.go b/generated/proto/protocol/protocol.pb.go index da54474..ea25628 100644 --- a/generated/proto/protocol/protocol.pb.go +++ b/generated/proto/protocol/protocol.pb.go @@ -9,7 +9,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 +// protoc-gen-go v1.26.0 // protoc (unknown) // source: proto/protocol/protocol.proto @@ -18,7 +18,6 @@ package protocol import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - emptypb "google.golang.org/protobuf/types/known/emptypb" reflect "reflect" sync "sync" ) @@ -30,23 +29,71 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// Service protocol version. +type ServiceProtocolVersion int32 + +const ( + ServiceProtocolVersion_SERVICE_PROTOCOL_VERSION_UNSPECIFIED ServiceProtocolVersion = 0 + // initial service protocol version + ServiceProtocolVersion_V1 ServiceProtocolVersion = 1 +) + +// Enum value maps for ServiceProtocolVersion. +var ( + ServiceProtocolVersion_name = map[int32]string{ + 0: "SERVICE_PROTOCOL_VERSION_UNSPECIFIED", + 1: "V1", + } + ServiceProtocolVersion_value = map[string]int32{ + "SERVICE_PROTOCOL_VERSION_UNSPECIFIED": 0, + "V1": 1, + } +) + +func (x ServiceProtocolVersion) Enum() *ServiceProtocolVersion { + p := new(ServiceProtocolVersion) + *p = x + return p +} + +func (x ServiceProtocolVersion) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ServiceProtocolVersion) Descriptor() protoreflect.EnumDescriptor { + return file_proto_protocol_protocol_proto_enumTypes[0].Descriptor() +} + +func (ServiceProtocolVersion) Type() protoreflect.EnumType { + return &file_proto_protocol_protocol_proto_enumTypes[0] +} + +func (x ServiceProtocolVersion) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ServiceProtocolVersion.Descriptor instead. +func (ServiceProtocolVersion) EnumDescriptor() ([]byte, []int) { + return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{0} +} + // Type: 0x0000 + 0 type StartMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Unique id of the invocation. This id is unique across invocations and won't - // change when replaying the journal. + // Unique id of the invocation. This id is unique across invocations and won't change when replaying the journal. Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Invocation id that can be used for logging. - // The user can use this id to address this invocation in admin and status - // introspection apis. + // The user can use this id to address this invocation in admin and status introspection apis. DebugId string `protobuf:"bytes,2,opt,name=debug_id,json=debugId,proto3" json:"debug_id,omitempty"` KnownEntries uint32 `protobuf:"varint,3,opt,name=known_entries,json=knownEntries,proto3" json:"known_entries,omitempty"` // protolint:disable:next REPEATED_FIELD_NAMES_PLURALIZED StateMap []*StartMessage_StateEntry `protobuf:"bytes,4,rep,name=state_map,json=stateMap,proto3" json:"state_map,omitempty"` PartialState bool `protobuf:"varint,5,opt,name=partial_state,json=partialState,proto3" json:"partial_state,omitempty"` + // If this invocation has a key associated (e.g. for objects and workflows), then this key is filled in. Empty otherwise. + Key string `protobuf:"bytes,6,opt,name=key,proto3" json:"key,omitempty"` } func (x *StartMessage) Reset() { @@ -116,6 +163,13 @@ func (x *StartMessage) GetPartialState() bool { return false } +func (x *StartMessage) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + // Type: 0x0000 + 1 type CompletionMessage struct { state protoimpl.MessageState @@ -177,7 +231,7 @@ func (m *CompletionMessage) GetResult() isCompletionMessage_Result { return nil } -func (x *CompletionMessage) GetEmpty() *emptypb.Empty { +func (x *CompletionMessage) GetEmpty() *Empty { if x, ok := x.GetResult().(*CompletionMessage_Empty); ok { return x.Empty } @@ -203,7 +257,7 @@ type isCompletionMessage_Result interface { } type CompletionMessage_Empty struct { - Empty *emptypb.Empty `protobuf:"bytes,13,opt,name=empty,proto3,oneof"` + Empty *Empty `protobuf:"bytes,13,opt,name=empty,proto3,oneof"` } type CompletionMessage_Value struct { @@ -227,10 +281,10 @@ type SuspensionMessage struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // This list represents any of the entry_index the invocation is waiting on to - // progress. The runtime will resume the invocation as soon as one of the - // given entry_index is completed. This list MUST not be empty. False - // positive, entry_indexes is a valid plural of entry_indices. + // This list represents any of the entry_index the invocation is waiting on to progress. + // The runtime will resume the invocation as soon as one of the given entry_index is completed. + // This list MUST not be empty. + // False positive, entry_indexes is a valid plural of entry_indices. // https://learn.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/i/index-indexes-indices EntryIndexes []uint32 `protobuf:"varint,1,rep,packed,name=entry_indexes,json=entryIndexes,proto3" json:"entry_indexes,omitempty"` // protolint:disable:this REPEATED_FIELD_NAMES_PLURALIZED } @@ -280,21 +334,22 @@ type ErrorMessage struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The code can be: - // * Any of the error codes defined by OutputStreamEntry.failure (see Failure - // message) - // * JOURNAL_MISMATCH = 32, that is when the SDK cannot replay a journal due - // to the mismatch between the journal and the actual code. - // * PROTOCOL_VIOLATION = 33, that is when the SDK receives an unexpected - // message or an expected message variant, given its state. - // - // If 16 < code < 32, or code > 33, the runtime will interpret it as code 2 - // (UNKNOWN). + // The code can be any HTTP status code, as described https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml. + // In addition, we define the following error codes that MAY be used by the SDK for better error reporting: + // * JOURNAL_MISMATCH = 570, that is when the SDK cannot replay a journal due to the mismatch between the journal and the actual code. + // * PROTOCOL_VIOLATION = 571, that is when the SDK receives an unexpected message or an expected message variant, given its state. Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` // Contains a concise error message, e.g. Throwable#getMessage() in Java. Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` // Contains a verbose error description, e.g. the exception stacktrace. Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + // Entry that caused the failure. This may be outside the current stored journal size. + // If no specific entry caused the failure, the current replayed/processed entry can be used. + RelatedEntryIndex *uint32 `protobuf:"varint,4,opt,name=related_entry_index,json=relatedEntryIndex,proto3,oneof" json:"related_entry_index,omitempty"` + // Name of the entry that caused the failure. + RelatedEntryName *string `protobuf:"bytes,5,opt,name=related_entry_name,json=relatedEntryName,proto3,oneof" json:"related_entry_name,omitempty"` + // Entry type. + RelatedEntryType *uint32 `protobuf:"varint,6,opt,name=related_entry_type,json=relatedEntryType,proto3,oneof" json:"related_entry_type,omitempty"` } func (x *ErrorMessage) Reset() { @@ -350,6 +405,27 @@ func (x *ErrorMessage) GetDescription() string { return "" } +func (x *ErrorMessage) GetRelatedEntryIndex() uint32 { + if x != nil && x.RelatedEntryIndex != nil { + return *x.RelatedEntryIndex + } + return 0 +} + +func (x *ErrorMessage) GetRelatedEntryName() string { + if x != nil && x.RelatedEntryName != nil { + return *x.RelatedEntryName + } + return "" +} + +func (x *ErrorMessage) GetRelatedEntryType() uint32 { + if x != nil && x.RelatedEntryType != nil { + return *x.RelatedEntryType + } + return 0 +} + // Type: 0x0000 + 4 type EntryAckMessage struct { state protoimpl.MessageState @@ -438,23 +514,22 @@ func (*EndMessage) Descriptor() ([]byte, []int) { return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{5} } -// Completable: Yes +// Completable: No // Fallible: No // Type: 0x0400 + 0 -type PollInputStreamEntryMessage struct { +type InputEntryMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Types that are assignable to Result: - // - // *PollInputStreamEntryMessage_Value - // *PollInputStreamEntryMessage_Failure - Result isPollInputStreamEntryMessage_Result `protobuf_oneof:"result"` + Headers []*Header `protobuf:"bytes,1,rep,name=headers,proto3" json:"headers,omitempty"` + Value []byte `protobuf:"bytes,14,opt,name=value,proto3" json:"value,omitempty"` + // Entry name + Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` } -func (x *PollInputStreamEntryMessage) Reset() { - *x = PollInputStreamEntryMessage{} +func (x *InputEntryMessage) Reset() { + *x = InputEntryMessage{} if protoimpl.UnsafeEnabled { mi := &file_proto_protocol_protocol_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -462,13 +537,13 @@ func (x *PollInputStreamEntryMessage) Reset() { } } -func (x *PollInputStreamEntryMessage) String() string { +func (x *InputEntryMessage) String() string { return protoimpl.X.MessageStringOf(x) } -func (*PollInputStreamEntryMessage) ProtoMessage() {} +func (*InputEntryMessage) ProtoMessage() {} -func (x *PollInputStreamEntryMessage) ProtoReflect() protoreflect.Message { +func (x *InputEntryMessage) ProtoReflect() protoreflect.Message { mi := &file_proto_protocol_protocol_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -480,65 +555,51 @@ func (x *PollInputStreamEntryMessage) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use PollInputStreamEntryMessage.ProtoReflect.Descriptor instead. -func (*PollInputStreamEntryMessage) Descriptor() ([]byte, []int) { +// Deprecated: Use InputEntryMessage.ProtoReflect.Descriptor instead. +func (*InputEntryMessage) Descriptor() ([]byte, []int) { return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{6} } -func (m *PollInputStreamEntryMessage) GetResult() isPollInputStreamEntryMessage_Result { - if m != nil { - return m.Result +func (x *InputEntryMessage) GetHeaders() []*Header { + if x != nil { + return x.Headers } return nil } -func (x *PollInputStreamEntryMessage) GetValue() []byte { - if x, ok := x.GetResult().(*PollInputStreamEntryMessage_Value); ok { +func (x *InputEntryMessage) GetValue() []byte { + if x != nil { return x.Value } return nil } -func (x *PollInputStreamEntryMessage) GetFailure() *Failure { - if x, ok := x.GetResult().(*PollInputStreamEntryMessage_Failure); ok { - return x.Failure +func (x *InputEntryMessage) GetName() string { + if x != nil { + return x.Name } - return nil -} - -type isPollInputStreamEntryMessage_Result interface { - isPollInputStreamEntryMessage_Result() -} - -type PollInputStreamEntryMessage_Value struct { - Value []byte `protobuf:"bytes,14,opt,name=value,proto3,oneof"` -} - -type PollInputStreamEntryMessage_Failure struct { - Failure *Failure `protobuf:"bytes,15,opt,name=failure,proto3,oneof"` + return "" } -func (*PollInputStreamEntryMessage_Value) isPollInputStreamEntryMessage_Result() {} - -func (*PollInputStreamEntryMessage_Failure) isPollInputStreamEntryMessage_Result() {} - // Completable: No // Fallible: No // Type: 0x0400 + 1 -type OutputStreamEntryMessage struct { +type OutputEntryMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields // Types that are assignable to Result: // - // *OutputStreamEntryMessage_Value - // *OutputStreamEntryMessage_Failure - Result isOutputStreamEntryMessage_Result `protobuf_oneof:"result"` + // *OutputEntryMessage_Value + // *OutputEntryMessage_Failure + Result isOutputEntryMessage_Result `protobuf_oneof:"result"` + // Entry name + Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` } -func (x *OutputStreamEntryMessage) Reset() { - *x = OutputStreamEntryMessage{} +func (x *OutputEntryMessage) Reset() { + *x = OutputEntryMessage{} if protoimpl.UnsafeEnabled { mi := &file_proto_protocol_protocol_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -546,13 +607,13 @@ func (x *OutputStreamEntryMessage) Reset() { } } -func (x *OutputStreamEntryMessage) String() string { +func (x *OutputEntryMessage) String() string { return protoimpl.X.MessageStringOf(x) } -func (*OutputStreamEntryMessage) ProtoMessage() {} +func (*OutputEntryMessage) ProtoMessage() {} -func (x *OutputStreamEntryMessage) ProtoReflect() protoreflect.Message { +func (x *OutputEntryMessage) ProtoReflect() protoreflect.Message { mi := &file_proto_protocol_protocol_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -564,47 +625,54 @@ func (x *OutputStreamEntryMessage) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use OutputStreamEntryMessage.ProtoReflect.Descriptor instead. -func (*OutputStreamEntryMessage) Descriptor() ([]byte, []int) { +// Deprecated: Use OutputEntryMessage.ProtoReflect.Descriptor instead. +func (*OutputEntryMessage) Descriptor() ([]byte, []int) { return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{7} } -func (m *OutputStreamEntryMessage) GetResult() isOutputStreamEntryMessage_Result { +func (m *OutputEntryMessage) GetResult() isOutputEntryMessage_Result { if m != nil { return m.Result } return nil } -func (x *OutputStreamEntryMessage) GetValue() []byte { - if x, ok := x.GetResult().(*OutputStreamEntryMessage_Value); ok { +func (x *OutputEntryMessage) GetValue() []byte { + if x, ok := x.GetResult().(*OutputEntryMessage_Value); ok { return x.Value } return nil } -func (x *OutputStreamEntryMessage) GetFailure() *Failure { - if x, ok := x.GetResult().(*OutputStreamEntryMessage_Failure); ok { +func (x *OutputEntryMessage) GetFailure() *Failure { + if x, ok := x.GetResult().(*OutputEntryMessage_Failure); ok { return x.Failure } return nil } -type isOutputStreamEntryMessage_Result interface { - isOutputStreamEntryMessage_Result() +func (x *OutputEntryMessage) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type isOutputEntryMessage_Result interface { + isOutputEntryMessage_Result() } -type OutputStreamEntryMessage_Value struct { +type OutputEntryMessage_Value struct { Value []byte `protobuf:"bytes,14,opt,name=value,proto3,oneof"` } -type OutputStreamEntryMessage_Failure struct { +type OutputEntryMessage_Failure struct { Failure *Failure `protobuf:"bytes,15,opt,name=failure,proto3,oneof"` } -func (*OutputStreamEntryMessage_Value) isOutputStreamEntryMessage_Result() {} +func (*OutputEntryMessage_Value) isOutputEntryMessage_Result() {} -func (*OutputStreamEntryMessage_Failure) isOutputStreamEntryMessage_Result() {} +func (*OutputEntryMessage_Failure) isOutputEntryMessage_Result() {} // Completable: Yes // Fallible: No @@ -621,6 +689,8 @@ type GetStateEntryMessage struct { // *GetStateEntryMessage_Value // *GetStateEntryMessage_Failure Result isGetStateEntryMessage_Result `protobuf_oneof:"result"` + // Entry name + Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` } func (x *GetStateEntryMessage) Reset() { @@ -669,7 +739,7 @@ func (m *GetStateEntryMessage) GetResult() isGetStateEntryMessage_Result { return nil } -func (x *GetStateEntryMessage) GetEmpty() *emptypb.Empty { +func (x *GetStateEntryMessage) GetEmpty() *Empty { if x, ok := x.GetResult().(*GetStateEntryMessage_Empty); ok { return x.Empty } @@ -690,12 +760,19 @@ func (x *GetStateEntryMessage) GetFailure() *Failure { return nil } +func (x *GetStateEntryMessage) GetName() string { + if x != nil { + return x.Name + } + return "" +} + type isGetStateEntryMessage_Result interface { isGetStateEntryMessage_Result() } type GetStateEntryMessage_Empty struct { - Empty *emptypb.Empty `protobuf:"bytes,13,opt,name=empty,proto3,oneof"` + Empty *Empty `protobuf:"bytes,13,opt,name=empty,proto3,oneof"` } type GetStateEntryMessage_Value struct { @@ -722,6 +799,8 @@ type SetStateEntryMessage struct { Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` Value []byte `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` + // Entry name + Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` } func (x *SetStateEntryMessage) Reset() { @@ -770,6 +849,13 @@ func (x *SetStateEntryMessage) GetValue() []byte { return nil } +func (x *SetStateEntryMessage) GetName() string { + if x != nil { + return x.Name + } + return "" +} + // Completable: No // Fallible: No // Type: 0x0800 + 2 @@ -779,6 +865,8 @@ type ClearStateEntryMessage struct { unknownFields protoimpl.UnknownFields Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // Entry name + Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` } func (x *ClearStateEntryMessage) Reset() { @@ -820,6 +908,13 @@ func (x *ClearStateEntryMessage) GetKey() []byte { return nil } +func (x *ClearStateEntryMessage) GetName() string { + if x != nil { + return x.Name + } + return "" +} + // Completable: No // Fallible: No // Type: 0x0800 + 3 @@ -827,6 +922,9 @@ type ClearAllStateEntryMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // Entry name + Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` } func (x *ClearAllStateEntryMessage) Reset() { @@ -861,6 +959,13 @@ func (*ClearAllStateEntryMessage) Descriptor() ([]byte, []int) { return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{11} } +func (x *ClearAllStateEntryMessage) GetName() string { + if x != nil { + return x.Name + } + return "" +} + // Completable: Yes // Fallible: No // Type: 0x0800 + 4 @@ -874,6 +979,8 @@ type GetStateKeysEntryMessage struct { // *GetStateKeysEntryMessage_Value // *GetStateKeysEntryMessage_Failure Result isGetStateKeysEntryMessage_Result `protobuf_oneof:"result"` + // Entry name + Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` } func (x *GetStateKeysEntryMessage) Reset() { @@ -929,6 +1036,13 @@ func (x *GetStateKeysEntryMessage) GetFailure() *Failure { return nil } +func (x *GetStateKeysEntryMessage) GetName() string { + if x != nil { + return x.Name + } + return "" +} + type isGetStateKeysEntryMessage_Result interface { isGetStateKeysEntryMessage_Result() } @@ -947,24 +1061,24 @@ func (*GetStateKeysEntryMessage_Failure) isGetStateKeysEntryMessage_Result() {} // Completable: Yes // Fallible: No -// Type: 0x0C00 + 0 -type SleepEntryMessage struct { +// Type: 0x0800 + 8 +type GetPromiseEntryMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Wake up time. - // The time is set as duration since UNIX Epoch. - WakeUpTime uint64 `protobuf:"varint,1,opt,name=wake_up_time,json=wakeUpTime,proto3" json:"wake_up_time,omitempty"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // Types that are assignable to Result: // - // *SleepEntryMessage_Empty - // *SleepEntryMessage_Failure - Result isSleepEntryMessage_Result `protobuf_oneof:"result"` + // *GetPromiseEntryMessage_Value + // *GetPromiseEntryMessage_Failure + Result isGetPromiseEntryMessage_Result `protobuf_oneof:"result"` + // Entry name + Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` } -func (x *SleepEntryMessage) Reset() { - *x = SleepEntryMessage{} +func (x *GetPromiseEntryMessage) Reset() { + *x = GetPromiseEntryMessage{} if protoimpl.UnsafeEnabled { mi := &file_proto_protocol_protocol_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -972,13 +1086,13 @@ func (x *SleepEntryMessage) Reset() { } } -func (x *SleepEntryMessage) String() string { +func (x *GetPromiseEntryMessage) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SleepEntryMessage) ProtoMessage() {} +func (*GetPromiseEntryMessage) ProtoMessage() {} -func (x *SleepEntryMessage) ProtoReflect() protoreflect.Message { +func (x *GetPromiseEntryMessage) ProtoReflect() protoreflect.Message { mi := &file_proto_protocol_protocol_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -990,75 +1104,83 @@ func (x *SleepEntryMessage) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SleepEntryMessage.ProtoReflect.Descriptor instead. -func (*SleepEntryMessage) Descriptor() ([]byte, []int) { +// Deprecated: Use GetPromiseEntryMessage.ProtoReflect.Descriptor instead. +func (*GetPromiseEntryMessage) Descriptor() ([]byte, []int) { return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{13} } -func (x *SleepEntryMessage) GetWakeUpTime() uint64 { +func (x *GetPromiseEntryMessage) GetKey() string { if x != nil { - return x.WakeUpTime + return x.Key } - return 0 + return "" } -func (m *SleepEntryMessage) GetResult() isSleepEntryMessage_Result { +func (m *GetPromiseEntryMessage) GetResult() isGetPromiseEntryMessage_Result { if m != nil { return m.Result } return nil } -func (x *SleepEntryMessage) GetEmpty() *emptypb.Empty { - if x, ok := x.GetResult().(*SleepEntryMessage_Empty); ok { - return x.Empty +func (x *GetPromiseEntryMessage) GetValue() []byte { + if x, ok := x.GetResult().(*GetPromiseEntryMessage_Value); ok { + return x.Value } return nil } -func (x *SleepEntryMessage) GetFailure() *Failure { - if x, ok := x.GetResult().(*SleepEntryMessage_Failure); ok { +func (x *GetPromiseEntryMessage) GetFailure() *Failure { + if x, ok := x.GetResult().(*GetPromiseEntryMessage_Failure); ok { return x.Failure } return nil } -type isSleepEntryMessage_Result interface { - isSleepEntryMessage_Result() +func (x *GetPromiseEntryMessage) GetName() string { + if x != nil { + return x.Name + } + return "" } -type SleepEntryMessage_Empty struct { - Empty *emptypb.Empty `protobuf:"bytes,13,opt,name=empty,proto3,oneof"` +type isGetPromiseEntryMessage_Result interface { + isGetPromiseEntryMessage_Result() } -type SleepEntryMessage_Failure struct { +type GetPromiseEntryMessage_Value struct { + Value []byte `protobuf:"bytes,14,opt,name=value,proto3,oneof"` +} + +type GetPromiseEntryMessage_Failure struct { Failure *Failure `protobuf:"bytes,15,opt,name=failure,proto3,oneof"` } -func (*SleepEntryMessage_Empty) isSleepEntryMessage_Result() {} +func (*GetPromiseEntryMessage_Value) isGetPromiseEntryMessage_Result() {} -func (*SleepEntryMessage_Failure) isSleepEntryMessage_Result() {} +func (*GetPromiseEntryMessage_Failure) isGetPromiseEntryMessage_Result() {} // Completable: Yes -// Fallible: Yes -// Type: 0x0C00 + 1 -type InvokeEntryMessage struct { +// Fallible: No +// Type: 0x0800 + 9 +type PeekPromiseEntryMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ServiceName string `protobuf:"bytes,1,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` - MethodName string `protobuf:"bytes,2,opt,name=method_name,json=methodName,proto3" json:"method_name,omitempty"` - Parameter []byte `protobuf:"bytes,3,opt,name=parameter,proto3" json:"parameter,omitempty"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // Types that are assignable to Result: // - // *InvokeEntryMessage_Value - // *InvokeEntryMessage_Failure - Result isInvokeEntryMessage_Result `protobuf_oneof:"result"` + // *PeekPromiseEntryMessage_Empty + // *PeekPromiseEntryMessage_Value + // *PeekPromiseEntryMessage_Failure + Result isPeekPromiseEntryMessage_Result `protobuf_oneof:"result"` + // Entry name + Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` } -func (x *InvokeEntryMessage) Reset() { - *x = InvokeEntryMessage{} +func (x *PeekPromiseEntryMessage) Reset() { + *x = PeekPromiseEntryMessage{} if protoimpl.UnsafeEnabled { mi := &file_proto_protocol_protocol_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1066,13 +1188,13 @@ func (x *InvokeEntryMessage) Reset() { } } -func (x *InvokeEntryMessage) String() string { +func (x *PeekPromiseEntryMessage) String() string { return protoimpl.X.MessageStringOf(x) } -func (*InvokeEntryMessage) ProtoMessage() {} +func (*PeekPromiseEntryMessage) ProtoMessage() {} -func (x *InvokeEntryMessage) ProtoReflect() protoreflect.Message { +func (x *PeekPromiseEntryMessage) ProtoReflect() protoreflect.Message { mi := &file_proto_protocol_protocol_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1084,89 +1206,102 @@ func (x *InvokeEntryMessage) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use InvokeEntryMessage.ProtoReflect.Descriptor instead. -func (*InvokeEntryMessage) Descriptor() ([]byte, []int) { +// Deprecated: Use PeekPromiseEntryMessage.ProtoReflect.Descriptor instead. +func (*PeekPromiseEntryMessage) Descriptor() ([]byte, []int) { return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{14} } -func (x *InvokeEntryMessage) GetServiceName() string { - if x != nil { - return x.ServiceName - } - return "" -} - -func (x *InvokeEntryMessage) GetMethodName() string { +func (x *PeekPromiseEntryMessage) GetKey() string { if x != nil { - return x.MethodName + return x.Key } return "" } -func (x *InvokeEntryMessage) GetParameter() []byte { - if x != nil { - return x.Parameter +func (m *PeekPromiseEntryMessage) GetResult() isPeekPromiseEntryMessage_Result { + if m != nil { + return m.Result } return nil } -func (m *InvokeEntryMessage) GetResult() isInvokeEntryMessage_Result { - if m != nil { - return m.Result +func (x *PeekPromiseEntryMessage) GetEmpty() *Empty { + if x, ok := x.GetResult().(*PeekPromiseEntryMessage_Empty); ok { + return x.Empty } return nil } -func (x *InvokeEntryMessage) GetValue() []byte { - if x, ok := x.GetResult().(*InvokeEntryMessage_Value); ok { +func (x *PeekPromiseEntryMessage) GetValue() []byte { + if x, ok := x.GetResult().(*PeekPromiseEntryMessage_Value); ok { return x.Value } return nil } -func (x *InvokeEntryMessage) GetFailure() *Failure { - if x, ok := x.GetResult().(*InvokeEntryMessage_Failure); ok { +func (x *PeekPromiseEntryMessage) GetFailure() *Failure { + if x, ok := x.GetResult().(*PeekPromiseEntryMessage_Failure); ok { return x.Failure } return nil } -type isInvokeEntryMessage_Result interface { - isInvokeEntryMessage_Result() +func (x *PeekPromiseEntryMessage) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type isPeekPromiseEntryMessage_Result interface { + isPeekPromiseEntryMessage_Result() } -type InvokeEntryMessage_Value struct { +type PeekPromiseEntryMessage_Empty struct { + Empty *Empty `protobuf:"bytes,13,opt,name=empty,proto3,oneof"` +} + +type PeekPromiseEntryMessage_Value struct { Value []byte `protobuf:"bytes,14,opt,name=value,proto3,oneof"` } -type InvokeEntryMessage_Failure struct { +type PeekPromiseEntryMessage_Failure struct { Failure *Failure `protobuf:"bytes,15,opt,name=failure,proto3,oneof"` } -func (*InvokeEntryMessage_Value) isInvokeEntryMessage_Result() {} +func (*PeekPromiseEntryMessage_Empty) isPeekPromiseEntryMessage_Result() {} -func (*InvokeEntryMessage_Failure) isInvokeEntryMessage_Result() {} +func (*PeekPromiseEntryMessage_Value) isPeekPromiseEntryMessage_Result() {} -// Completable: No -// Fallible: Yes -// Type: 0x0C00 + 2 -type BackgroundInvokeEntryMessage struct { +func (*PeekPromiseEntryMessage_Failure) isPeekPromiseEntryMessage_Result() {} + +// Completable: Yes +// Fallible: No +// Type: 0x0800 + A +type CompletePromiseEntryMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ServiceName string `protobuf:"bytes,1,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` - MethodName string `protobuf:"bytes,2,opt,name=method_name,json=methodName,proto3" json:"method_name,omitempty"` - Parameter []byte `protobuf:"bytes,3,opt,name=parameter,proto3" json:"parameter,omitempty"` - // Time when this BackgroundInvoke should be executed. - // The time is set as duration since UNIX Epoch. - // If this value is not set, equal to 0, or past in time, - // the runtime will execute this BackgroundInvoke as soon as possible. - InvokeTime uint64 `protobuf:"varint,4,opt,name=invoke_time,json=invokeTime,proto3" json:"invoke_time,omitempty"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // The value to use to complete the promise + // + // Types that are assignable to Completion: + // + // *CompletePromiseEntryMessage_CompletionValue + // *CompletePromiseEntryMessage_CompletionFailure + Completion isCompletePromiseEntryMessage_Completion `protobuf_oneof:"completion"` + // Types that are assignable to Result: + // + // *CompletePromiseEntryMessage_Empty + // *CompletePromiseEntryMessage_Failure + Result isCompletePromiseEntryMessage_Result `protobuf_oneof:"result"` + // Entry name + Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` } -func (x *BackgroundInvokeEntryMessage) Reset() { - *x = BackgroundInvokeEntryMessage{} +func (x *CompletePromiseEntryMessage) Reset() { + *x = CompletePromiseEntryMessage{} if protoimpl.UnsafeEnabled { mi := &file_proto_protocol_protocol_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1174,13 +1309,13 @@ func (x *BackgroundInvokeEntryMessage) Reset() { } } -func (x *BackgroundInvokeEntryMessage) String() string { +func (x *CompletePromiseEntryMessage) String() string { return protoimpl.X.MessageStringOf(x) } -func (*BackgroundInvokeEntryMessage) ProtoMessage() {} +func (*CompletePromiseEntryMessage) ProtoMessage() {} -func (x *BackgroundInvokeEntryMessage) ProtoReflect() protoreflect.Message { +func (x *CompletePromiseEntryMessage) ProtoReflect() protoreflect.Message { mi := &file_proto_protocol_protocol_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1192,58 +1327,123 @@ func (x *BackgroundInvokeEntryMessage) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use BackgroundInvokeEntryMessage.ProtoReflect.Descriptor instead. -func (*BackgroundInvokeEntryMessage) Descriptor() ([]byte, []int) { +// Deprecated: Use CompletePromiseEntryMessage.ProtoReflect.Descriptor instead. +func (*CompletePromiseEntryMessage) Descriptor() ([]byte, []int) { return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{15} } -func (x *BackgroundInvokeEntryMessage) GetServiceName() string { +func (x *CompletePromiseEntryMessage) GetKey() string { if x != nil { - return x.ServiceName + return x.Key } return "" } -func (x *BackgroundInvokeEntryMessage) GetMethodName() string { - if x != nil { - return x.MethodName +func (m *CompletePromiseEntryMessage) GetCompletion() isCompletePromiseEntryMessage_Completion { + if m != nil { + return m.Completion } - return "" + return nil } -func (x *BackgroundInvokeEntryMessage) GetParameter() []byte { - if x != nil { - return x.Parameter +func (x *CompletePromiseEntryMessage) GetCompletionValue() []byte { + if x, ok := x.GetCompletion().(*CompletePromiseEntryMessage_CompletionValue); ok { + return x.CompletionValue + } + return nil +} + +func (x *CompletePromiseEntryMessage) GetCompletionFailure() *Failure { + if x, ok := x.GetCompletion().(*CompletePromiseEntryMessage_CompletionFailure); ok { + return x.CompletionFailure + } + return nil +} + +func (m *CompletePromiseEntryMessage) GetResult() isCompletePromiseEntryMessage_Result { + if m != nil { + return m.Result } return nil } -func (x *BackgroundInvokeEntryMessage) GetInvokeTime() uint64 { +func (x *CompletePromiseEntryMessage) GetEmpty() *Empty { + if x, ok := x.GetResult().(*CompletePromiseEntryMessage_Empty); ok { + return x.Empty + } + return nil +} + +func (x *CompletePromiseEntryMessage) GetFailure() *Failure { + if x, ok := x.GetResult().(*CompletePromiseEntryMessage_Failure); ok { + return x.Failure + } + return nil +} + +func (x *CompletePromiseEntryMessage) GetName() string { if x != nil { - return x.InvokeTime + return x.Name } - return 0 + return "" +} + +type isCompletePromiseEntryMessage_Completion interface { + isCompletePromiseEntryMessage_Completion() +} + +type CompletePromiseEntryMessage_CompletionValue struct { + CompletionValue []byte `protobuf:"bytes,2,opt,name=completion_value,json=completionValue,proto3,oneof"` +} + +type CompletePromiseEntryMessage_CompletionFailure struct { + CompletionFailure *Failure `protobuf:"bytes,3,opt,name=completion_failure,json=completionFailure,proto3,oneof"` +} + +func (*CompletePromiseEntryMessage_CompletionValue) isCompletePromiseEntryMessage_Completion() {} + +func (*CompletePromiseEntryMessage_CompletionFailure) isCompletePromiseEntryMessage_Completion() {} + +type isCompletePromiseEntryMessage_Result interface { + isCompletePromiseEntryMessage_Result() +} + +type CompletePromiseEntryMessage_Empty struct { + // Returns empty if value was set successfully + Empty *Empty `protobuf:"bytes,13,opt,name=empty,proto3,oneof"` +} + +type CompletePromiseEntryMessage_Failure struct { + // Returns a failure if the promise was already completed + Failure *Failure `protobuf:"bytes,15,opt,name=failure,proto3,oneof"` } +func (*CompletePromiseEntryMessage_Empty) isCompletePromiseEntryMessage_Result() {} + +func (*CompletePromiseEntryMessage_Failure) isCompletePromiseEntryMessage_Result() {} + // Completable: Yes // Fallible: No -// Type: 0x0C00 + 3 -// Awakeables are addressed by an identifier exposed to the user. See the spec -// for more details. -type AwakeableEntryMessage struct { +// Type: 0x0C00 + 0 +type SleepEntryMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // Wake up time. + // The time is set as duration since UNIX Epoch. + WakeUpTime uint64 `protobuf:"varint,1,opt,name=wake_up_time,json=wakeUpTime,proto3" json:"wake_up_time,omitempty"` // Types that are assignable to Result: // - // *AwakeableEntryMessage_Value - // *AwakeableEntryMessage_Failure - Result isAwakeableEntryMessage_Result `protobuf_oneof:"result"` + // *SleepEntryMessage_Empty + // *SleepEntryMessage_Failure + Result isSleepEntryMessage_Result `protobuf_oneof:"result"` + // Entry name + Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` } -func (x *AwakeableEntryMessage) Reset() { - *x = AwakeableEntryMessage{} +func (x *SleepEntryMessage) Reset() { + *x = SleepEntryMessage{} if protoimpl.UnsafeEnabled { mi := &file_proto_protocol_protocol_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1251,13 +1451,13 @@ func (x *AwakeableEntryMessage) Reset() { } } -func (x *AwakeableEntryMessage) String() string { +func (x *SleepEntryMessage) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AwakeableEntryMessage) ProtoMessage() {} +func (*SleepEntryMessage) ProtoMessage() {} -func (x *AwakeableEntryMessage) ProtoReflect() protoreflect.Message { +func (x *SleepEntryMessage) ProtoReflect() protoreflect.Message { mi := &file_proto_protocol_protocol_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1269,16 +1469,355 @@ func (x *AwakeableEntryMessage) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AwakeableEntryMessage.ProtoReflect.Descriptor instead. -func (*AwakeableEntryMessage) Descriptor() ([]byte, []int) { +// Deprecated: Use SleepEntryMessage.ProtoReflect.Descriptor instead. +func (*SleepEntryMessage) Descriptor() ([]byte, []int) { return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{16} } -func (m *AwakeableEntryMessage) GetResult() isAwakeableEntryMessage_Result { - if m != nil { - return m.Result +func (x *SleepEntryMessage) GetWakeUpTime() uint64 { + if x != nil { + return x.WakeUpTime } - return nil + return 0 +} + +func (m *SleepEntryMessage) GetResult() isSleepEntryMessage_Result { + if m != nil { + return m.Result + } + return nil +} + +func (x *SleepEntryMessage) GetEmpty() *Empty { + if x, ok := x.GetResult().(*SleepEntryMessage_Empty); ok { + return x.Empty + } + return nil +} + +func (x *SleepEntryMessage) GetFailure() *Failure { + if x, ok := x.GetResult().(*SleepEntryMessage_Failure); ok { + return x.Failure + } + return nil +} + +func (x *SleepEntryMessage) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type isSleepEntryMessage_Result interface { + isSleepEntryMessage_Result() +} + +type SleepEntryMessage_Empty struct { + Empty *Empty `protobuf:"bytes,13,opt,name=empty,proto3,oneof"` +} + +type SleepEntryMessage_Failure struct { + Failure *Failure `protobuf:"bytes,15,opt,name=failure,proto3,oneof"` +} + +func (*SleepEntryMessage_Empty) isSleepEntryMessage_Result() {} + +func (*SleepEntryMessage_Failure) isSleepEntryMessage_Result() {} + +// Completable: Yes +// Fallible: Yes +// Type: 0x0C00 + 1 +type CallEntryMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ServiceName string `protobuf:"bytes,1,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` + HandlerName string `protobuf:"bytes,2,opt,name=handler_name,json=handlerName,proto3" json:"handler_name,omitempty"` + Parameter []byte `protobuf:"bytes,3,opt,name=parameter,proto3" json:"parameter,omitempty"` + Headers []*Header `protobuf:"bytes,4,rep,name=headers,proto3" json:"headers,omitempty"` + // If this invocation has a key associated (e.g. for objects and workflows), then this key is filled in. Empty otherwise. + Key string `protobuf:"bytes,5,opt,name=key,proto3" json:"key,omitempty"` + // Types that are assignable to Result: + // + // *CallEntryMessage_Value + // *CallEntryMessage_Failure + Result isCallEntryMessage_Result `protobuf_oneof:"result"` + // Entry name + Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *CallEntryMessage) Reset() { + *x = CallEntryMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_protocol_protocol_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CallEntryMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CallEntryMessage) ProtoMessage() {} + +func (x *CallEntryMessage) ProtoReflect() protoreflect.Message { + mi := &file_proto_protocol_protocol_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CallEntryMessage.ProtoReflect.Descriptor instead. +func (*CallEntryMessage) Descriptor() ([]byte, []int) { + return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{17} +} + +func (x *CallEntryMessage) GetServiceName() string { + if x != nil { + return x.ServiceName + } + return "" +} + +func (x *CallEntryMessage) GetHandlerName() string { + if x != nil { + return x.HandlerName + } + return "" +} + +func (x *CallEntryMessage) GetParameter() []byte { + if x != nil { + return x.Parameter + } + return nil +} + +func (x *CallEntryMessage) GetHeaders() []*Header { + if x != nil { + return x.Headers + } + return nil +} + +func (x *CallEntryMessage) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (m *CallEntryMessage) GetResult() isCallEntryMessage_Result { + if m != nil { + return m.Result + } + return nil +} + +func (x *CallEntryMessage) GetValue() []byte { + if x, ok := x.GetResult().(*CallEntryMessage_Value); ok { + return x.Value + } + return nil +} + +func (x *CallEntryMessage) GetFailure() *Failure { + if x, ok := x.GetResult().(*CallEntryMessage_Failure); ok { + return x.Failure + } + return nil +} + +func (x *CallEntryMessage) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type isCallEntryMessage_Result interface { + isCallEntryMessage_Result() +} + +type CallEntryMessage_Value struct { + Value []byte `protobuf:"bytes,14,opt,name=value,proto3,oneof"` +} + +type CallEntryMessage_Failure struct { + Failure *Failure `protobuf:"bytes,15,opt,name=failure,proto3,oneof"` +} + +func (*CallEntryMessage_Value) isCallEntryMessage_Result() {} + +func (*CallEntryMessage_Failure) isCallEntryMessage_Result() {} + +// Completable: No +// Fallible: Yes +// Type: 0x0C00 + 2 +type OneWayCallEntryMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ServiceName string `protobuf:"bytes,1,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` + HandlerName string `protobuf:"bytes,2,opt,name=handler_name,json=handlerName,proto3" json:"handler_name,omitempty"` + Parameter []byte `protobuf:"bytes,3,opt,name=parameter,proto3" json:"parameter,omitempty"` + // Time when this BackgroundInvoke should be executed. + // The time is set as duration since UNIX Epoch. + // If this value is not set, equal to 0, or past in time, + // the runtime will execute this BackgroundInvoke as soon as possible. + InvokeTime uint64 `protobuf:"varint,4,opt,name=invoke_time,json=invokeTime,proto3" json:"invoke_time,omitempty"` + Headers []*Header `protobuf:"bytes,5,rep,name=headers,proto3" json:"headers,omitempty"` + // If this invocation has a key associated (e.g. for objects and workflows), then this key is filled in. Empty otherwise. + Key string `protobuf:"bytes,6,opt,name=key,proto3" json:"key,omitempty"` + // Entry name + Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *OneWayCallEntryMessage) Reset() { + *x = OneWayCallEntryMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_protocol_protocol_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OneWayCallEntryMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OneWayCallEntryMessage) ProtoMessage() {} + +func (x *OneWayCallEntryMessage) ProtoReflect() protoreflect.Message { + mi := &file_proto_protocol_protocol_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OneWayCallEntryMessage.ProtoReflect.Descriptor instead. +func (*OneWayCallEntryMessage) Descriptor() ([]byte, []int) { + return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{18} +} + +func (x *OneWayCallEntryMessage) GetServiceName() string { + if x != nil { + return x.ServiceName + } + return "" +} + +func (x *OneWayCallEntryMessage) GetHandlerName() string { + if x != nil { + return x.HandlerName + } + return "" +} + +func (x *OneWayCallEntryMessage) GetParameter() []byte { + if x != nil { + return x.Parameter + } + return nil +} + +func (x *OneWayCallEntryMessage) GetInvokeTime() uint64 { + if x != nil { + return x.InvokeTime + } + return 0 +} + +func (x *OneWayCallEntryMessage) GetHeaders() []*Header { + if x != nil { + return x.Headers + } + return nil +} + +func (x *OneWayCallEntryMessage) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *OneWayCallEntryMessage) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +// Completable: Yes +// Fallible: No +// Type: 0x0C00 + 3 +// Awakeables are addressed by an identifier exposed to the user. See the spec for more details. +type AwakeableEntryMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Result: + // + // *AwakeableEntryMessage_Value + // *AwakeableEntryMessage_Failure + Result isAwakeableEntryMessage_Result `protobuf_oneof:"result"` + // Entry name + Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *AwakeableEntryMessage) Reset() { + *x = AwakeableEntryMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_protocol_protocol_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AwakeableEntryMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AwakeableEntryMessage) ProtoMessage() {} + +func (x *AwakeableEntryMessage) ProtoReflect() protoreflect.Message { + mi := &file_proto_protocol_protocol_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AwakeableEntryMessage.ProtoReflect.Descriptor instead. +func (*AwakeableEntryMessage) Descriptor() ([]byte, []int) { + return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{19} +} + +func (m *AwakeableEntryMessage) GetResult() isAwakeableEntryMessage_Result { + if m != nil { + return m.Result + } + return nil } func (x *AwakeableEntryMessage) GetValue() []byte { @@ -1292,59 +1831,169 @@ func (x *AwakeableEntryMessage) GetFailure() *Failure { if x, ok := x.GetResult().(*AwakeableEntryMessage_Failure); ok { return x.Failure } - return nil + return nil +} + +func (x *AwakeableEntryMessage) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type isAwakeableEntryMessage_Result interface { + isAwakeableEntryMessage_Result() +} + +type AwakeableEntryMessage_Value struct { + Value []byte `protobuf:"bytes,14,opt,name=value,proto3,oneof"` +} + +type AwakeableEntryMessage_Failure struct { + Failure *Failure `protobuf:"bytes,15,opt,name=failure,proto3,oneof"` +} + +func (*AwakeableEntryMessage_Value) isAwakeableEntryMessage_Result() {} + +func (*AwakeableEntryMessage_Failure) isAwakeableEntryMessage_Result() {} + +// Completable: No +// Fallible: Yes +// Type: 0x0C00 + 4 +type CompleteAwakeableEntryMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Identifier of the awakeable. See the spec for more details. + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Types that are assignable to Result: + // + // *CompleteAwakeableEntryMessage_Value + // *CompleteAwakeableEntryMessage_Failure + Result isCompleteAwakeableEntryMessage_Result `protobuf_oneof:"result"` + // Entry name + Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *CompleteAwakeableEntryMessage) Reset() { + *x = CompleteAwakeableEntryMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_protocol_protocol_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CompleteAwakeableEntryMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CompleteAwakeableEntryMessage) ProtoMessage() {} + +func (x *CompleteAwakeableEntryMessage) ProtoReflect() protoreflect.Message { + mi := &file_proto_protocol_protocol_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CompleteAwakeableEntryMessage.ProtoReflect.Descriptor instead. +func (*CompleteAwakeableEntryMessage) Descriptor() ([]byte, []int) { + return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{20} +} + +func (x *CompleteAwakeableEntryMessage) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (m *CompleteAwakeableEntryMessage) GetResult() isCompleteAwakeableEntryMessage_Result { + if m != nil { + return m.Result + } + return nil +} + +func (x *CompleteAwakeableEntryMessage) GetValue() []byte { + if x, ok := x.GetResult().(*CompleteAwakeableEntryMessage_Value); ok { + return x.Value + } + return nil +} + +func (x *CompleteAwakeableEntryMessage) GetFailure() *Failure { + if x, ok := x.GetResult().(*CompleteAwakeableEntryMessage_Failure); ok { + return x.Failure + } + return nil +} + +func (x *CompleteAwakeableEntryMessage) GetName() string { + if x != nil { + return x.Name + } + return "" } -type isAwakeableEntryMessage_Result interface { - isAwakeableEntryMessage_Result() +type isCompleteAwakeableEntryMessage_Result interface { + isCompleteAwakeableEntryMessage_Result() } -type AwakeableEntryMessage_Value struct { +type CompleteAwakeableEntryMessage_Value struct { Value []byte `protobuf:"bytes,14,opt,name=value,proto3,oneof"` } -type AwakeableEntryMessage_Failure struct { +type CompleteAwakeableEntryMessage_Failure struct { Failure *Failure `protobuf:"bytes,15,opt,name=failure,proto3,oneof"` } -func (*AwakeableEntryMessage_Value) isAwakeableEntryMessage_Result() {} +func (*CompleteAwakeableEntryMessage_Value) isCompleteAwakeableEntryMessage_Result() {} -func (*AwakeableEntryMessage_Failure) isAwakeableEntryMessage_Result() {} +func (*CompleteAwakeableEntryMessage_Failure) isCompleteAwakeableEntryMessage_Result() {} // Completable: No -// Fallible: Yes -// Type: 0x0C00 + 4 -type CompleteAwakeableEntryMessage struct { +// Fallible: No +// Type: 0x0C00 + 5 +// Flag: RequiresRuntimeAck +type RunEntryMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Identifier of the awakeable. See the spec for more details. - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // Types that are assignable to Result: // - // *CompleteAwakeableEntryMessage_Value - // *CompleteAwakeableEntryMessage_Failure - Result isCompleteAwakeableEntryMessage_Result `protobuf_oneof:"result"` + // *RunEntryMessage_Value + // *RunEntryMessage_Failure + Result isRunEntryMessage_Result `protobuf_oneof:"result"` + // Entry name + Name string `protobuf:"bytes,12,opt,name=name,proto3" json:"name,omitempty"` } -func (x *CompleteAwakeableEntryMessage) Reset() { - *x = CompleteAwakeableEntryMessage{} +func (x *RunEntryMessage) Reset() { + *x = RunEntryMessage{} if protoimpl.UnsafeEnabled { - mi := &file_proto_protocol_protocol_proto_msgTypes[17] + mi := &file_proto_protocol_protocol_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *CompleteAwakeableEntryMessage) String() string { +func (x *RunEntryMessage) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CompleteAwakeableEntryMessage) ProtoMessage() {} +func (*RunEntryMessage) ProtoMessage() {} -func (x *CompleteAwakeableEntryMessage) ProtoReflect() protoreflect.Message { - mi := &file_proto_protocol_protocol_proto_msgTypes[17] +func (x *RunEntryMessage) ProtoReflect() protoreflect.Message { + mi := &file_proto_protocol_protocol_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1355,68 +2004,63 @@ func (x *CompleteAwakeableEntryMessage) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use CompleteAwakeableEntryMessage.ProtoReflect.Descriptor instead. -func (*CompleteAwakeableEntryMessage) Descriptor() ([]byte, []int) { - return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{17} -} - -func (x *CompleteAwakeableEntryMessage) GetId() string { - if x != nil { - return x.Id - } - return "" +// Deprecated: Use RunEntryMessage.ProtoReflect.Descriptor instead. +func (*RunEntryMessage) Descriptor() ([]byte, []int) { + return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{21} } -func (m *CompleteAwakeableEntryMessage) GetResult() isCompleteAwakeableEntryMessage_Result { +func (m *RunEntryMessage) GetResult() isRunEntryMessage_Result { if m != nil { return m.Result } return nil } -func (x *CompleteAwakeableEntryMessage) GetValue() []byte { - if x, ok := x.GetResult().(*CompleteAwakeableEntryMessage_Value); ok { +func (x *RunEntryMessage) GetValue() []byte { + if x, ok := x.GetResult().(*RunEntryMessage_Value); ok { return x.Value } return nil } -func (x *CompleteAwakeableEntryMessage) GetFailure() *Failure { - if x, ok := x.GetResult().(*CompleteAwakeableEntryMessage_Failure); ok { +func (x *RunEntryMessage) GetFailure() *Failure { + if x, ok := x.GetResult().(*RunEntryMessage_Failure); ok { return x.Failure } return nil } -type isCompleteAwakeableEntryMessage_Result interface { - isCompleteAwakeableEntryMessage_Result() +func (x *RunEntryMessage) GetName() string { + if x != nil { + return x.Name + } + return "" } -type CompleteAwakeableEntryMessage_Value struct { - Value []byte `protobuf:"bytes,5,opt,name=value,proto3,oneof"` +type isRunEntryMessage_Result interface { + isRunEntryMessage_Result() } -type CompleteAwakeableEntryMessage_Failure struct { - Failure *Failure `protobuf:"bytes,6,opt,name=failure,proto3,oneof"` +type RunEntryMessage_Value struct { + Value []byte `protobuf:"bytes,14,opt,name=value,proto3,oneof"` } -func (*CompleteAwakeableEntryMessage_Value) isCompleteAwakeableEntryMessage_Result() {} +type RunEntryMessage_Failure struct { + Failure *Failure `protobuf:"bytes,15,opt,name=failure,proto3,oneof"` +} -func (*CompleteAwakeableEntryMessage_Failure) isCompleteAwakeableEntryMessage_Result() {} +func (*RunEntryMessage_Value) isRunEntryMessage_Result() {} + +func (*RunEntryMessage_Failure) isRunEntryMessage_Result() {} // This failure object carries user visible errors, -// e.g. invocation failure return value or failure result of an -// InvokeEntryMessage. +// e.g. invocation failure return value or failure result of an InvokeEntryMessage. type Failure struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The code should be any of the gRPC error codes, - // as defined here: - // https://github.com/grpc/grpc/blob/master/doc/statuscodes.md#status-codes-and-their-use-in-grpc - // - // If code > 16, the runtime will interpret it as code 2 (UNKNOWN). + // The code can be any HTTP status code, as described https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml. Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` // Contains a concise error message, e.g. Throwable#getMessage() in Java. Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` @@ -1425,7 +2069,7 @@ type Failure struct { func (x *Failure) Reset() { *x = Failure{} if protoimpl.UnsafeEnabled { - mi := &file_proto_protocol_protocol_proto_msgTypes[18] + mi := &file_proto_protocol_protocol_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1438,7 +2082,7 @@ func (x *Failure) String() string { func (*Failure) ProtoMessage() {} func (x *Failure) ProtoReflect() protoreflect.Message { - mi := &file_proto_protocol_protocol_proto_msgTypes[18] + mi := &file_proto_protocol_protocol_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1451,7 +2095,7 @@ func (x *Failure) ProtoReflect() protoreflect.Message { // Deprecated: Use Failure.ProtoReflect.Descriptor instead. func (*Failure) Descriptor() ([]byte, []int) { - return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{18} + return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{22} } func (x *Failure) GetCode() uint32 { @@ -1468,6 +2112,99 @@ func (x *Failure) GetMessage() string { return "" } +type Header struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *Header) Reset() { + *x = Header{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_protocol_protocol_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Header) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Header) ProtoMessage() {} + +func (x *Header) ProtoReflect() protoreflect.Message { + mi := &file_proto_protocol_protocol_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Header.ProtoReflect.Descriptor instead. +func (*Header) Descriptor() ([]byte, []int) { + return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{23} +} + +func (x *Header) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *Header) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +type Empty struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Empty) Reset() { + *x = Empty{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_protocol_protocol_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Empty) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Empty) ProtoMessage() {} + +func (x *Empty) ProtoReflect() protoreflect.Message { + mi := &file_proto_protocol_protocol_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Empty.ProtoReflect.Descriptor instead. +func (*Empty) Descriptor() ([]byte, []int) { + return file_proto_protocol_protocol_proto_rawDescGZIP(), []int{24} +} + type StartMessage_StateEntry struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1482,7 +2219,7 @@ type StartMessage_StateEntry struct { func (x *StartMessage_StateEntry) Reset() { *x = StartMessage_StateEntry{} if protoimpl.UnsafeEnabled { - mi := &file_proto_protocol_protocol_proto_msgTypes[19] + mi := &file_proto_protocol_protocol_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1495,7 +2232,7 @@ func (x *StartMessage_StateEntry) String() string { func (*StartMessage_StateEntry) ProtoMessage() {} func (x *StartMessage_StateEntry) ProtoReflect() protoreflect.Message { - mi := &file_proto_protocol_protocol_proto_msgTypes[19] + mi := &file_proto_protocol_protocol_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1536,7 +2273,7 @@ type GetStateKeysEntryMessage_StateKeys struct { func (x *GetStateKeysEntryMessage_StateKeys) Reset() { *x = GetStateKeysEntryMessage_StateKeys{} if protoimpl.UnsafeEnabled { - mi := &file_proto_protocol_protocol_proto_msgTypes[20] + mi := &file_proto_protocol_protocol_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1549,7 +2286,7 @@ func (x *GetStateKeysEntryMessage_StateKeys) String() string { func (*GetStateKeysEntryMessage_StateKeys) ProtoMessage() {} func (x *GetStateKeysEntryMessage_StateKeys) ProtoReflect() protoreflect.Message { - mi := &file_proto_protocol_protocol_proto_msgTypes[20] + mi := &file_proto_protocol_protocol_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1578,177 +2315,280 @@ var file_proto_protocol_protocol_proto_rawDesc = []byte{ 0x0a, 0x1d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x1a, 0x1b, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, - 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8d, 0x02, 0x0a, 0x0c, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x64, - 0x65, 0x62, 0x75, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, - 0x65, 0x62, 0x75, 0x67, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, - 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6b, - 0x6e, 0x6f, 0x77, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x52, 0x0a, 0x09, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, - 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x74, - 0x61, 0x72, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x70, 0x12, - 0x23, 0x0a, 0x0d, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x1a, 0x34, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xc9, 0x01, 0x0a, 0x11, 0x43, - 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x64, 0x65, - 0x78, 0x12, 0x2e, 0x0a, 0x05, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, 0x00, 0x52, 0x05, 0x65, 0x6d, 0x70, 0x74, + 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x9f, 0x02, + 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, + 0x0a, 0x08, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x64, 0x65, 0x62, 0x75, 0x67, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x6b, 0x6e, 0x6f, + 0x77, 0x6e, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0c, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x52, + 0x0a, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x35, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x65, 0x4d, + 0x61, 0x70, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x1a, 0x34, 0x0a, 0x0a, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, + 0xd6, 0x01, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x72, + 0x79, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x3b, 0x0a, 0x05, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, + 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, 0x00, 0x52, 0x05, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, + 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x66, + 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, + 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, + 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x42, 0x08, + 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x38, 0x0a, 0x11, 0x53, 0x75, 0x73, 0x70, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, + 0x0d, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0c, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x65, 0x73, 0x22, 0xbf, 0x02, 0x0a, 0x0c, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x13, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x65, + 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, + 0x48, 0x00, 0x52, 0x11, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x12, 0x72, 0x65, 0x6c, 0x61, + 0x74, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x10, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x12, 0x72, + 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x02, 0x52, 0x10, 0x72, 0x65, 0x6c, 0x61, 0x74, + 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x88, 0x01, 0x01, 0x42, 0x16, + 0x0a, 0x14, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, + 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x74, + 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x15, 0x0a, + 0x13, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x22, 0x32, 0x0a, 0x0f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x41, 0x63, 0x6b, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x74, 0x72, 0x79, + 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x65, 0x6e, + 0x74, 0x72, 0x79, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x0c, 0x0a, 0x0a, 0x45, 0x6e, 0x64, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x7d, 0x0a, 0x11, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x64, + 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x8d, 0x01, 0x0a, 0x12, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, + 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, + 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xde, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x3b, 0x0a, 0x05, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x23, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x48, 0x00, 0x52, 0x05, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x16, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, + 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, + 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x08, 0x0a, 0x06, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x52, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3e, 0x0a, 0x16, 0x43, 0x6c, + 0x65, 0x61, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x2f, 0x0a, 0x19, 0x43, 0x6c, + 0x65, 0x61, 0x72, 0x41, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xf6, 0x01, 0x0a, 0x18, + 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x58, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4b, + 0x65, 0x79, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x0f, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x61, + 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0c, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x1f, 0x0a, 0x09, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x22, 0xa3, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x6d, + 0x69, 0x73, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, - 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x42, 0x08, 0x0a, 0x06, - 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x38, 0x0a, 0x11, 0x53, 0x75, 0x73, 0x70, 0x65, 0x6e, - 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, - 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0d, 0x52, 0x0c, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, - 0x22, 0x5e, 0x0a, 0x0c, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, - 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0x32, 0x0a, 0x0f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x41, 0x63, 0x6b, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x49, - 0x6e, 0x64, 0x65, 0x78, 0x22, 0x0c, 0x0a, 0x0a, 0x45, 0x6e, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x22, 0x82, 0x01, 0x0a, 0x1b, 0x50, 0x6f, 0x6c, 0x6c, 0x49, 0x6e, 0x70, 0x75, 0x74, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x16, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, + 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xe1, 0x01, 0x0a, 0x17, 0x50, + 0x65, 0x65, 0x6b, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3b, 0x0a, 0x05, 0x65, 0x6d, 0x70, 0x74, + 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, 0x00, 0x52, 0x05, + 0x65, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0e, + 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x41, 0x0a, + 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, + 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, + 0x69, 0x6c, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xe0, + 0x02, 0x0a, 0x1b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x6d, 0x69, + 0x73, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x2b, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0f, 0x63, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x56, 0x0a, + 0x12, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x61, 0x69, 0x6c, + 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, 0x65, 0x76, 0x2e, + 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, + 0x48, 0x00, 0x52, 0x11, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x61, + 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x0d, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, 0x01, 0x52, 0x05, 0x65, 0x6d, 0x70, + 0x74, 0x79, 0x12, 0x41, 0x0a, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x0f, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x48, 0x01, 0x52, 0x07, 0x66, 0x61, + 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0c, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x22, 0xd3, 0x01, 0x0a, 0x11, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0c, 0x77, 0x61, 0x6b, 0x65, 0x5f, + 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x77, + 0x61, 0x6b, 0x65, 0x55, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x65, 0x6d, 0x70, + 0x74, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, + 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, 0x00, 0x52, + 0x05, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x41, 0x0a, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, + 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x48, 0x00, + 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x08, 0x0a, + 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xc1, 0x02, 0x0a, 0x10, 0x43, 0x61, 0x6c, 0x6c, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x21, 0x0a, 0x0c, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x12, 0x3e, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x24, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x16, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, - 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x42, 0x08, 0x0a, - 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x7f, 0x0a, 0x18, 0x4f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, - 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x66, - 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, + 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x83, 0x02, 0x0a, 0x16, + 0x4f, 0x6e, 0x65, 0x57, 0x61, 0x79, 0x43, 0x61, 0x6c, 0x6c, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x68, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x09, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, + 0x76, 0x6f, 0x6b, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0a, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, - 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x42, 0x08, - 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xbd, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x0d, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, 0x00, 0x52, 0x05, 0x65, 0x6d, - 0x70, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, - 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x66, - 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, - 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, - 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x42, 0x08, - 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3e, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x2a, 0x0a, 0x16, 0x43, 0x6c, 0x65, 0x61, - 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x22, 0x1b, 0x0a, 0x19, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x41, 0x6c, 0x6c, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x22, 0xe2, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4b, 0x65, - 0x79, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x58, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, 0x2e, - 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x47, 0x65, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x48, - 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x66, 0x61, 0x69, 0x6c, - 0x75, 0x72, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, 0x65, 0x76, 0x2e, - 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, - 0x48, 0x00, 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x1a, 0x1f, 0x0a, 0x09, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x42, 0x08, 0x0a, 0x06, - 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xb2, 0x01, 0x0a, 0x11, 0x53, 0x6c, 0x65, 0x65, 0x70, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0c, - 0x77, 0x61, 0x6b, 0x65, 0x5f, 0x75, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0a, 0x77, 0x61, 0x6b, 0x65, 0x55, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2e, - 0x0a, 0x05, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, 0x00, 0x52, 0x05, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x41, - 0x0a, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x25, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, - 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, - 0x65, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xdb, 0x01, 0x0a, 0x12, - 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x65, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0e, 0x20, - 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x41, 0x0a, 0x07, - 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, - 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, - 0x6c, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x42, - 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xa1, 0x01, 0x0a, 0x1c, 0x42, 0x61, - 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x49, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, - 0x0b, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, - 0x0a, 0x09, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, - 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x0a, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x7c, 0x0a, - 0x15, 0x41, 0x77, 0x61, 0x6b, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x90, 0x01, 0x0a, 0x15, 0x41, 0x77, 0x61, 0x6b, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x0f, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, + 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x22, 0xa8, 0x01, 0x0a, 0x1d, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x41, 0x77, 0x61, 0x6b, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, - 0x65, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x94, 0x01, 0x0a, 0x1d, - 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x77, 0x61, 0x6b, 0x65, 0x61, 0x62, 0x6c, - 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, - 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x22, 0x37, 0x0a, 0x07, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, - 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x85, 0x02, 0x0a, 0x20, - 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, - 0x42, 0x0d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x75, - 0x68, 0x61, 0x6d, 0x61, 0x64, 0x61, 0x7a, 0x6d, 0x79, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2d, 0x73, 0x64, 0x6b, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0xa2, 0x02, 0x04, 0x44, 0x52, 0x53, 0x50, 0xaa, 0x02, 0x1c, 0x44, 0x65, 0x76, 0x2e, 0x52, - 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0xca, 0x02, 0x1c, 0x44, 0x65, 0x76, 0x5c, 0x52, 0x65, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0xe2, 0x02, 0x28, 0x44, 0x65, 0x76, 0x5c, 0x52, 0x65, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0xea, 0x02, 0x1f, 0x44, 0x65, 0x76, 0x3a, 0x3a, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x3a, 0x3a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x3a, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, + 0x8a, 0x01, 0x0a, 0x0f, 0x52, 0x75, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0e, 0x20, 0x01, + 0x28, 0x0c, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x66, + 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x64, + 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x46, 0x61, 0x69, 0x6c, + 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x37, 0x0a, 0x07, + 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x30, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x2a, 0x4a, 0x0a, 0x16, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x24, 0x53, 0x45, + 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x56, + 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x56, 0x31, 0x10, 0x01, 0x42, 0xfc, 0x01, 0x0a, + 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x42, 0x0d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, + 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x64, 0x65, 0x76, 0x2f, 0x73, 0x64, 0x6b, 0x2d, 0x67, 0x6f, + 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0xa2, 0x02, 0x04, 0x44, 0x52, 0x53, 0x50, + 0xaa, 0x02, 0x1c, 0x44, 0x65, 0x76, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0xca, + 0x02, 0x1c, 0x44, 0x65, 0x76, 0x5c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0xe2, 0x02, + 0x28, 0x44, 0x65, 0x76, 0x5c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x5c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1f, 0x44, 0x65, 0x76, 0x3a, + 0x3a, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x3a, 0x3a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x3a, 0x3a, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -1763,51 +2603,67 @@ func file_proto_protocol_protocol_proto_rawDescGZIP() []byte { return file_proto_protocol_protocol_proto_rawDescData } -var file_proto_protocol_protocol_proto_msgTypes = make([]protoimpl.MessageInfo, 21) +var file_proto_protocol_protocol_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_proto_protocol_protocol_proto_msgTypes = make([]protoimpl.MessageInfo, 27) var file_proto_protocol_protocol_proto_goTypes = []interface{}{ - (*StartMessage)(nil), // 0: dev.restate.service.protocol.StartMessage - (*CompletionMessage)(nil), // 1: dev.restate.service.protocol.CompletionMessage - (*SuspensionMessage)(nil), // 2: dev.restate.service.protocol.SuspensionMessage - (*ErrorMessage)(nil), // 3: dev.restate.service.protocol.ErrorMessage - (*EntryAckMessage)(nil), // 4: dev.restate.service.protocol.EntryAckMessage - (*EndMessage)(nil), // 5: dev.restate.service.protocol.EndMessage - (*PollInputStreamEntryMessage)(nil), // 6: dev.restate.service.protocol.PollInputStreamEntryMessage - (*OutputStreamEntryMessage)(nil), // 7: dev.restate.service.protocol.OutputStreamEntryMessage - (*GetStateEntryMessage)(nil), // 8: dev.restate.service.protocol.GetStateEntryMessage - (*SetStateEntryMessage)(nil), // 9: dev.restate.service.protocol.SetStateEntryMessage - (*ClearStateEntryMessage)(nil), // 10: dev.restate.service.protocol.ClearStateEntryMessage - (*ClearAllStateEntryMessage)(nil), // 11: dev.restate.service.protocol.ClearAllStateEntryMessage - (*GetStateKeysEntryMessage)(nil), // 12: dev.restate.service.protocol.GetStateKeysEntryMessage - (*SleepEntryMessage)(nil), // 13: dev.restate.service.protocol.SleepEntryMessage - (*InvokeEntryMessage)(nil), // 14: dev.restate.service.protocol.InvokeEntryMessage - (*BackgroundInvokeEntryMessage)(nil), // 15: dev.restate.service.protocol.BackgroundInvokeEntryMessage - (*AwakeableEntryMessage)(nil), // 16: dev.restate.service.protocol.AwakeableEntryMessage - (*CompleteAwakeableEntryMessage)(nil), // 17: dev.restate.service.protocol.CompleteAwakeableEntryMessage - (*Failure)(nil), // 18: dev.restate.service.protocol.Failure - (*StartMessage_StateEntry)(nil), // 19: dev.restate.service.protocol.StartMessage.StateEntry - (*GetStateKeysEntryMessage_StateKeys)(nil), // 20: dev.restate.service.protocol.GetStateKeysEntryMessage.StateKeys - (*emptypb.Empty)(nil), // 21: google.protobuf.Empty + (ServiceProtocolVersion)(0), // 0: dev.restate.service.protocol.ServiceProtocolVersion + (*StartMessage)(nil), // 1: dev.restate.service.protocol.StartMessage + (*CompletionMessage)(nil), // 2: dev.restate.service.protocol.CompletionMessage + (*SuspensionMessage)(nil), // 3: dev.restate.service.protocol.SuspensionMessage + (*ErrorMessage)(nil), // 4: dev.restate.service.protocol.ErrorMessage + (*EntryAckMessage)(nil), // 5: dev.restate.service.protocol.EntryAckMessage + (*EndMessage)(nil), // 6: dev.restate.service.protocol.EndMessage + (*InputEntryMessage)(nil), // 7: dev.restate.service.protocol.InputEntryMessage + (*OutputEntryMessage)(nil), // 8: dev.restate.service.protocol.OutputEntryMessage + (*GetStateEntryMessage)(nil), // 9: dev.restate.service.protocol.GetStateEntryMessage + (*SetStateEntryMessage)(nil), // 10: dev.restate.service.protocol.SetStateEntryMessage + (*ClearStateEntryMessage)(nil), // 11: dev.restate.service.protocol.ClearStateEntryMessage + (*ClearAllStateEntryMessage)(nil), // 12: dev.restate.service.protocol.ClearAllStateEntryMessage + (*GetStateKeysEntryMessage)(nil), // 13: dev.restate.service.protocol.GetStateKeysEntryMessage + (*GetPromiseEntryMessage)(nil), // 14: dev.restate.service.protocol.GetPromiseEntryMessage + (*PeekPromiseEntryMessage)(nil), // 15: dev.restate.service.protocol.PeekPromiseEntryMessage + (*CompletePromiseEntryMessage)(nil), // 16: dev.restate.service.protocol.CompletePromiseEntryMessage + (*SleepEntryMessage)(nil), // 17: dev.restate.service.protocol.SleepEntryMessage + (*CallEntryMessage)(nil), // 18: dev.restate.service.protocol.CallEntryMessage + (*OneWayCallEntryMessage)(nil), // 19: dev.restate.service.protocol.OneWayCallEntryMessage + (*AwakeableEntryMessage)(nil), // 20: dev.restate.service.protocol.AwakeableEntryMessage + (*CompleteAwakeableEntryMessage)(nil), // 21: dev.restate.service.protocol.CompleteAwakeableEntryMessage + (*RunEntryMessage)(nil), // 22: dev.restate.service.protocol.RunEntryMessage + (*Failure)(nil), // 23: dev.restate.service.protocol.Failure + (*Header)(nil), // 24: dev.restate.service.protocol.Header + (*Empty)(nil), // 25: dev.restate.service.protocol.Empty + (*StartMessage_StateEntry)(nil), // 26: dev.restate.service.protocol.StartMessage.StateEntry + (*GetStateKeysEntryMessage_StateKeys)(nil), // 27: dev.restate.service.protocol.GetStateKeysEntryMessage.StateKeys } var file_proto_protocol_protocol_proto_depIdxs = []int32{ - 19, // 0: dev.restate.service.protocol.StartMessage.state_map:type_name -> dev.restate.service.protocol.StartMessage.StateEntry - 21, // 1: dev.restate.service.protocol.CompletionMessage.empty:type_name -> google.protobuf.Empty - 18, // 2: dev.restate.service.protocol.CompletionMessage.failure:type_name -> dev.restate.service.protocol.Failure - 18, // 3: dev.restate.service.protocol.PollInputStreamEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure - 18, // 4: dev.restate.service.protocol.OutputStreamEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure - 21, // 5: dev.restate.service.protocol.GetStateEntryMessage.empty:type_name -> google.protobuf.Empty - 18, // 6: dev.restate.service.protocol.GetStateEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure - 20, // 7: dev.restate.service.protocol.GetStateKeysEntryMessage.value:type_name -> dev.restate.service.protocol.GetStateKeysEntryMessage.StateKeys - 18, // 8: dev.restate.service.protocol.GetStateKeysEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure - 21, // 9: dev.restate.service.protocol.SleepEntryMessage.empty:type_name -> google.protobuf.Empty - 18, // 10: dev.restate.service.protocol.SleepEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure - 18, // 11: dev.restate.service.protocol.InvokeEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure - 18, // 12: dev.restate.service.protocol.AwakeableEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure - 18, // 13: dev.restate.service.protocol.CompleteAwakeableEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure - 14, // [14:14] is the sub-list for method output_type - 14, // [14:14] is the sub-list for method input_type - 14, // [14:14] is the sub-list for extension type_name - 14, // [14:14] is the sub-list for extension extendee - 0, // [0:14] is the sub-list for field type_name + 26, // 0: dev.restate.service.protocol.StartMessage.state_map:type_name -> dev.restate.service.protocol.StartMessage.StateEntry + 25, // 1: dev.restate.service.protocol.CompletionMessage.empty:type_name -> dev.restate.service.protocol.Empty + 23, // 2: dev.restate.service.protocol.CompletionMessage.failure:type_name -> dev.restate.service.protocol.Failure + 24, // 3: dev.restate.service.protocol.InputEntryMessage.headers:type_name -> dev.restate.service.protocol.Header + 23, // 4: dev.restate.service.protocol.OutputEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure + 25, // 5: dev.restate.service.protocol.GetStateEntryMessage.empty:type_name -> dev.restate.service.protocol.Empty + 23, // 6: dev.restate.service.protocol.GetStateEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure + 27, // 7: dev.restate.service.protocol.GetStateKeysEntryMessage.value:type_name -> dev.restate.service.protocol.GetStateKeysEntryMessage.StateKeys + 23, // 8: dev.restate.service.protocol.GetStateKeysEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure + 23, // 9: dev.restate.service.protocol.GetPromiseEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure + 25, // 10: dev.restate.service.protocol.PeekPromiseEntryMessage.empty:type_name -> dev.restate.service.protocol.Empty + 23, // 11: dev.restate.service.protocol.PeekPromiseEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure + 23, // 12: dev.restate.service.protocol.CompletePromiseEntryMessage.completion_failure:type_name -> dev.restate.service.protocol.Failure + 25, // 13: dev.restate.service.protocol.CompletePromiseEntryMessage.empty:type_name -> dev.restate.service.protocol.Empty + 23, // 14: dev.restate.service.protocol.CompletePromiseEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure + 25, // 15: dev.restate.service.protocol.SleepEntryMessage.empty:type_name -> dev.restate.service.protocol.Empty + 23, // 16: dev.restate.service.protocol.SleepEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure + 24, // 17: dev.restate.service.protocol.CallEntryMessage.headers:type_name -> dev.restate.service.protocol.Header + 23, // 18: dev.restate.service.protocol.CallEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure + 24, // 19: dev.restate.service.protocol.OneWayCallEntryMessage.headers:type_name -> dev.restate.service.protocol.Header + 23, // 20: dev.restate.service.protocol.AwakeableEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure + 23, // 21: dev.restate.service.protocol.CompleteAwakeableEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure + 23, // 22: dev.restate.service.protocol.RunEntryMessage.failure:type_name -> dev.restate.service.protocol.Failure + 23, // [23:23] is the sub-list for method output_type + 23, // [23:23] is the sub-list for method input_type + 23, // [23:23] is the sub-list for extension type_name + 23, // [23:23] is the sub-list for extension extendee + 0, // [0:23] is the sub-list for field type_name } func init() { file_proto_protocol_protocol_proto_init() } @@ -1889,7 +2745,7 @@ func file_proto_protocol_protocol_proto_init() { } } file_proto_protocol_protocol_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PollInputStreamEntryMessage); i { + switch v := v.(*InputEntryMessage); i { case 0: return &v.state case 1: @@ -1901,7 +2757,7 @@ func file_proto_protocol_protocol_proto_init() { } } file_proto_protocol_protocol_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*OutputStreamEntryMessage); i { + switch v := v.(*OutputEntryMessage); i { case 0: return &v.state case 1: @@ -1973,7 +2829,7 @@ func file_proto_protocol_protocol_proto_init() { } } file_proto_protocol_protocol_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SleepEntryMessage); i { + switch v := v.(*GetPromiseEntryMessage); i { case 0: return &v.state case 1: @@ -1985,7 +2841,7 @@ func file_proto_protocol_protocol_proto_init() { } } file_proto_protocol_protocol_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InvokeEntryMessage); i { + switch v := v.(*PeekPromiseEntryMessage); i { case 0: return &v.state case 1: @@ -1997,7 +2853,7 @@ func file_proto_protocol_protocol_proto_init() { } } file_proto_protocol_protocol_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BackgroundInvokeEntryMessage); i { + switch v := v.(*CompletePromiseEntryMessage); i { case 0: return &v.state case 1: @@ -2009,7 +2865,7 @@ func file_proto_protocol_protocol_proto_init() { } } file_proto_protocol_protocol_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AwakeableEntryMessage); i { + switch v := v.(*SleepEntryMessage); i { case 0: return &v.state case 1: @@ -2021,7 +2877,7 @@ func file_proto_protocol_protocol_proto_init() { } } file_proto_protocol_protocol_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CompleteAwakeableEntryMessage); i { + switch v := v.(*CallEntryMessage); i { case 0: return &v.state case 1: @@ -2033,7 +2889,7 @@ func file_proto_protocol_protocol_proto_init() { } } file_proto_protocol_protocol_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Failure); i { + switch v := v.(*OneWayCallEntryMessage); i { case 0: return &v.state case 1: @@ -2045,7 +2901,7 @@ func file_proto_protocol_protocol_proto_init() { } } file_proto_protocol_protocol_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StartMessage_StateEntry); i { + switch v := v.(*AwakeableEntryMessage); i { case 0: return &v.state case 1: @@ -2057,6 +2913,78 @@ func file_proto_protocol_protocol_proto_init() { } } file_proto_protocol_protocol_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CompleteAwakeableEntryMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_protocol_protocol_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RunEntryMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_protocol_protocol_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Failure); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_protocol_protocol_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Header); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_protocol_protocol_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Empty); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_protocol_protocol_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StartMessage_StateEntry); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_protocol_protocol_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetStateKeysEntryMessage_StateKeys); i { case 0: return &v.state @@ -2074,13 +3002,10 @@ func file_proto_protocol_protocol_proto_init() { (*CompletionMessage_Value)(nil), (*CompletionMessage_Failure)(nil), } - file_proto_protocol_protocol_proto_msgTypes[6].OneofWrappers = []interface{}{ - (*PollInputStreamEntryMessage_Value)(nil), - (*PollInputStreamEntryMessage_Failure)(nil), - } + file_proto_protocol_protocol_proto_msgTypes[3].OneofWrappers = []interface{}{} file_proto_protocol_protocol_proto_msgTypes[7].OneofWrappers = []interface{}{ - (*OutputStreamEntryMessage_Value)(nil), - (*OutputStreamEntryMessage_Failure)(nil), + (*OutputEntryMessage_Value)(nil), + (*OutputEntryMessage_Failure)(nil), } file_proto_protocol_protocol_proto_msgTypes[8].OneofWrappers = []interface{}{ (*GetStateEntryMessage_Empty)(nil), @@ -2092,33 +3017,53 @@ func file_proto_protocol_protocol_proto_init() { (*GetStateKeysEntryMessage_Failure)(nil), } file_proto_protocol_protocol_proto_msgTypes[13].OneofWrappers = []interface{}{ - (*SleepEntryMessage_Empty)(nil), - (*SleepEntryMessage_Failure)(nil), + (*GetPromiseEntryMessage_Value)(nil), + (*GetPromiseEntryMessage_Failure)(nil), } file_proto_protocol_protocol_proto_msgTypes[14].OneofWrappers = []interface{}{ - (*InvokeEntryMessage_Value)(nil), - (*InvokeEntryMessage_Failure)(nil), + (*PeekPromiseEntryMessage_Empty)(nil), + (*PeekPromiseEntryMessage_Value)(nil), + (*PeekPromiseEntryMessage_Failure)(nil), + } + file_proto_protocol_protocol_proto_msgTypes[15].OneofWrappers = []interface{}{ + (*CompletePromiseEntryMessage_CompletionValue)(nil), + (*CompletePromiseEntryMessage_CompletionFailure)(nil), + (*CompletePromiseEntryMessage_Empty)(nil), + (*CompletePromiseEntryMessage_Failure)(nil), } file_proto_protocol_protocol_proto_msgTypes[16].OneofWrappers = []interface{}{ + (*SleepEntryMessage_Empty)(nil), + (*SleepEntryMessage_Failure)(nil), + } + file_proto_protocol_protocol_proto_msgTypes[17].OneofWrappers = []interface{}{ + (*CallEntryMessage_Value)(nil), + (*CallEntryMessage_Failure)(nil), + } + file_proto_protocol_protocol_proto_msgTypes[19].OneofWrappers = []interface{}{ (*AwakeableEntryMessage_Value)(nil), (*AwakeableEntryMessage_Failure)(nil), } - file_proto_protocol_protocol_proto_msgTypes[17].OneofWrappers = []interface{}{ + file_proto_protocol_protocol_proto_msgTypes[20].OneofWrappers = []interface{}{ (*CompleteAwakeableEntryMessage_Value)(nil), (*CompleteAwakeableEntryMessage_Failure)(nil), } + file_proto_protocol_protocol_proto_msgTypes[21].OneofWrappers = []interface{}{ + (*RunEntryMessage_Value)(nil), + (*RunEntryMessage_Failure)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_protocol_protocol_proto_rawDesc, - NumEnums: 0, - NumMessages: 21, + NumEnums: 1, + NumMessages: 27, NumExtensions: 0, NumServices: 0, }, GoTypes: file_proto_protocol_protocol_proto_goTypes, DependencyIndexes: file_proto_protocol_protocol_proto_depIdxs, + EnumInfos: file_proto_protocol_protocol_proto_enumTypes, MessageInfos: file_proto_protocol_protocol_proto_msgTypes, }.Build() File_proto_protocol_protocol_proto = out.File diff --git a/generated/proto/services/services.pb.go b/generated/proto/services/services.pb.go deleted file mode 100644 index f3ceaf3..0000000 --- a/generated/proto/services/services.pb.go +++ /dev/null @@ -1,1151 +0,0 @@ -// Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH -// -// This file is part of the Restate service protocol, which is -// released under the MIT license. -// -// You can find a copy of the license in file LICENSE in the root -// directory of this repository or package, or at -// https://github.com/restatedev/proto/blob/main/LICENSE - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc (unknown) -// source: proto/services/services.proto - -// -//This package contains internal service interfaces - -package services - -import ( - _ "github.com/restatedev/sdk-go/generated/dev/restate" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - emptypb "google.golang.org/protobuf/types/known/emptypb" - _ "google.golang.org/protobuf/types/known/structpb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type StartRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // User provided operation id, this is used as idempotency key. - OperationId string `protobuf:"bytes,1,opt,name=operation_id,json=operationId,proto3" json:"operation_id,omitempty"` - // Stream id to uniquely identify a open stream between client and Restate. - // There can be at most one open stream at the same time. - StreamId string `protobuf:"bytes,2,opt,name=stream_id,json=streamId,proto3" json:"stream_id,omitempty"` - // Retention period for the response in seconds. - // After the invocation completes, the response will be persisted for the - // given duration. Afterwards, the system will cleanup the response and treats - // any subsequent invocation with same operation_id as new. - // - // If not set, 30 minutes will be used as retention period. - RetentionPeriodSec uint32 `protobuf:"varint,3,opt,name=retention_period_sec,json=retentionPeriodSec,proto3" json:"retention_period_sec,omitempty"` - // Argument of the invocation - Argument []byte `protobuf:"bytes,4,opt,name=argument,proto3" json:"argument,omitempty"` -} - -func (x *StartRequest) Reset() { - *x = StartRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_services_services_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *StartRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StartRequest) ProtoMessage() {} - -func (x *StartRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_services_services_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StartRequest.ProtoReflect.Descriptor instead. -func (*StartRequest) Descriptor() ([]byte, []int) { - return file_proto_services_services_proto_rawDescGZIP(), []int{0} -} - -func (x *StartRequest) GetOperationId() string { - if x != nil { - return x.OperationId - } - return "" -} - -func (x *StartRequest) GetStreamId() string { - if x != nil { - return x.StreamId - } - return "" -} - -func (x *StartRequest) GetRetentionPeriodSec() uint32 { - if x != nil { - return x.RetentionPeriodSec - } - return 0 -} - -func (x *StartRequest) GetArgument() []byte { - if x != nil { - return x.Argument - } - return nil -} - -type StartResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to InvocationStatus: - // - // *StartResponse_Executing - // *StartResponse_Completed - InvocationStatus isStartResponse_InvocationStatus `protobuf_oneof:"invocation_status"` -} - -func (x *StartResponse) Reset() { - *x = StartResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_services_services_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *StartResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StartResponse) ProtoMessage() {} - -func (x *StartResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_services_services_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StartResponse.ProtoReflect.Descriptor instead. -func (*StartResponse) Descriptor() ([]byte, []int) { - return file_proto_services_services_proto_rawDescGZIP(), []int{1} -} - -func (m *StartResponse) GetInvocationStatus() isStartResponse_InvocationStatus { - if m != nil { - return m.InvocationStatus - } - return nil -} - -func (x *StartResponse) GetExecuting() []byte { - if x, ok := x.GetInvocationStatus().(*StartResponse_Executing); ok { - return x.Executing - } - return nil -} - -func (x *StartResponse) GetCompleted() *GetResultResponse { - if x, ok := x.GetInvocationStatus().(*StartResponse_Completed); ok { - return x.Completed - } - return nil -} - -type isStartResponse_InvocationStatus interface { - isStartResponse_InvocationStatus() -} - -type StartResponse_Executing struct { - // Contains the concatenated first messages of the stream, encoded using the - // same framing used by service-protocol - Executing []byte `protobuf:"bytes,1,opt,name=executing,proto3,oneof"` -} - -type StartResponse_Completed struct { - // Contains the result of the invocation - Completed *GetResultResponse `protobuf:"bytes,2,opt,name=completed,proto3,oneof"` -} - -func (*StartResponse_Executing) isStartResponse_InvocationStatus() {} - -func (*StartResponse_Completed) isStartResponse_InvocationStatus() {} - -type SendRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // User provided operation id, this is used as idempotency key. - OperationId string `protobuf:"bytes,1,opt,name=operation_id,json=operationId,proto3" json:"operation_id,omitempty"` - // Stream id to uniquely identify a open stream between client and Restate. - // There can be at most one open stream at the same time. - StreamId string `protobuf:"bytes,2,opt,name=stream_id,json=streamId,proto3" json:"stream_id,omitempty"` - // Contains the concatenated messages of the stream, encoded using the same - // framing used by service-protocol - Messages []byte `protobuf:"bytes,3,opt,name=messages,proto3" json:"messages,omitempty"` -} - -func (x *SendRequest) Reset() { - *x = SendRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_services_services_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SendRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SendRequest) ProtoMessage() {} - -func (x *SendRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_services_services_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SendRequest.ProtoReflect.Descriptor instead. -func (*SendRequest) Descriptor() ([]byte, []int) { - return file_proto_services_services_proto_rawDescGZIP(), []int{2} -} - -func (x *SendRequest) GetOperationId() string { - if x != nil { - return x.OperationId - } - return "" -} - -func (x *SendRequest) GetStreamId() string { - if x != nil { - return x.StreamId - } - return "" -} - -func (x *SendRequest) GetMessages() []byte { - if x != nil { - return x.Messages - } - return nil -} - -type SendResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Response: - // - // *SendResponse_Ok - // *SendResponse_InvalidStream - // *SendResponse_InvocationCompleted - Response isSendResponse_Response `protobuf_oneof:"response"` -} - -func (x *SendResponse) Reset() { - *x = SendResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_services_services_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *SendResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*SendResponse) ProtoMessage() {} - -func (x *SendResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_services_services_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use SendResponse.ProtoReflect.Descriptor instead. -func (*SendResponse) Descriptor() ([]byte, []int) { - return file_proto_services_services_proto_rawDescGZIP(), []int{3} -} - -func (m *SendResponse) GetResponse() isSendResponse_Response { - if m != nil { - return m.Response - } - return nil -} - -func (x *SendResponse) GetOk() *emptypb.Empty { - if x, ok := x.GetResponse().(*SendResponse_Ok); ok { - return x.Ok - } - return nil -} - -func (x *SendResponse) GetInvalidStream() *emptypb.Empty { - if x, ok := x.GetResponse().(*SendResponse_InvalidStream); ok { - return x.InvalidStream - } - return nil -} - -func (x *SendResponse) GetInvocationCompleted() *emptypb.Empty { - if x, ok := x.GetResponse().(*SendResponse_InvocationCompleted); ok { - return x.InvocationCompleted - } - return nil -} - -type isSendResponse_Response interface { - isSendResponse_Response() -} - -type SendResponse_Ok struct { - Ok *emptypb.Empty `protobuf:"bytes,1,opt,name=ok,proto3,oneof"` -} - -type SendResponse_InvalidStream struct { - // This means the provided stream_id is invalid, and it should not be - // reused, nor the client should create a new stream using Start(). The - // client can instead read the invocation result using GetResult(). - InvalidStream *emptypb.Empty `protobuf:"bytes,2,opt,name=invalid_stream,json=invalidStream,proto3,oneof"` -} - -type SendResponse_InvocationCompleted struct { - // This means the invocation is completed, and the result should be - // collected using GetResult - InvocationCompleted *emptypb.Empty `protobuf:"bytes,3,opt,name=invocation_completed,json=invocationCompleted,proto3,oneof"` -} - -func (*SendResponse_Ok) isSendResponse_Response() {} - -func (*SendResponse_InvalidStream) isSendResponse_Response() {} - -func (*SendResponse_InvocationCompleted) isSendResponse_Response() {} - -type RecvRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // User provided operation id, this is used as idempotency key. - OperationId string `protobuf:"bytes,1,opt,name=operation_id,json=operationId,proto3" json:"operation_id,omitempty"` - // Stream id to uniquely identify a open stream between client and Restate. - // There can be at most one open stream at the same time. - StreamId string `protobuf:"bytes,2,opt,name=stream_id,json=streamId,proto3" json:"stream_id,omitempty"` -} - -func (x *RecvRequest) Reset() { - *x = RecvRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_services_services_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RecvRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RecvRequest) ProtoMessage() {} - -func (x *RecvRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_services_services_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RecvRequest.ProtoReflect.Descriptor instead. -func (*RecvRequest) Descriptor() ([]byte, []int) { - return file_proto_services_services_proto_rawDescGZIP(), []int{4} -} - -func (x *RecvRequest) GetOperationId() string { - if x != nil { - return x.OperationId - } - return "" -} - -func (x *RecvRequest) GetStreamId() string { - if x != nil { - return x.StreamId - } - return "" -} - -type RecvResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Response: - // - // *RecvResponse_Messages - // *RecvResponse_InvalidStream - // *RecvResponse_InvocationCompleted - Response isRecvResponse_Response `protobuf_oneof:"response"` -} - -func (x *RecvResponse) Reset() { - *x = RecvResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_services_services_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RecvResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RecvResponse) ProtoMessage() {} - -func (x *RecvResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_services_services_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RecvResponse.ProtoReflect.Descriptor instead. -func (*RecvResponse) Descriptor() ([]byte, []int) { - return file_proto_services_services_proto_rawDescGZIP(), []int{5} -} - -func (m *RecvResponse) GetResponse() isRecvResponse_Response { - if m != nil { - return m.Response - } - return nil -} - -func (x *RecvResponse) GetMessages() []byte { - if x, ok := x.GetResponse().(*RecvResponse_Messages); ok { - return x.Messages - } - return nil -} - -func (x *RecvResponse) GetInvalidStream() *emptypb.Empty { - if x, ok := x.GetResponse().(*RecvResponse_InvalidStream); ok { - return x.InvalidStream - } - return nil -} - -func (x *RecvResponse) GetInvocationCompleted() *emptypb.Empty { - if x, ok := x.GetResponse().(*RecvResponse_InvocationCompleted); ok { - return x.InvocationCompleted - } - return nil -} - -type isRecvResponse_Response interface { - isRecvResponse_Response() -} - -type RecvResponse_Messages struct { - // Contains the concatenated messages of the stream, encoded using the same - // framing used by service-protocol - Messages []byte `protobuf:"bytes,1,opt,name=messages,proto3,oneof"` -} - -type RecvResponse_InvalidStream struct { - // This means the provided stream_id is invalid, and it should not be - // reused, nor the client should create a new stream using Start(). The - // client can instead read the invocation result using GetResult(). - InvalidStream *emptypb.Empty `protobuf:"bytes,2,opt,name=invalid_stream,json=invalidStream,proto3,oneof"` -} - -type RecvResponse_InvocationCompleted struct { - // This means the invocation is completed, and the result should be - // collected using GetResult - InvocationCompleted *emptypb.Empty `protobuf:"bytes,3,opt,name=invocation_completed,json=invocationCompleted,proto3,oneof"` -} - -func (*RecvResponse_Messages) isRecvResponse_Response() {} - -func (*RecvResponse_InvalidStream) isRecvResponse_Response() {} - -func (*RecvResponse_InvocationCompleted) isRecvResponse_Response() {} - -type GetResultRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // User provided operation id, this is used as idempotency key. - OperationId string `protobuf:"bytes,1,opt,name=operation_id,json=operationId,proto3" json:"operation_id,omitempty"` -} - -func (x *GetResultRequest) Reset() { - *x = GetResultRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_services_services_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetResultRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetResultRequest) ProtoMessage() {} - -func (x *GetResultRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_services_services_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetResultRequest.ProtoReflect.Descriptor instead. -func (*GetResultRequest) Descriptor() ([]byte, []int) { - return file_proto_services_services_proto_rawDescGZIP(), []int{6} -} - -func (x *GetResultRequest) GetOperationId() string { - if x != nil { - return x.OperationId - } - return "" -} - -type GetResultResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Response: - // - // *GetResultResponse_None - // *GetResultResponse_Success - // *GetResultResponse_Failure - Response isGetResultResponse_Response `protobuf_oneof:"response"` - // Timestamp of the response expiry time in RFC3339. - // Empty if response = none - ExpiryTime string `protobuf:"bytes,15,opt,name=expiry_time,json=expiryTime,proto3" json:"expiry_time,omitempty"` -} - -func (x *GetResultResponse) Reset() { - *x = GetResultResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_services_services_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetResultResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetResultResponse) ProtoMessage() {} - -func (x *GetResultResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_services_services_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetResultResponse.ProtoReflect.Descriptor instead. -func (*GetResultResponse) Descriptor() ([]byte, []int) { - return file_proto_services_services_proto_rawDescGZIP(), []int{7} -} - -func (m *GetResultResponse) GetResponse() isGetResultResponse_Response { - if m != nil { - return m.Response - } - return nil -} - -func (x *GetResultResponse) GetNone() *emptypb.Empty { - if x, ok := x.GetResponse().(*GetResultResponse_None); ok { - return x.None - } - return nil -} - -func (x *GetResultResponse) GetSuccess() []byte { - if x, ok := x.GetResponse().(*GetResultResponse_Success); ok { - return x.Success - } - return nil -} - -func (x *GetResultResponse) GetFailure() *GetResultResponse_InvocationFailure { - if x, ok := x.GetResponse().(*GetResultResponse_Failure); ok { - return x.Failure - } - return nil -} - -func (x *GetResultResponse) GetExpiryTime() string { - if x != nil { - return x.ExpiryTime - } - return "" -} - -type isGetResultResponse_Response interface { - isGetResultResponse_Response() -} - -type GetResultResponse_None struct { - // See GetResult documentation - None *emptypb.Empty `protobuf:"bytes,1,opt,name=none,proto3,oneof"` -} - -type GetResultResponse_Success struct { - Success []byte `protobuf:"bytes,2,opt,name=success,proto3,oneof"` -} - -type GetResultResponse_Failure struct { - Failure *GetResultResponse_InvocationFailure `protobuf:"bytes,3,opt,name=failure,proto3,oneof"` -} - -func (*GetResultResponse_None) isGetResultResponse_Response() {} - -func (*GetResultResponse_Success) isGetResultResponse_Response() {} - -func (*GetResultResponse_Failure) isGetResultResponse_Response() {} - -type CleanupRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // User provided operation id, this is used as idempotency key. - OperationId string `protobuf:"bytes,1,opt,name=operation_id,json=operationId,proto3" json:"operation_id,omitempty"` -} - -func (x *CleanupRequest) Reset() { - *x = CleanupRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_services_services_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CleanupRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CleanupRequest) ProtoMessage() {} - -func (x *CleanupRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_services_services_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CleanupRequest.ProtoReflect.Descriptor instead. -func (*CleanupRequest) Descriptor() ([]byte, []int) { - return file_proto_services_services_proto_rawDescGZIP(), []int{8} -} - -func (x *CleanupRequest) GetOperationId() string { - if x != nil { - return x.OperationId - } - return "" -} - -type GetResultResponse_InvocationFailure struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` - Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` -} - -func (x *GetResultResponse_InvocationFailure) Reset() { - *x = GetResultResponse_InvocationFailure{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_services_services_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetResultResponse_InvocationFailure) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetResultResponse_InvocationFailure) ProtoMessage() {} - -func (x *GetResultResponse_InvocationFailure) ProtoReflect() protoreflect.Message { - mi := &file_proto_services_services_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetResultResponse_InvocationFailure.ProtoReflect.Descriptor instead. -func (*GetResultResponse_InvocationFailure) Descriptor() ([]byte, []int) { - return file_proto_services_services_proto_rawDescGZIP(), []int{7, 0} -} - -func (x *GetResultResponse_InvocationFailure) GetCode() uint32 { - if x != nil { - return x.Code - } - return 0 -} - -func (x *GetResultResponse_InvocationFailure) GetMessage() string { - if x != nil { - return x.Message - } - return "" -} - -var File_proto_services_services_proto protoreflect.FileDescriptor - -var file_proto_services_services_proto_rawDesc = []byte{ - 0x0a, 0x1d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x1c, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x1a, 0x15, 0x64, - 0x65, 0x76, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x65, 0x78, 0x74, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0xa2, 0x01, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x27, 0x0a, 0x0c, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0x90, 0x82, 0x19, 0x00, 0x52, 0x0b, 0x6f, 0x70, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x5f, 0x73, 0x65, 0x63, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x65, 0x72, 0x69, 0x6f, 0x64, 0x53, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x72, 0x67, 0x75, - 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x72, 0x67, 0x75, - 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x95, 0x01, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x09, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x09, 0x65, 0x78, 0x65, - 0x63, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x4f, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, - 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x64, 0x65, 0x76, 0x2e, - 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x09, 0x63, 0x6f, - 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x42, 0x13, 0x0a, 0x11, 0x69, 0x6e, 0x76, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x6f, 0x0a, 0x0b, - 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0c, 0x6f, - 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x04, 0x90, 0x82, 0x19, 0x00, 0x52, 0x0b, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, - 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0xd2, 0x01, - 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, - 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x48, 0x00, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x3f, 0x0a, 0x0e, 0x69, 0x6e, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, 0x00, 0x52, 0x0d, 0x69, 0x6e, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x4b, 0x0a, 0x14, 0x69, 0x6e, 0x76, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, - 0x00, 0x52, 0x13, 0x69, 0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x53, 0x0a, 0x0b, 0x52, 0x65, 0x63, 0x76, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x27, 0x0a, 0x0c, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0x90, 0x82, 0x19, 0x00, 0x52, 0x0b, 0x6f, - 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x22, 0xc6, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x63, 0x76, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x0e, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, 0x00, 0x52, 0x0d, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x4b, 0x0a, 0x14, 0x69, 0x6e, 0x76, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, 0x00, 0x52, - 0x13, 0x69, 0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x65, 0x64, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x3b, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0c, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0x90, 0x82, 0x19, 0x00, - 0x52, 0x0b, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0xac, 0x02, - 0x0a, 0x11, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x6f, 0x6e, - 0x65, 0x12, 0x1a, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x48, 0x00, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x5d, 0x0a, - 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x41, - 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x47, 0x65, - 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, - 0x49, 0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, - 0x65, 0x48, 0x00, 0x52, 0x07, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x1f, 0x0a, 0x0b, - 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x1a, 0x41, 0x0a, - 0x11, 0x49, 0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x61, 0x69, 0x6c, 0x75, - 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x0a, 0x0e, - 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, - 0x0a, 0x0c, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0x90, 0x82, 0x19, 0x00, 0x52, 0x0b, 0x6f, 0x70, 0x65, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x32, 0xf4, 0x03, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, - 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x60, 0x0a, 0x05, 0x53, 0x74, 0x61, - 0x72, 0x74, 0x12, 0x2a, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, - 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x74, - 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x04, 0x53, - 0x65, 0x6e, 0x64, 0x12, 0x29, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, - 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x53, 0x65, - 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5d, 0x0a, 0x04, 0x52, 0x65, - 0x63, 0x76, 0x12, 0x29, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x2e, 0x52, 0x65, 0x63, 0x76, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, - 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x63, - 0x76, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x09, 0x47, 0x65, 0x74, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x2e, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x07, 0x43, 0x6c, 0x65, 0x61, 0x6e, - 0x75, 0x70, 0x12, 0x2c, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x2e, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x04, 0x90, 0x82, 0x19, 0x01, 0x42, 0x85, - 0x02, 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x64, 0x65, 0x76, 0x2e, 0x72, 0x65, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x42, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x6d, 0x75, 0x68, 0x61, 0x6d, 0x61, 0x64, 0x61, 0x7a, 0x6d, 0x79, 0x2f, 0x72, 0x65, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2d, 0x73, 0x64, 0x6b, 0x2d, 0x67, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x65, - 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0xa2, 0x02, 0x04, 0x44, 0x52, 0x53, 0x53, 0xaa, 0x02, 0x1c, 0x44, 0x65, - 0x76, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0xca, 0x02, 0x1c, 0x44, 0x65, 0x76, - 0x5c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0xe2, 0x02, 0x28, 0x44, 0x65, 0x76, 0x5c, - 0x52, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5c, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1f, 0x44, 0x65, 0x76, 0x3a, 0x3a, 0x52, 0x65, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x3a, 0x3a, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x3a, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_proto_services_services_proto_rawDescOnce sync.Once - file_proto_services_services_proto_rawDescData = file_proto_services_services_proto_rawDesc -) - -func file_proto_services_services_proto_rawDescGZIP() []byte { - file_proto_services_services_proto_rawDescOnce.Do(func() { - file_proto_services_services_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_services_services_proto_rawDescData) - }) - return file_proto_services_services_proto_rawDescData -} - -var file_proto_services_services_proto_msgTypes = make([]protoimpl.MessageInfo, 10) -var file_proto_services_services_proto_goTypes = []interface{}{ - (*StartRequest)(nil), // 0: dev.restate.service.services.StartRequest - (*StartResponse)(nil), // 1: dev.restate.service.services.StartResponse - (*SendRequest)(nil), // 2: dev.restate.service.services.SendRequest - (*SendResponse)(nil), // 3: dev.restate.service.services.SendResponse - (*RecvRequest)(nil), // 4: dev.restate.service.services.RecvRequest - (*RecvResponse)(nil), // 5: dev.restate.service.services.RecvResponse - (*GetResultRequest)(nil), // 6: dev.restate.service.services.GetResultRequest - (*GetResultResponse)(nil), // 7: dev.restate.service.services.GetResultResponse - (*CleanupRequest)(nil), // 8: dev.restate.service.services.CleanupRequest - (*GetResultResponse_InvocationFailure)(nil), // 9: dev.restate.service.services.GetResultResponse.InvocationFailure - (*emptypb.Empty)(nil), // 10: google.protobuf.Empty -} -var file_proto_services_services_proto_depIdxs = []int32{ - 7, // 0: dev.restate.service.services.StartResponse.completed:type_name -> dev.restate.service.services.GetResultResponse - 10, // 1: dev.restate.service.services.SendResponse.ok:type_name -> google.protobuf.Empty - 10, // 2: dev.restate.service.services.SendResponse.invalid_stream:type_name -> google.protobuf.Empty - 10, // 3: dev.restate.service.services.SendResponse.invocation_completed:type_name -> google.protobuf.Empty - 10, // 4: dev.restate.service.services.RecvResponse.invalid_stream:type_name -> google.protobuf.Empty - 10, // 5: dev.restate.service.services.RecvResponse.invocation_completed:type_name -> google.protobuf.Empty - 10, // 6: dev.restate.service.services.GetResultResponse.none:type_name -> google.protobuf.Empty - 9, // 7: dev.restate.service.services.GetResultResponse.failure:type_name -> dev.restate.service.services.GetResultResponse.InvocationFailure - 0, // 8: dev.restate.service.services.RemoteContext.Start:input_type -> dev.restate.service.services.StartRequest - 2, // 9: dev.restate.service.services.RemoteContext.Send:input_type -> dev.restate.service.services.SendRequest - 4, // 10: dev.restate.service.services.RemoteContext.Recv:input_type -> dev.restate.service.services.RecvRequest - 6, // 11: dev.restate.service.services.RemoteContext.GetResult:input_type -> dev.restate.service.services.GetResultRequest - 8, // 12: dev.restate.service.services.RemoteContext.Cleanup:input_type -> dev.restate.service.services.CleanupRequest - 1, // 13: dev.restate.service.services.RemoteContext.Start:output_type -> dev.restate.service.services.StartResponse - 3, // 14: dev.restate.service.services.RemoteContext.Send:output_type -> dev.restate.service.services.SendResponse - 5, // 15: dev.restate.service.services.RemoteContext.Recv:output_type -> dev.restate.service.services.RecvResponse - 7, // 16: dev.restate.service.services.RemoteContext.GetResult:output_type -> dev.restate.service.services.GetResultResponse - 10, // 17: dev.restate.service.services.RemoteContext.Cleanup:output_type -> google.protobuf.Empty - 13, // [13:18] is the sub-list for method output_type - 8, // [8:13] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name -} - -func init() { file_proto_services_services_proto_init() } -func file_proto_services_services_proto_init() { - if File_proto_services_services_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_services_services_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StartRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_services_services_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StartResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_services_services_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SendRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_services_services_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SendResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_services_services_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RecvRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_services_services_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RecvResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_services_services_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetResultRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_services_services_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetResultResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_services_services_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CleanupRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_services_services_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetResultResponse_InvocationFailure); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_proto_services_services_proto_msgTypes[1].OneofWrappers = []interface{}{ - (*StartResponse_Executing)(nil), - (*StartResponse_Completed)(nil), - } - file_proto_services_services_proto_msgTypes[3].OneofWrappers = []interface{}{ - (*SendResponse_Ok)(nil), - (*SendResponse_InvalidStream)(nil), - (*SendResponse_InvocationCompleted)(nil), - } - file_proto_services_services_proto_msgTypes[5].OneofWrappers = []interface{}{ - (*RecvResponse_Messages)(nil), - (*RecvResponse_InvalidStream)(nil), - (*RecvResponse_InvocationCompleted)(nil), - } - file_proto_services_services_proto_msgTypes[7].OneofWrappers = []interface{}{ - (*GetResultResponse_None)(nil), - (*GetResultResponse_Success)(nil), - (*GetResultResponse_Failure)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_services_services_proto_rawDesc, - NumEnums: 0, - NumMessages: 10, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_proto_services_services_proto_goTypes, - DependencyIndexes: file_proto_services_services_proto_depIdxs, - MessageInfos: file_proto_services_services_proto_msgTypes, - }.Build() - File_proto_services_services_proto = out.File - file_proto_services_services_proto_rawDesc = nil - file_proto_services_services_proto_goTypes = nil - file_proto_services_services_proto_depIdxs = nil -} diff --git a/go.mod b/go.mod index 65164a6..f9f4eb6 100644 --- a/go.mod +++ b/go.mod @@ -3,21 +3,20 @@ module github.com/restatedev/sdk-go go 1.22.0 require ( + github.com/google/uuid v1.6.0 + github.com/posener/h2conn v0.0.0-20231204025407-3997deeca0f0 github.com/rs/zerolog v1.32.0 + github.com/stretchr/testify v1.9.0 + github.com/vmihailenco/msgpack/v5 v5.4.1 golang.org/x/net v0.21.0 google.golang.org/protobuf v1.32.0 ) require ( - github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/google/uuid v1.6.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/posener/h2conn v0.0.0-20231204025407-3997deeca0f0 // indirect - github.com/stretchr/testify v1.9.0 // indirect - github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect golang.org/x/sys v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect diff --git a/go.sum b/go.sum index deb27be..11597c7 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,9 @@ -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -29,14 +29,16 @@ golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/handler.go b/handler.go index a376d44..8d9e5fb 100644 --- a/handler.go +++ b/handler.go @@ -4,9 +4,6 @@ import ( "encoding/json" "fmt" "reflect" - - "github.com/restatedev/sdk-go/generated/proto/dynrpc" - "google.golang.org/protobuf/types/known/structpb" ) // Void is a placeholder used usually for functions that their signature require that @@ -22,27 +19,22 @@ func (v *Void) UnmarshalJSON(_ []byte) error { return nil } -type UnKeyedHandler struct { +type ServiceHandler struct { fn reflect.Value input reflect.Type output reflect.Type } -// NewUnKeyedHandler create a new handler for an `un-keyed` function -func NewUnKeyedHandler[I any, O any](fn UnKeyedHandlerFn[I, O]) *UnKeyedHandler { - return &UnKeyedHandler{ +// NewServiceHandler create a new handler for a service +func NewServiceHandler[I any, O any](fn ServiceHandlerFn[I, O]) *ServiceHandler { + return &ServiceHandler{ fn: reflect.ValueOf(fn), input: reflect.TypeFor[I](), output: reflect.TypeFor[O](), } } -func (h *UnKeyedHandler) Call(ctx Context, request *dynrpc.RpcRequest) (*dynrpc.RpcResponse, error) { - bytes, err := request.Request.MarshalJSON() - if err != nil { - return nil, TerminalError(fmt.Errorf("request is not valid json: %w", err)) - } - +func (h *ServiceHandler) Call(ctx Context, bytes []byte) ([]byte, error) { input := reflect.New(h.input) if err := json.Unmarshal(bytes, input.Interface()); err != nil { @@ -61,43 +53,31 @@ func (h *UnKeyedHandler) Call(ctx Context, request *dynrpc.RpcRequest) (*dynrpc. return nil, errI.(error) } - bytes, err = json.Marshal(outI) + bytes, err := json.Marshal(outI) if err != nil { return nil, TerminalError(fmt.Errorf("failed to serialize output: %w", err)) } - var response dynrpc.RpcResponse - response.Response = &structpb.Value{} - - if err := response.Response.UnmarshalJSON(bytes); err != nil { - return nil, TerminalError(err) - } - - return &response, nil + return bytes, nil } -func (h *UnKeyedHandler) sealed() {} +func (h *ServiceHandler) sealed() {} -type KeyedHandler struct { +type ObjectHandler struct { fn reflect.Value input reflect.Type output reflect.Type } -func NewKeyedHandler[I any, O any](fn KeyedHandlerFn[I, O]) *KeyedHandler { - return &KeyedHandler{ +func NewObjectHandler[I any, O any](fn ObjectHandlerFn[I, O]) *ObjectHandler { + return &ObjectHandler{ fn: reflect.ValueOf(fn), input: reflect.TypeFor[I](), output: reflect.TypeFor[O](), } } -func (h *KeyedHandler) Call(ctx Context, request *dynrpc.RpcRequest) (*dynrpc.RpcResponse, error) { - bytes, err := request.Request.MarshalJSON() - if err != nil { - return nil, TerminalError(fmt.Errorf("request is not valid json: %w", err)) - } - +func (h *ObjectHandler) Call(ctx ObjectContext, bytes []byte) ([]byte, error) { input := reflect.New(h.input) if err := json.Unmarshal(bytes, input.Interface()); err != nil { @@ -107,7 +87,6 @@ func (h *KeyedHandler) Call(ctx Context, request *dynrpc.RpcRequest) (*dynrpc.Rp // we are sure about the fn signature so it's safe to do this output := h.fn.Call([]reflect.Value{ reflect.ValueOf(ctx), - reflect.ValueOf(request.Key), input.Elem(), }) @@ -117,19 +96,12 @@ func (h *KeyedHandler) Call(ctx Context, request *dynrpc.RpcRequest) (*dynrpc.Rp return nil, errI.(error) } - bytes, err = json.Marshal(outI) + bytes, err := json.Marshal(outI) if err != nil { return nil, TerminalError(fmt.Errorf("failed to serialize output: %w", err)) } - var response dynrpc.RpcResponse - response.Response = &structpb.Value{} - - if err := response.Response.UnmarshalJSON(bytes); err != nil { - return nil, TerminalError(err) - } - - return &response, nil + return bytes, nil } -func (h *KeyedHandler) sealed() {} +func (h *ObjectHandler) sealed() {} diff --git a/internal/discovery.go b/internal/discovery.go new file mode 100644 index 0000000..738d789 --- /dev/null +++ b/internal/discovery.go @@ -0,0 +1,57 @@ +package internal + +type ProtocolMode string + +const ( + ProtocolMode_BIDI_STREAM ProtocolMode = "BIDI_STREAM" + ProtocolMode_REQUEST_RESPONSE ProtocolMode = "REQUEST_RESPONSE" +) + +type ServiceType string + +const ( + ServiceType_VIRTUAL_OBJECT ServiceType = "VIRTUAL_OBJECT" + ServiceType_SERVICE ServiceType = "SERVICE" + ServiceType_WORKFLOW ServiceType = "WORKFLOW" +) + +type ServiceHandlerType string + +const ( + ServiceHandlerType_WORKFLOW ServiceHandlerType = "WORKFLOW" + ServiceHandlerType_EXCLUSIVE ServiceHandlerType = "EXCLUSIVE" + ServiceHandlerType_SHARED ServiceHandlerType = "SHARED" +) + +type InputPayload struct { + Required bool `json:"required"` + ContentType string `json:"contentType"` + JsonSchema interface{} `json:"jsonSchema,omitempty"` +} + +type OutputPayload struct { + ContentType string `json:"contentType"` + SetContentTypeIfEmpty bool `json:"setContentTypeIfEmpty"` + JsonSchema interface{} `json:"jsonSchema,omitempty"` +} + +type Handler struct { + Name string `json:"name,omitempty"` + // If unspecified, defaults to EXCLUSIVE for Virtual Object. This should be unset for Services. + Ty *ServiceHandlerType `json:"ty,omitempty"` + Input *InputPayload `json:"input,omitempty"` + Output *OutputPayload `json:"output,omitempty"` +} + +type Service struct { + Name string `json:"name"` + Ty ServiceType `json:"ty"` + Handlers []Handler `json:"handlers"` +} + +type Endpoint struct { + ProtocolMode ProtocolMode `json:"protocolMode"` + MinProtocolVersion int32 `json:"minProtocolVersion"` + MaxProtocolVersion int32 `json:"maxProtocolVersion"` + Services []Service `json:"services"` +} diff --git a/internal/dynrpc.binbp b/internal/dynrpc.binbp deleted file mode 100644 index 005949b417ad30facceb283964cb96609df50fb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78311 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 LmFHhb&+Y#K=<&`u diff --git a/internal/dynrpc.go b/internal/dynrpc.go deleted file mode 100644 index 8836efe..0000000 --- a/internal/dynrpc.go +++ /dev/null @@ -1,109 +0,0 @@ -package internal - -import ( - _ "embed" - "fmt" - - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/descriptorpb" -) - -var ( - requestTypeName = "RpcRequest" - responseTypeName = "RpcResponse" -) - -//go:embed dynrpc.binbp -var dynRpcBytes []byte - -// NewDynRpcDescriptorSet creates a new DynRpcDescriptorSet -func NewDynRpcDescriptorSet() *DynRpcDescriptorSet { - var ds descriptorpb.FileDescriptorSet - err := proto.Unmarshal(dynRpcBytes, &ds) - if err != nil { - panic(fmt.Sprintf("invalid file descriptor set: %s", err)) - } - - return &DynRpcDescriptorSet{&ds} -} - -// DynRpcService wrapper around ServiceDescriptorProto for easier manipulation -type DynRpcService struct { - *descriptorpb.ServiceDescriptorProto -} - -func (s *DynRpcService) AddHandler(name string) { - s.Method = append(s.Method, &descriptorpb.MethodDescriptorProto{ - Name: &name, - InputType: &requestTypeName, - OutputType: &responseTypeName, - // TODO: check options and others - }) -} - -// DynRpcDescriptorSet wrapper around FileDescriptorSet for easier manipulation -type DynRpcDescriptorSet struct { - *descriptorpb.FileDescriptorSet -} - -// Inner returns the inner *descriptorpb.FileDescriptorSet -func (d *DynRpcDescriptorSet) Inner() *descriptorpb.FileDescriptorSet { - return d.FileDescriptorSet -} - -func (d *DynRpcDescriptorSet) getDynRpcFile() (*descriptorpb.FileDescriptorProto, error) { - // since it's always the last file may be we should use the index - // but this is safer - for _, file := range d.File { - if file.Name != nil && *file.Name == "dynrpc/dynrpc.proto" { - return file, nil - } - } - - return nil, fmt.Errorf("file descriptor for dynrpc not found") -} - -// AddKeyedService creates a new Keyed service from the KeyedRpcService template -func (d *DynRpcDescriptorSet) AddKeyedService(name string) (*DynRpcService, error) { - return d.addService(name, 0) -} - -// AddUnKeyedService creates a new Un-Keyed service from the RpcService template -func (d *DynRpcDescriptorSet) AddUnKeyedService(name string) (*DynRpcService, error) { - return d.addService(name, 1) -} - -func (d *DynRpcDescriptorSet) addService(name string, from int) (*DynRpcService, error) { - file, err := d.getDynRpcFile() - if err != nil { - return nil, err - } - - // unkeyed service is always number one - service, err := deepCopy(file.Service[from]) - if err != nil { - return nil, err - } - - service.Name = &name - // clean up services - service.Method = []*descriptorpb.MethodDescriptorProto{} - - file.Service = append(file.Service, service) - - return &DynRpcService{service}, nil -} - -func deepCopy(src *descriptorpb.ServiceDescriptorProto) (*descriptorpb.ServiceDescriptorProto, error) { - bytes, err := proto.Marshal(src) - if err != nil { - return nil, err - } - - var copy descriptorpb.ServiceDescriptorProto - if err := proto.Unmarshal(bytes, &copy); err != nil { - return nil, err - } - - return &copy, nil -} diff --git a/internal/dynrpc_test.go b/internal/dynrpc_test.go deleted file mode 100644 index e28a411..0000000 --- a/internal/dynrpc_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package internal - -import ( - "fmt" - "testing" -) - -func TestDynRpc(t *testing.T) { - - ds := NewDynRpcDescriptorSet() - - //fmt.Println(len(ds.File)) - // require.Len(t, ds.File, 2) - - for _, file := range ds.File { - - fmt.Println(*file.Name) - fmt.Printf("dep: %+v\n", file.Dependency) - for _, service := range file.Service { - fmt.Println(" - service: ", *service.Name) - } - } -} diff --git a/internal/state/call.go b/internal/state/call.go index 7052620..03bc670 100644 --- a/internal/state/call.go +++ b/internal/state/call.go @@ -6,16 +6,14 @@ import ( "fmt" "time" - "github.com/restatedev/sdk-go" - "github.com/restatedev/sdk-go/generated/proto/dynrpc" + restate "github.com/restatedev/sdk-go" "github.com/restatedev/sdk-go/generated/proto/protocol" "github.com/restatedev/sdk-go/internal/wire" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/structpb" ) var ( _ restate.Service = (*serviceProxy)(nil) + _ restate.Object = (*serviceProxy)(nil) _ restate.Call = (*serviceCall)(nil) ) @@ -24,12 +22,14 @@ var ( type serviceProxy struct { *Context service string + key string } func (c *serviceProxy) Method(fn string) restate.Call { return &serviceCall{ Context: c.Context, service: c.service, + key: c.key, method: fn, } } @@ -37,66 +37,34 @@ func (c *serviceProxy) Method(fn string) restate.Call { type serviceCall struct { *Context service string + key string method string } // Do makes a call and wait for the response -func (c *serviceCall) Do(key string, input any, output any) error { - return c.machine.doDynCall(c.service, c.method, key, input, output) +func (c *serviceCall) Do(input any, output any) error { + return c.machine.doDynCall(c.service, c.key, c.method, input, output) } // Send runs a call in the background after delay duration -func (c *serviceCall) Send(key string, body any, delay time.Duration) error { - return c.machine.sendCall(c.service, c.method, key, body, delay) +func (c *serviceCall) Send(body any, delay time.Duration) error { + return c.machine.sendCall(c.service, c.method, c.key, body, delay) } -func (m *Machine) makeRequest(key string, body any) ([]byte, error) { - - input, err := json.Marshal(body) - if err != nil { - return nil, err - } - - params := &dynrpc.RpcRequest{ - Key: key, - Request: &structpb.Value{}, - } - - if err := params.Request.UnmarshalJSON(input); err != nil { - return nil, err - } - - return proto.Marshal(params) -} - -func (m *Machine) doDynCall(service, method, key string, input, output any) error { +func (m *Machine) doDynCall(service, key, method string, input, output any) error { m.log.Debug().Str("service", service).Str("method", method).Msg("in do call") - params, err := m.makeRequest(key, input) + params, err := json.Marshal(input) if err != nil { return err } - bytes, err := m.doCall(service, method, params) + bytes, err := m.doCall(service, key, method, params) if err != nil { return err } - var rpcResponse dynrpc.RpcResponse - if err := proto.Unmarshal(bytes, &rpcResponse); err != nil { - return fmt.Errorf("failed to decode rpc response: %w", err) - } - - js, err := rpcResponse.Response.MarshalJSON() - if err != nil { - return fmt.Errorf("failed to process response payload") - } - - if output == nil { - return nil - } - - if err := json.Unmarshal(js, output); err != nil { + if err := json.Unmarshal(bytes, output); err != nil { // TODO: is this should be a terminal error or not? return restate.TerminalError(fmt.Errorf("failed to decode response (%s): %w", string(bytes), err)) } @@ -104,35 +72,37 @@ func (m *Machine) doDynCall(service, method, key string, input, output any) erro return nil } -func (m *Machine) doCall(service, method string, params []byte) ([]byte, error) { +func (m *Machine) doCall(service, key, method string, params []byte) ([]byte, error) { return replayOrNew( m, - wire.InvokeEntryMessageType, - func(entry *wire.InvokeEntryMessage) ([]byte, error) { + wire.CallEntryMessageType, + func(entry *wire.CallEntryMessage) ([]byte, error) { if entry.Payload.ServiceName != service || - entry.Payload.MethodName != method || + entry.Payload.Key != key || + entry.Payload.HandlerName != method || !bytes.Equal(entry.Payload.Parameter, params) { return nil, errEntryMismatch } switch result := entry.Payload.Result.(type) { - case *protocol.InvokeEntryMessage_Failure: + case *protocol.CallEntryMessage_Failure: return nil, restate.WithErrorCode(fmt.Errorf(result.Failure.Message), restate.Code(result.Failure.Code)) - case *protocol.InvokeEntryMessage_Value: + case *protocol.CallEntryMessage_Value: return result.Value, nil } return nil, errUnreachable }, func() ([]byte, error) { - return m._doCall(service, method, params) + return m._doCall(service, key, method, params) }) } -func (m *Machine) _doCall(service, method string, params []byte) ([]byte, error) { - err := m.protocol.Write(&protocol.InvokeEntryMessage{ +func (m *Machine) _doCall(service, key, method string, params []byte) ([]byte, error) { + err := m.protocol.Write(&protocol.CallEntryMessage{ ServiceName: service, - MethodName: method, + HandlerName: method, Parameter: params, + Key: key, }) if err != nil { @@ -163,17 +133,18 @@ func (m *Machine) _doCall(service, method string, params []byte) ([]byte, error) } func (c *Machine) sendCall(service, method, key string, body any, delay time.Duration) error { - params, err := c.makeRequest(key, body) + params, err := json.Marshal(body) if err != nil { return err } _, err = replayOrNew( c, - wire.BackgroundInvokeEntryMessageType, - func(entry *wire.BackgroundInvokeEntryMessage) (restate.Void, error) { + wire.OneWayCallEntryMessageType, + func(entry *wire.OneWayCallEntryMessage) (restate.Void, error) { if entry.Payload.ServiceName != service || - entry.Payload.MethodName != method || + entry.Payload.Key != key || + entry.Payload.HandlerName != method || !bytes.Equal(entry.Payload.Parameter, params) { return restate.Void{}, errEntryMismatch } @@ -194,9 +165,9 @@ func (c *Machine) _sendCall(service, method string, params []byte, delay time.Du invokeTime = uint64(time.Now().Add(delay).UnixMilli()) } - err := c.protocol.Write(&protocol.BackgroundInvokeEntryMessage{ + err := c.protocol.Write(&protocol.OneWayCallEntryMessage{ ServiceName: service, - MethodName: method, + HandlerName: method, Parameter: params, InvokeTime: invokeTime, }) diff --git a/internal/state/state.go b/internal/state/state.go index c25dfbe..66c6abd 100644 --- a/internal/state/state.go +++ b/internal/state/state.go @@ -8,9 +8,7 @@ import ( "sync" "time" - "github.com/cenkalti/backoff/v4" - "github.com/restatedev/sdk-go" - "github.com/restatedev/sdk-go/generated/proto/dynrpc" + restate "github.com/restatedev/sdk-go" "github.com/restatedev/sdk-go/generated/proto/protocol" "github.com/restatedev/sdk-go/internal/wire" @@ -42,6 +40,9 @@ type Context struct { machine *Machine } +var _ restate.ObjectContext = &Context{} +var _ restate.Context = &Context{} + func (c *Context) Ctx() context.Context { return c.ctx } @@ -80,17 +81,20 @@ func (c *Context) Service(service string) restate.Service { } } -func (c *Context) SideEffect(fn func() ([]byte, error), bo ...backoff.BackOff) ([]byte, error) { - var back backoff.BackOff - if len(bo) == 0 { - back = &restate.DefaultBackoffPolicy - } else if len(bo) == 1 { - back = bo[0] - } else { - panic("only single backoff policy is allowed") +func (c *Context) Object(service, key string) restate.Object { + return &serviceProxy{ + Context: c, + service: service, + key: key, } +} + +func (c *Context) SideEffect(fn func() ([]byte, error)) ([]byte, error) { + return c.machine.sideEffect(fn) +} - return c.machine.sideEffect(fn, back) +func (c *Context) Key() string { + return c.machine.key } func newContext(inner context.Context, machine *Machine) *Context { @@ -114,7 +118,8 @@ type Machine struct { mutex sync.Mutex // state - id string + id string + key string partial bool current map[string][]byte @@ -149,9 +154,7 @@ func (m *Machine) Start(inner context.Context, trace string) error { start := msg.(*wire.StartMessage) m.id = start.Payload.DebugId - if start.Version != Version { - return ErrInvalidVersion - } + m.key = start.Payload.Key m.log = log.With().Str("id", start.Payload.DebugId).Str("method", trace).Logger() @@ -164,15 +167,15 @@ func (m *Machine) Start(inner context.Context, trace string) error { } // handle handler response and build proper response message -func (m *Machine) output(r *dynrpc.RpcResponse, err error) proto.Message { +func (m *Machine) output(bytes []byte, err error) proto.Message { if err != nil { m.log.Error().Err(err).Msg("failure") } if err != nil && restate.IsTerminalError(err) { // terminal errors. - return &protocol.OutputStreamEntryMessage{ - Result: &protocol.OutputStreamEntryMessage_Failure{ + return &protocol.OutputEntryMessage{ + Result: &protocol.OutputEntryMessage_Failure{ Failure: &protocol.Failure{ Code: uint32(restate.ErrorCode(err)), Message: err.Error(), @@ -187,24 +190,14 @@ func (m *Machine) output(r *dynrpc.RpcResponse, err error) proto.Message { } } - bytes, err := proto.Marshal(r) - if err != nil { - // this shouldn't happen but in case we return a retry error - return &protocol.ErrorMessage{ - Code: uint32(restate.INTERNAL), - Message: err.Error(), - Description: "failed to serialize call output", - } - } - - return &protocol.OutputStreamEntryMessage{ - Result: &protocol.OutputStreamEntryMessage_Value{ + return &protocol.OutputEntryMessage{ + Result: &protocol.OutputEntryMessage_Value{ Value: bytes, }, } } -func (m *Machine) invoke(ctx *Context, input *dynrpc.RpcRequest) error { +func (m *Machine) invoke(ctx *Context, key string, input []byte) error { // always terminate the invocation with // an end message. // this will always terminate the connection @@ -266,7 +259,7 @@ func (m *Machine) process(ctx *Context, start *wire.StartMessage) error { return err } - if msg.Type() != wire.PollInputEntryMessageType { + if msg.Type() != wire.InputEntryMessageType { return wire.ErrUnexpectedMessage } @@ -284,14 +277,9 @@ func (m *Machine) process(ctx *Context, start *wire.StartMessage) error { m.entries = append(m.entries, msg) } - inputMsg := msg.(*wire.PollInputEntry) + inputMsg := msg.(*wire.InputEntryMessage) value := inputMsg.Payload.GetValue() - var input dynrpc.RpcRequest - if err := proto.Unmarshal(value, &input); err != nil { - return fmt.Errorf("invalid invocation input: %w", err) - } - - return m.invoke(ctx, &input) + return m.invoke(ctx, start.Payload.Key, value) } diff --git a/internal/state/sys.go b/internal/state/sys.go index 571d0aa..da03ac3 100644 --- a/internal/state/sys.go +++ b/internal/state/sys.go @@ -2,12 +2,11 @@ package state import ( "bytes" + "errors" "fmt" "time" - "github.com/cenkalti/backoff/v4" - "github.com/restatedev/sdk-go" - "github.com/restatedev/sdk-go/generated/proto/javascript" + restate "github.com/restatedev/sdk-go" "github.com/restatedev/sdk-go/generated/proto/protocol" "github.com/restatedev/sdk-go/internal/wire" "google.golang.org/protobuf/proto" @@ -321,59 +320,62 @@ func (m *Machine) _sleep(until time.Time) error { return nil } -func (m *Machine) sideEffect(fn func() ([]byte, error), bo backoff.BackOff) ([]byte, error) { +func (m *Machine) sideEffect(fn func() ([]byte, error)) ([]byte, error) { return replayOrNew( m, - wire.SideEffectEntryMessageType, - func(entry *wire.SideEffectEntryMessage) ([]byte, error) { + wire.RunEntryMessageType, + func(entry *wire.RunEntryMessage) ([]byte, error) { switch result := entry.Payload.Result.(type) { - case *javascript.SideEffectEntryMessage_Failure: - err := fmt.Errorf("[%d] %s", result.Failure.Failure.Code, result.Failure.Failure.Message) - if result.Failure.Terminal { - err = restate.TerminalError(err) - } - return nil, err - case *javascript.SideEffectEntryMessage_Value: + case *protocol.RunEntryMessage_Failure: + return nil, restate.TerminalError(errors.New(result.Failure.Message), restate.Code(result.Failure.Code)) + case *protocol.RunEntryMessage_Value: return result.Value, nil } return nil, errUnreachable }, func() ([]byte, error) { - return m._sideEffect(fn, bo) + return m._sideEffect(fn) }, ) } -func (m *Machine) _sideEffect(fn func() ([]byte, error), bo backoff.BackOff) ([]byte, error) { - var bytes []byte - err := backoff.Retry(func() error { - var err error - bytes, err = fn() +func (m *Machine) _sideEffect(fn func() ([]byte, error)) ([]byte, error) { + bytes, err := fn() - if restate.IsTerminalError(err) { - // if inner function returned a terminal error - // we need to wrap it in permanent to break - // the retries - return backoff.Permanent(err) - } - return err - }, bo) - - var msg javascript.SideEffectEntryMessage + var msg protocol.RunEntryMessage if err != nil { - msg.Result = &javascript.SideEffectEntryMessage_Failure{ - Failure: &javascript.FailureWithTerminal{ - Failure: &protocol.Failure{ - Code: uint32(restate.ErrorCode(err)), - Message: err.Error(), + if restate.IsTerminalError(err) { + msg := protocol.RunEntryMessage{ + Result: &protocol.RunEntryMessage_Failure{ + Failure: &protocol.Failure{ + Code: uint32(restate.ErrorCode(err)), + Message: err.Error(), + }, }, - Terminal: restate.IsTerminalError(err), - }, + } + if err := m.protocol.Write(&msg); err != nil { + return nil, err + } + } else { + ty := uint32(wire.RunEntryMessageType) + msg := protocol.ErrorMessage{ + Code: uint32(restate.ErrorCode(err)), + Message: err.Error(), + RelatedEntryType: &ty, + } + if err := m.protocol.Write(&msg); err != nil { + return nil, err + } } } else { - msg.Result = &javascript.SideEffectEntryMessage_Value{ - Value: bytes, + msg := protocol.RunEntryMessage{ + Result: &protocol.RunEntryMessage_Value{ + Value: bytes, + }, + } + if err := m.protocol.Write(&msg); err != nil { + return nil, err } } diff --git a/internal/wire/wire.go b/internal/wire/wire.go index 2c29134..a750d0f 100644 --- a/internal/wire/wire.go +++ b/internal/wire/wire.go @@ -9,8 +9,7 @@ import ( "io" "math" - "github.com/restatedev/sdk-go/generated/proto/javascript" - "github.com/restatedev/sdk-go/generated/proto/protocol" + protocol "github.com/restatedev/sdk-go/generated/proto/protocol" "github.com/rs/zerolog/log" "google.golang.org/protobuf/proto" ) @@ -36,8 +35,8 @@ const ( EndMessageType Type = 0x0000 + 5 // Input/Output - PollInputEntryMessageType Type = 0x0400 - OutputStreamEntryMessageType Type = 0x0400 + 1 + InputEntryMessageType Type = 0x0400 + OutputEntryMessageType Type = 0x0400 + 1 // State GetStateEntryMessageType Type = 0x0800 @@ -47,12 +46,12 @@ const ( GetStateKeysEntryMessageType Type = 0x0800 + 4 //SysCalls - SleepEntryMessageType Type = 0x0C00 - InvokeEntryMessageType Type = 0x0C00 + 1 - BackgroundInvokeEntryMessageType Type = 0x0C00 + 2 - - // SideEffect - SideEffectEntryMessageType Type = 0xFC00 + 1 + SleepEntryMessageType Type = 0x0C00 + CallEntryMessageType Type = 0x0C00 + 1 + OneWayCallEntryMessageType Type = 0x0C00 + 2 + AwakeableEntryMessageType Type = 0x0C00 + 3 + CompleteAwakeableEntryMessageType Type = 0x0C00 + 4 + RunEntryMessageType Type = 0x0C00 + 5 ) type Type uint16 @@ -65,11 +64,6 @@ func (t Type) String() string { // a different meaning based on message type. type Flag uint16 -// this is only valid with start message -func (r Flag) version() uint16 { - return uint16(r) & VersionMask -} - func (r Flag) Completed() bool { return r&FlagCompleted != 0 } @@ -193,10 +187,10 @@ func (s *Protocol) Write(message proto.Message, flags ...Flag) error { typ = StartMessageType case *protocol.SuspensionMessage: typ = SuspensionMessageType - case *protocol.PollInputStreamEntryMessage: - typ = PollInputEntryMessageType - case *protocol.OutputStreamEntryMessage: - typ = OutputStreamEntryMessageType + case *protocol.InputEntryMessage: + typ = InputEntryMessageType + case *protocol.OutputEntryMessage: + typ = OutputEntryMessageType case *protocol.ErrorMessage: typ = ErrorMessageType case *protocol.EndMessage: @@ -211,14 +205,14 @@ func (s *Protocol) Write(message proto.Message, flags ...Flag) error { typ = ClearAllStateEntryMessageType case *protocol.SleepEntryMessage: typ = SleepEntryMessageType - case *protocol.InvokeEntryMessage: - typ = InvokeEntryMessageType - case *protocol.BackgroundInvokeEntryMessage: - typ = BackgroundInvokeEntryMessageType + case *protocol.CallEntryMessage: + typ = CallEntryMessageType + case *protocol.OneWayCallEntryMessage: + typ = OneWayCallEntryMessageType case *protocol.GetStateKeysEntryMessage: typ = GetStateKeysEntryMessageType - case *javascript.SideEffectEntryMessage: - typ = SideEffectEntryMessageType + case *protocol.RunEntryMessage: + typ = RunEntryMessageType default: return fmt.Errorf("can not send message of unknown message type") } @@ -258,8 +252,7 @@ var ( builders = map[Type]messageBuilder{ StartMessageType: func(header Header, bytes []byte) (Message, error) { msg := &StartMessage{ - Header: header, - Version: header.Flag.version(), + Header: header, } return msg, proto.Unmarshal(bytes, &msg.Payload) @@ -271,15 +264,15 @@ var ( return msg, proto.Unmarshal(bytes, &msg.Payload) }, - PollInputEntryMessageType: func(header Header, bytes []byte) (Message, error) { - msg := &PollInputEntry{ + InputEntryMessageType: func(header Header, bytes []byte) (Message, error) { + msg := &InputEntryMessage{ Header: header, } return msg, proto.Unmarshal(bytes, &msg.Payload) }, - OutputStreamEntryMessageType: func(header Header, bytes []byte) (Message, error) { - msg := &OutputStreamEntry{ + OutputEntryMessageType: func(header Header, bytes []byte) (Message, error) { + msg := &OutputEntryMessage{ Header: header, } @@ -334,22 +327,22 @@ var ( return msg, proto.Unmarshal(bytes, &msg.Payload) }, - InvokeEntryMessageType: func(header Header, bytes []byte) (Message, error) { - msg := &InvokeEntryMessage{ + CallEntryMessageType: func(header Header, bytes []byte) (Message, error) { + msg := &CallEntryMessage{ Header: header, } return msg, proto.Unmarshal(bytes, &msg.Payload) }, - BackgroundInvokeEntryMessageType: func(header Header, bytes []byte) (Message, error) { - msg := &BackgroundInvokeEntryMessage{ + OneWayCallEntryMessageType: func(header Header, bytes []byte) (Message, error) { + msg := &OneWayCallEntryMessage{ Header: header, } return msg, proto.Unmarshal(bytes, &msg.Payload) }, - SideEffectEntryMessageType: func(header Header, bytes []byte) (Message, error) { - msg := &SideEffectEntryMessage{ + RunEntryMessageType: func(header Header, bytes []byte) (Message, error) { + msg := &RunEntryMessage{ Header: header, } @@ -360,18 +353,17 @@ var ( type StartMessage struct { Header - Version uint16 Payload protocol.StartMessage } -type PollInputEntry struct { +type InputEntryMessage struct { Header - Payload protocol.PollInputStreamEntryMessage + Payload protocol.InputEntryMessage } -type OutputStreamEntry struct { +type OutputEntryMessage struct { Header - Payload protocol.OutputStreamEntryMessage + Payload protocol.OutputEntryMessage } type GetStateEntryMessage struct { @@ -409,19 +401,19 @@ type SleepEntryMessage struct { Payload protocol.SleepEntryMessage } -type InvokeEntryMessage struct { +type CallEntryMessage struct { Header - Payload protocol.InvokeEntryMessage + Payload protocol.CallEntryMessage } -type BackgroundInvokeEntryMessage struct { +type OneWayCallEntryMessage struct { Header - Payload protocol.BackgroundInvokeEntryMessage + Payload protocol.OneWayCallEntryMessage } -type SideEffectEntryMessage struct { +type RunEntryMessage struct { Header - Payload javascript.SideEffectEntryMessage + Payload protocol.RunEntryMessage } type EntryAckMessage struct { diff --git a/proto/buf.lock b/proto/buf.lock deleted file mode 100644 index 84e0028..0000000 --- a/proto/buf.lock +++ /dev/null @@ -1,8 +0,0 @@ -# Generated by buf. DO NOT EDIT. -version: v1 -deps: - - remote: buf.build - owner: restatedev - repository: proto - commit: 6ea2d15aed8f408590a1465844df5a8e - digest: shake256:e6599809ff13490a631f87d1a4b13ef1886d1bd1c0aa001ccb92806c0acc373d047a6ead761f8a21dfbd57a4fd9acd5915a52e47bd5b4e4a02dd1766f78511b3 diff --git a/proto/discovery/discovery.proto b/proto/discovery/discovery.proto index 36d8d92..e385c92 100644 --- a/proto/discovery/discovery.proto +++ b/proto/discovery/discovery.proto @@ -1,46 +1,22 @@ -/* - * Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH - * - * This file is part of the Restate SDK for Node.js/TypeScript, - * which is released under the MIT license. - * - * You can find a copy of the license in file LICENSE in the root - * directory of this repository or package, or at - * https://github.com/restatedev/sdk-typescript/blob/main/LICENSE - */ +// Copyright (c) 2024 - Restate Software, Inc., Restate GmbH +// +// This file is part of the Restate service protocol, which is +// released under the MIT license. +// +// You can find a copy of the license in file LICENSE in the root +// directory of this repository or package, or at +// https://github.com/restatedev/service-protocol/blob/main/LICENSE syntax = "proto3"; package dev.restate.service.discovery; -import "google/protobuf/descriptor.proto"; +option java_package = "dev.restate.generated.service.discovery"; +option go_package = "restate.dev/sdk-go/pb/service/discovery"; -// --- Service discovery endpoint --- -// Request: POST /discover with application/proto containing -// ServiceDiscoveryRequest Response: application/proto containing -// ServiceDiscoveryResponse - -message ServiceDiscoveryRequest {} - -enum ProtocolMode { - // protolint:disable:next ENUM_FIELD_NAMES_ZERO_VALUE_END_WITH - BIDI_STREAM = 0; - REQUEST_RESPONSE = 1; -} - -message ServiceDiscoveryResponse { - // List of all proto files used to define the services, including the - // dependencies. - google.protobuf.FileDescriptorSet files = 1; - - // List of services to register. This might be a subset of services defined in - // files. - repeated string services = 2; - - // Service-protocol version negotiation - uint32 min_protocol_version = 3; - uint32 max_protocol_version = 4; - - // Protocol mode negotiation - ProtocolMode protocol_mode = 5; +// Service discovery protocol version. +enum ServiceDiscoveryProtocolVersion { + SERVICE_DISCOVERY_PROTOCOL_VERSION_UNSPECIFIED = 0; + // initial service discovery protocol version using endpoint_manifest_schema.json + V1 = 1; } diff --git a/proto/dynrpc/dynrpc.proto b/proto/dynrpc/dynrpc.proto deleted file mode 100644 index 8f459ae..0000000 --- a/proto/dynrpc/dynrpc.proto +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH - * - * This file is part of the Restate SDK for Node.js/TypeScript, - * which is released under the MIT license. - * - * You can find a copy of the license in file LICENSE in the root - * directory of this repository or package, or at - * https://github.com/restatedev/sdk-typescript/blob/main/LICENSE - */ - -syntax = "proto3"; - -import "dev/restate/ext.proto"; -import "google/protobuf/struct.proto"; -import "google/protobuf/empty.proto"; - -service RpcEndpoint { - option (dev.restate.ext.service_type) = KEYED; - - rpc call(RpcRequest) returns (RpcResponse) {}; - - rpc handle(KeyedEvent) returns (google.protobuf.Empty) {}; -} - -message KeyedEvent { - string key = 1 [ (dev.restate.ext.field) = KEY ]; - bytes payload = 3 [ (dev.restate.ext.field) = EVENT_PAYLOAD ]; - map<string, string> attributes = 15 - [ (dev.restate.ext.field) = EVENT_METADATA ]; -} - -service UnkeyedRpcEndpoint { - option (dev.restate.ext.service_type) = UNKEYED; - - rpc call(RpcRequest) returns (RpcResponse) {}; -} - -message RpcRequest { - string key = 1 [ (dev.restate.ext.field) = KEY ]; - google.protobuf.Value request = 2; - - // internal: see src/utils/assumptions.ts - int32 sender_assumes = 101; -} - -message RpcResponse { google.protobuf.Value response = 1; } diff --git a/proto/javascript/javascript.proto b/proto/javascript/javascript.proto index c78b9d6..f774986 100644 --- a/proto/javascript/javascript.proto +++ b/proto/javascript/javascript.proto @@ -15,20 +15,6 @@ package dev.restate.sdk.javascript; import "proto/protocol/protocol.proto"; -message FailureWithTerminal { - dev.restate.service.protocol.Failure failure = 1; - bool terminal = 2; -} - -// Type: 0xFC00 + 1 -// Flag: RequiresRuntimeAck -message SideEffectEntryMessage { - oneof result { - bytes value = 14; - FailureWithTerminal failure = 15; - }; -} - // Type: 0xFC00 + 2 message CombinatorEntryMessage { int32 combinator_id = 1; diff --git a/proto/protocol/protocol.proto b/proto/protocol/protocol.proto index 68c9d95..333a36e 100644 --- a/proto/protocol/protocol.proto +++ b/proto/protocol/protocol.proto @@ -11,11 +11,16 @@ syntax = "proto3"; package dev.restate.service.protocol; -import "google/protobuf/empty.proto"; - option java_package = "dev.restate.generated.service.protocol"; option go_package = "restate.dev/sdk-go/pb/service/protocol"; +// Service protocol version. +enum ServiceProtocolVersion { + SERVICE_PROTOCOL_VERSION_UNSPECIFIED = 0; + // initial service protocol version + V1 = 1; +} + // --- Core frames --- // Type: 0x0000 + 0 @@ -27,13 +32,11 @@ message StartMessage { bytes value = 2; } - // Unique id of the invocation. This id is unique across invocations and won't - // change when replaying the journal. + // Unique id of the invocation. This id is unique across invocations and won't change when replaying the journal. bytes id = 1; // Invocation id that can be used for logging. - // The user can use this id to address this invocation in admin and status - // introspection apis. + // The user can use this id to address this invocation in admin and status introspection apis. string debug_id = 2; uint32 known_entries = 3; @@ -41,6 +44,9 @@ message StartMessage { // protolint:disable:next REPEATED_FIELD_NAMES_PLURALIZED repeated StateEntry state_map = 4; bool partial_state = 5; + + // If this invocation has a key associated (e.g. for objects and workflows), then this key is filled in. Empty otherwise. + string key = 6; } // Type: 0x0000 + 1 @@ -48,7 +54,7 @@ message CompletionMessage { uint32 entry_index = 1; oneof result { - google.protobuf.Empty empty = 13; + Empty empty = 13; bytes value = 14; Failure failure = 15; }; @@ -57,76 +63,84 @@ message CompletionMessage { // Type: 0x0000 + 2 // Implementations MUST send this message when suspending an invocation. message SuspensionMessage { - // This list represents any of the entry_index the invocation is waiting on to - // progress. The runtime will resume the invocation as soon as one of the - // given entry_index is completed. This list MUST not be empty. False - // positive, entry_indexes is a valid plural of entry_indices. + // This list represents any of the entry_index the invocation is waiting on to progress. + // The runtime will resume the invocation as soon as one of the given entry_index is completed. + // This list MUST not be empty. + // False positive, entry_indexes is a valid plural of entry_indices. // https://learn.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/i/index-indexes-indices - repeated uint32 entry_indexes = - 1; // protolint:disable:this REPEATED_FIELD_NAMES_PLURALIZED + repeated uint32 entry_indexes = 1; // protolint:disable:this REPEATED_FIELD_NAMES_PLURALIZED } // Type: 0x0000 + 3 message ErrorMessage { - // The code can be: - // * Any of the error codes defined by OutputStreamEntry.failure (see Failure - // message) - // * JOURNAL_MISMATCH = 32, that is when the SDK cannot replay a journal due - // to the mismatch between the journal and the actual code. - // * PROTOCOL_VIOLATION = 33, that is when the SDK receives an unexpected - // message or an expected message variant, given its state. - // - // If 16 < code < 32, or code > 33, the runtime will interpret it as code 2 - // (UNKNOWN). + // The code can be any HTTP status code, as described https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml. + // In addition, we define the following error codes that MAY be used by the SDK for better error reporting: + // * JOURNAL_MISMATCH = 570, that is when the SDK cannot replay a journal due to the mismatch between the journal and the actual code. + // * PROTOCOL_VIOLATION = 571, that is when the SDK receives an unexpected message or an expected message variant, given its state. uint32 code = 1; // Contains a concise error message, e.g. Throwable#getMessage() in Java. string message = 2; // Contains a verbose error description, e.g. the exception stacktrace. string description = 3; + + // Entry that caused the failure. This may be outside the current stored journal size. + // If no specific entry caused the failure, the current replayed/processed entry can be used. + optional uint32 related_entry_index = 4; + // Name of the entry that caused the failure. + optional string related_entry_name = 5; + // Entry type. + optional uint32 related_entry_type = 6; } // Type: 0x0000 + 4 -message EntryAckMessage { uint32 entry_index = 1; } +message EntryAckMessage { + uint32 entry_index = 1; +} // Type: 0x0000 + 5 // Implementations MUST send this message when the invocation lifecycle ends. -message EndMessage {} +message EndMessage { +} // --- Journal Entries --- -// Every Completable JournalEntry has a result field, filled only and only if -// the entry is in DONE state. Depending on the semantics of the corresponding -// syscall, the entry can represent the result field with any of these three -// types: +// Every Completable JournalEntry has a result field, filled only and only if the entry is in DONE state. +// +// For every journal entry, fields 12, 13, 14 and 15 are reserved. +// +// The field 12 is used for name. The name is used by introspection/observability tools. +// +// Depending on the semantics of the corresponding syscall, the entry can represent the completion result field with any of these three types: // -// * google.protobuf.Empty empty = 13 for cases when we need to propagate to -// user code the distinction between default value or no value. +// * google.protobuf.Empty empty = 13 for cases when we need to propagate to user code the distinction between default value or no value. // * bytes value = 14 for carrying the result value // * Failure failure = 15 for carrying a failure -// -// The tag numbers 13, 14 and 15 are reserved and shouldn't be used for other -// fields. // ------ Input and output ------ -// Completable: Yes +// Completable: No // Fallible: No // Type: 0x0400 + 0 -message PollInputStreamEntryMessage { - oneof result { - bytes value = 14; - Failure failure = 15; - } +message InputEntryMessage { + repeated Header headers = 1; + + bytes value = 14; + + // Entry name + string name = 12; } // Completable: No // Fallible: No // Type: 0x0400 + 1 -message OutputStreamEntryMessage { +message OutputEntryMessage { oneof result { bytes value = 14; Failure failure = 15; }; + + // Entry name + string name = 12; } // ------ State access ------ @@ -138,10 +152,13 @@ message GetStateEntryMessage { bytes key = 1; oneof result { - google.protobuf.Empty empty = 13; + Empty empty = 13; bytes value = 14; Failure failure = 15; }; + + // Entry name + string name = 12; } // Completable: No @@ -150,28 +167,98 @@ message GetStateEntryMessage { message SetStateEntryMessage { bytes key = 1; bytes value = 3; + + // Entry name + string name = 12; } // Completable: No // Fallible: No // Type: 0x0800 + 2 -message ClearStateEntryMessage { bytes key = 1; } +message ClearStateEntryMessage { + bytes key = 1; + + // Entry name + string name = 12; +} // Completable: No // Fallible: No // Type: 0x0800 + 3 -message ClearAllStateEntryMessage {} +message ClearAllStateEntryMessage { + // Entry name + string name = 12; +} // Completable: Yes // Fallible: No // Type: 0x0800 + 4 message GetStateKeysEntryMessage { - message StateKeys { repeated bytes keys = 1; } + message StateKeys { + repeated bytes keys = 1; + } oneof result { StateKeys value = 14; Failure failure = 15; }; + + // Entry name + string name = 12; +} + +// Completable: Yes +// Fallible: No +// Type: 0x0800 + 8 +message GetPromiseEntryMessage { + string key = 1; + + oneof result { + bytes value = 14; + Failure failure = 15; + }; + + // Entry name + string name = 12; +} + +// Completable: Yes +// Fallible: No +// Type: 0x0800 + 9 +message PeekPromiseEntryMessage { + string key = 1; + + oneof result { + Empty empty = 13; + bytes value = 14; + Failure failure = 15; + }; + + // Entry name + string name = 12; +} + +// Completable: Yes +// Fallible: No +// Type: 0x0800 + A +message CompletePromiseEntryMessage { + string key = 1; + + // The value to use to complete the promise + oneof completion { + bytes completion_value = 2; + Failure completion_failure = 3; + }; + + oneof result { + // Returns empty if value was set successfully + Empty empty = 13; + // Returns a failure if the promise was already completed + Failure failure = 15; + } + + // Entry name + string name = 12; } // ------ Syscalls ------ @@ -185,32 +272,43 @@ message SleepEntryMessage { uint64 wake_up_time = 1; oneof result { - google.protobuf.Empty empty = 13; + Empty empty = 13; Failure failure = 15; } + + // Entry name + string name = 12; } // Completable: Yes // Fallible: Yes // Type: 0x0C00 + 1 -message InvokeEntryMessage { +message CallEntryMessage { string service_name = 1; - string method_name = 2; + string handler_name = 2; bytes parameter = 3; + repeated Header headers = 4; + + // If this invocation has a key associated (e.g. for objects and workflows), then this key is filled in. Empty otherwise. + string key = 5; + oneof result { bytes value = 14; Failure failure = 15; }; + + // Entry name + string name = 12; } // Completable: No // Fallible: Yes // Type: 0x0C00 + 2 -message BackgroundInvokeEntryMessage { +message OneWayCallEntryMessage { string service_name = 1; - string method_name = 2; + string handler_name = 2; bytes parameter = 3; @@ -219,18 +317,28 @@ message BackgroundInvokeEntryMessage { // If this value is not set, equal to 0, or past in time, // the runtime will execute this BackgroundInvoke as soon as possible. uint64 invoke_time = 4; + + repeated Header headers = 5; + + // If this invocation has a key associated (e.g. for objects and workflows), then this key is filled in. Empty otherwise. + string key = 6; + + // Entry name + string name = 12; } // Completable: Yes // Fallible: No // Type: 0x0C00 + 3 -// Awakeables are addressed by an identifier exposed to the user. See the spec -// for more details. +// Awakeables are addressed by an identifier exposed to the user. See the spec for more details. message AwakeableEntryMessage { oneof result { bytes value = 14; Failure failure = 15; }; + + // Entry name + string name = 12; } // Completable: No @@ -241,23 +349,43 @@ message CompleteAwakeableEntryMessage { string id = 1; oneof result { - bytes value = 5; - Failure failure = 6; + bytes value = 14; + Failure failure = 15; + }; + + // Entry name + string name = 12; +} + +// Completable: No +// Fallible: No +// Type: 0x0C00 + 5 +// Flag: RequiresRuntimeAck +message RunEntryMessage { + oneof result { + bytes value = 14; + dev.restate.service.protocol.Failure failure = 15; }; + + // Entry name + string name = 12; } // --- Nested messages // This failure object carries user visible errors, -// e.g. invocation failure return value or failure result of an -// InvokeEntryMessage. +// e.g. invocation failure return value or failure result of an InvokeEntryMessage. message Failure { - // The code should be any of the gRPC error codes, - // as defined here: - // https://github.com/grpc/grpc/blob/master/doc/statuscodes.md#status-codes-and-their-use-in-grpc - // - // If code > 16, the runtime will interpret it as code 2 (UNKNOWN). + // The code can be any HTTP status code, as described https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml. uint32 code = 1; // Contains a concise error message, e.g. Throwable#getMessage() in Java. string message = 2; } + +message Header { + string key = 1; + string value = 2; +} + +message Empty { +} diff --git a/proto/services/services.proto b/proto/services/services.proto deleted file mode 100644 index 59c939e..0000000 --- a/proto/services/services.proto +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH -// -// This file is part of the Restate service protocol, which is -// released under the MIT license. -// -// You can find a copy of the license in file LICENSE in the root -// directory of this repository or package, or at -// https://github.com/restatedev/proto/blob/main/LICENSE - -syntax = "proto3"; - -/* - This package contains internal service interfaces - */ -package dev.restate.service.services; - -import "dev/restate/ext.proto"; -import "google/protobuf/empty.proto"; -import "google/protobuf/struct.proto"; - -// RemoteContext service to implement the embedded handler API -service RemoteContext { - option (dev.restate.ext.service_type) = KEYED; - - // Start a new invocation, or resume a previously existing one. - // - // If another client is already executing this invocation, it will be fenced - // off and this client will take precedence. - // - // This method is not idempotent. - rpc Start(StartRequest) returns (StartResponse); - - // Send new messages to append to the message stream. - // - // This method is not idempotent, and a request can fail for several reasons, - // including errors in sent messages, or some other transient error. - // The client should consider the stream in an unrecoverable error state and - // it can retry by creating a new stream through Start() with a different - // stream_id. - // - // Once the invocation is completed, subsequent Send fail. - rpc Send(SendRequest) returns (SendResponse); - - // Receive new messages from the message stream. - // - // This method is not idempotent, and a request can fail for several reasons, - // including errors in sent messages, or some other transient error. - // The client should consider the stream in an unrecoverable error state and - // it can retry by creating a new stream through Start() with a different - // stream_id. - // - // If the invocation is completed, Recv returns a response with messages field - // empty. - rpc Recv(RecvRequest) returns (RecvResponse); - - // Get the result of the invocation. - // - // In case another client is executing the invocation (through a sequence of - // Start/Send/Recv), this method will block until a response is computed. In - // case the response is already available, it will return immediately with the - // response. In case no client is executing the invocation, that is no client - // ever invoked Start() for the given operation_id, this method will return - // response.none. - // - // This method can be safely invoked by multiple clients and it's idempotent. - rpc GetResult(GetResultRequest) returns (GetResultResponse); - - // Cleanup all the state of the invocation, excluding the user state. - // - // This is automatically executed when retention_period_sec is past, but it - // can be manually invoked before the expiry time elapsed. - rpc Cleanup(CleanupRequest) returns (google.protobuf.Empty); -} - -message StartRequest { - // User provided operation id, this is used as idempotency key. - string operation_id = 1 [ (dev.restate.ext.field) = KEY ]; - - // Stream id to uniquely identify a open stream between client and Restate. - // There can be at most one open stream at the same time. - string stream_id = 2; - - // Retention period for the response in seconds. - // After the invocation completes, the response will be persisted for the - // given duration. Afterwards, the system will cleanup the response and treats - // any subsequent invocation with same operation_id as new. - // - // If not set, 30 minutes will be used as retention period. - uint32 retention_period_sec = 3; - - // Argument of the invocation - bytes argument = 4; -} - -message StartResponse { - oneof invocation_status { - // Contains the concatenated first messages of the stream, encoded using the - // same framing used by service-protocol - bytes executing = 1; - - // Contains the result of the invocation - GetResultResponse completed = 2; - } -} - -message SendRequest { - // User provided operation id, this is used as idempotency key. - string operation_id = 1 [ (dev.restate.ext.field) = KEY ]; - - // Stream id to uniquely identify a open stream between client and Restate. - // There can be at most one open stream at the same time. - string stream_id = 2; - - // Contains the concatenated messages of the stream, encoded using the same - // framing used by service-protocol - bytes messages = 3; -} - -message SendResponse { - oneof response { - google.protobuf.Empty ok = 1; - - // This means the provided stream_id is invalid, and it should not be - // reused, nor the client should create a new stream using Start(). The - // client can instead read the invocation result using GetResult(). - google.protobuf.Empty invalid_stream = 2; - - // This means the invocation is completed, and the result should be - // collected using GetResult - google.protobuf.Empty invocation_completed = 3; - } -} - -message RecvRequest { - // User provided operation id, this is used as idempotency key. - string operation_id = 1 [ (dev.restate.ext.field) = KEY ]; - - // Stream id to uniquely identify a open stream between client and Restate. - // There can be at most one open stream at the same time. - string stream_id = 2; -} - -message RecvResponse { - oneof response { - // Contains the concatenated messages of the stream, encoded using the same - // framing used by service-protocol - bytes messages = 1; - - // This means the provided stream_id is invalid, and it should not be - // reused, nor the client should create a new stream using Start(). The - // client can instead read the invocation result using GetResult(). - google.protobuf.Empty invalid_stream = 2; - - // This means the invocation is completed, and the result should be - // collected using GetResult - google.protobuf.Empty invocation_completed = 3; - } -} - -message GetResultRequest { - // User provided operation id, this is used as idempotency key. - string operation_id = 1 [ (dev.restate.ext.field) = KEY ]; -} - -message GetResultResponse { - message InvocationFailure { - uint32 code = 1; - string message = 2; - } - - oneof response { - // See GetResult documentation - google.protobuf.Empty none = 1; - bytes success = 2; - InvocationFailure failure = 3; - } - - // Timestamp of the response expiry time in RFC3339. - // Empty if response = none - string expiry_time = 15; -} - -message CleanupRequest { - // User provided operation id, this is used as idempotency key. - string operation_id = 1 [ (dev.restate.ext.field) = KEY ]; -} diff --git a/router.go b/router.go index ac6b2d5..de8f5bb 100644 --- a/router.go +++ b/router.go @@ -5,30 +5,19 @@ import ( "fmt" "time" - "github.com/cenkalti/backoff/v4" - "github.com/restatedev/sdk-go/generated/proto/dynrpc" + "github.com/restatedev/sdk-go/internal" "github.com/vmihailenco/msgpack/v5" ) var ( ErrKeyNotFound = fmt.Errorf("key not found") - //DefaultBackoffPolicy is an infinite exponential backoff - DefaultBackoffPolicy = backoff.ExponentialBackOff{ - InitialInterval: 10 * time.Microsecond, - RandomizationFactor: backoff.DefaultRandomizationFactor, - Multiplier: backoff.DefaultMultiplier, - MaxInterval: backoff.DefaultMaxInterval, - MaxElapsedTime: 0, - Stop: backoff.Stop, - Clock: backoff.SystemClock, - } ) type Call interface { // Do makes a call and wait for the response - Do(key string, input any, output any) error + Do(input any, output any) error // Send makes a call in the background (doesn't wait for response) after delay duration - Send(key string, body any, delay time.Duration) error + Send(body any, delay time.Duration) error } type Service interface { @@ -36,9 +25,70 @@ type Service interface { Method(method string) Call } +type Object interface { + // Method creates a call to method with name + Method(method string) Call +} + type Context interface { // Context of request. Ctx() context.Context + // Sleep sleep during the execution until time is reached + Sleep(until time.Time) error + // Service gets a Service accessor by name where service + // must be another service known by restate runtime + Service(service string) Service + // Object gets a Object accessor by name where object + // must be another object known by restate runtime and + // key is any string representing the key for the object + Object(object, key string) Object + + // SideEffects runs the function (fn) until it succeeds or permanently fails. + // this stores the results of the function inside restate runtime so a replay + // will produce the same value (think generating a unique id for example) + // Note: use the SideEffectAs helper function + SideEffect(fn func() ([]byte, error)) ([]byte, error) +} + +// Router interface +type Router interface { + Type() internal.ServiceType + // Set of handlers associated with this router + Handlers() map[string]Handler +} + +type Handler interface { + Call(ctx Context, request []byte) (output []byte, err error) + sealed() +} + +type ServiceType string + +const ( + ServiceType_VIRTUAL_OBJECT ServiceType = "VIRTUAL_OBJECT" + ServiceType_SERVICE ServiceType = "SERVICE" +) + +type ObjectHandlerWrapper struct { + h *ObjectHandler +} + +func (o ObjectHandlerWrapper) Call(ctx Context, request []byte) ([]byte, error) { + switch ctx := ctx.(type) { + case ObjectContext: + return o.h.Call(ctx, request) + default: + panic("Object handler called with context that doesn't implement ObjectContext") + } +} + +func (ObjectHandlerWrapper) sealed() {} + +type ServiceHandlerWrapper struct { + h ServiceHandler +} + +type KeyValueStore interface { // Set sets key value to bytes array. You can // Note: Use SetAs helper function to seamlessly store // a value of specific type. @@ -55,94 +105,79 @@ type Context interface { ClearAll() error // Keys returns a list of all associated key Keys() ([]string, error) - // Sleep sleep during the execution until time is reached - Sleep(until time.Time) error - // Service gets a Service accessor by name where service - // must be another service known by restate runtime - Service(service string) Service - - // SideEffects runs the function (fn) with backoff strategy bo until it succeeds - // or permanently fail. - // this stores the results of the function inside restate runtime so a replay - // will produce the same value (think generating a unique id for example) - // Note: use the SideEffectAs helper function - SideEffect(fn func() ([]byte, error), bo ...backoff.BackOff) ([]byte, error) } -// UnKeyedHandlerFn signature of `un-keyed` handler function -type UnKeyedHandlerFn[I any, O any] func(ctx Context, input I) (output O, err error) - -// KeyedHandlerFn signature for `keyed` handler function -type KeyedHandlerFn[I any, O any] func(ctx Context, key string, input I) (output O, err error) - -// Handler interface. -type Handler interface { - Call(ctx Context, request *dynrpc.RpcRequest) (output *dynrpc.RpcResponse, err error) - sealed() +type ObjectContext interface { + Context + KeyValueStore + Key() string } -// Router interface -type Router interface { - Keyed() bool - // Set of handlers associated with this router - Handlers() map[string]Handler -} +// ServiceHandlerFn signature of service (unkeyed) handler function +type ServiceHandlerFn[I any, O any] func(ctx Context, input I) (output O, err error) + +// ObjectHandlerFn signature for object (keyed) handler function +type ObjectHandlerFn[I any, O any] func(ctx ObjectContext, input I) (output O, err error) -// UnKeyedRouter implements Router -type UnKeyedRouter struct { +// ServiceRouter implements Router +type ServiceRouter struct { handlers map[string]Handler } -// NewUnKeyedRouter creates a new UnKeyedRouter -func NewUnKeyedRouter() *UnKeyedRouter { - return &UnKeyedRouter{ +var _ Router = &ServiceRouter{} + +// NewServiceRouter creates a new ServiceRouter +func NewServiceRouter() *ServiceRouter { + return &ServiceRouter{ handlers: make(map[string]Handler), } } // Handler registers a new handler by name -func (r *UnKeyedRouter) Handler(name string, handler *UnKeyedHandler) *UnKeyedRouter { +func (r *ServiceRouter) Handler(name string, handler *ServiceHandler) *ServiceRouter { r.handlers[name] = handler return r } -func (r *UnKeyedRouter) Keyed() bool { - return false +func (r *ServiceRouter) Handlers() map[string]Handler { + return r.handlers } -func (r *UnKeyedRouter) Handlers() map[string]Handler { - return r.handlers +func (r *ServiceRouter) Type() internal.ServiceType { + return internal.ServiceType_SERVICE } -// KeyedRouter -type KeyedRouter struct { +// ObjectRouter +type ObjectRouter struct { handlers map[string]Handler } -func NewKeyedRouter() *KeyedRouter { - return &KeyedRouter{ +var _ Router = &ObjectRouter{} + +func NewObjectRouter() *ObjectRouter { + return &ObjectRouter{ handlers: make(map[string]Handler), } } -func (r *KeyedRouter) Handler(name string, handler *KeyedHandler) *KeyedRouter { - r.handlers[name] = handler +func (r *ObjectRouter) Handler(name string, handler *ObjectHandler) *ObjectRouter { + r.handlers[name] = ObjectHandlerWrapper{h: handler} return r } -func (r *KeyedRouter) Keyed() bool { - return true +func (r *ObjectRouter) Handlers() map[string]Handler { + return r.handlers } -func (r *KeyedRouter) Handlers() map[string]Handler { - return r.handlers +func (r *ObjectRouter) Type() internal.ServiceType { + return internal.ServiceType_VIRTUAL_OBJECT } // GetAs helper function to get a key as specific type. Note that // if there is no associated value with key, an error ErrKeyNotFound is // returned // it does encoding/decoding of bytes automatically using msgpack -func GetAs[T any](ctx Context, key string) (output T, err error) { +func GetAs[T any](ctx ObjectContext, key string) (output T, err error) { bytes, err := ctx.Get(key) if err != nil { return output, err @@ -160,7 +195,7 @@ func GetAs[T any](ctx Context, key string) (output T, err error) { // SetAs helper function to set a key value with a generic type T. // it does encoding/decoding of bytes automatically using msgpack -func SetAs[T any](ctx Context, key string, value T) error { +func SetAs[T any](ctx ObjectContext, key string, value T) error { bytes, err := msgpack.Marshal(value) if err != nil { return err @@ -171,7 +206,7 @@ func SetAs[T any](ctx Context, key string, value T) error { // SideEffectAs helper function runs a side effect function with specific concrete type as a result // it does encoding/decoding of bytes automatically using msgpack -func SideEffectAs[T any](ctx Context, fn func() (T, error), bo ...backoff.BackOff) (output T, err error) { +func SideEffectAs[T any](ctx Context, fn func() (T, error)) (output T, err error) { bytes, err := ctx.SideEffect(func() ([]byte, error) { out, err := fn() if err != nil { @@ -180,7 +215,7 @@ func SideEffectAs[T any](ctx Context, fn func() (T, error), bo ...backoff.BackOf bytes, err := msgpack.Marshal(out) return bytes, TerminalError(err) - }, bo...) + }) if err != nil { return output, err diff --git a/server/restate.go b/server/restate.go index caf0fb6..5b90144 100644 --- a/server/restate.go +++ b/server/restate.go @@ -2,21 +2,43 @@ package server import ( "context" + "encoding/json" "fmt" "net" "net/http" + "runtime/debug" "strings" "github.com/posener/h2conn" - "github.com/restatedev/sdk-go" + restate "github.com/restatedev/sdk-go" "github.com/restatedev/sdk-go/generated/proto/discovery" + "github.com/restatedev/sdk-go/generated/proto/protocol" "github.com/restatedev/sdk-go/internal" "github.com/restatedev/sdk-go/internal/state" "github.com/rs/zerolog/log" "golang.org/x/net/http2" - "google.golang.org/protobuf/proto" ) +const MIN_SERVICE_PROTOCOL_VERSION protocol.ServiceProtocolVersion = protocol.ServiceProtocolVersion_V1 +const MAX_SERVICE_PROTOCOL_VERSION protocol.ServiceProtocolVersion = protocol.ServiceProtocolVersion_V1 +const MIN_SERVICE_DISCOVERY_PROTOCOL_VERSION discovery.ServiceDiscoveryProtocolVersion = discovery.ServiceDiscoveryProtocolVersion_V1 +const MAX_SERVICE_DISCOVERY_PROTOCOL_VERSION discovery.ServiceDiscoveryProtocolVersion = discovery.ServiceDiscoveryProtocolVersion_V1 + +var X_RESTATE_SERVER = `restate-sdk-go/unknown` + +func init() { + bi, ok := debug.ReadBuildInfo() + if !ok { + return + } + for _, dep := range bi.Deps { + if dep.Path == "github.com/restatedev/sdk-go" { + X_RESTATE_SERVER = "restate-sdk-go/" + dep.Version + break + } + } +} + type Restate struct { routers map[string]restate.Router } @@ -40,39 +62,58 @@ func (r *Restate) Bind(name string, router restate.Router) *Restate { return r } -func (r *Restate) discover() (resource *discovery.ServiceDiscoveryResponse, err error) { - ds := internal.NewDynRpcDescriptorSet() - resource = &discovery.ServiceDiscoveryResponse{ - ProtocolMode: discovery.ProtocolMode_BIDI_STREAM, - Files: ds.Inner(), +func (r *Restate) discover() (resource *internal.Endpoint, err error) { + resource = &internal.Endpoint{ + ProtocolMode: internal.ProtocolMode_BIDI_STREAM, + MinProtocolVersion: 1, + MaxProtocolVersion: 2, + Services: make([]internal.Service, 0, len(r.routers)), } for name, router := range r.routers { - resource.Services = append(resource.Services, name) - var service *internal.DynRpcService - if router.Keyed() { - service, err = ds.AddKeyedService(name) - } else { - service, err = ds.AddUnKeyedService(name) - } - - if err != nil { - return resource, fmt.Errorf("failed to build service '%s': %w", name, err) + service := internal.Service{ + Name: name, + Ty: router.Type(), + Handlers: make([]internal.Handler, 0, len(router.Handlers())), } for name := range router.Handlers() { - service.AddHandler(name) + service.Handlers = append(service.Handlers, internal.Handler{ + Name: name, + Input: &internal.InputPayload{ + Required: false, + ContentType: "application/json", // TODO configurable handler encoding + }, + Output: &internal.OutputPayload{ + SetContentTypeIfEmpty: false, + ContentType: "application/json", + }, + }) } + resource.Services = append(resource.Services, service) } - resource.Files = ds.Inner() - return } -func (r *Restate) discoverHandler(writer http.ResponseWriter, _ *http.Request) { +func (r *Restate) discoverHandler(writer http.ResponseWriter, req *http.Request) { log.Trace().Msg("discover called") - writer.Header().Add("Content-Type", "application/proto") + + acceptVersionsString := req.Header.Get("accept") + if acceptVersionsString == "" { + writer.Write([]byte("missing accept header")) + writer.WriteHeader(http.StatusUnsupportedMediaType) + + return + } + + serviceDiscoveryProtocolVersion := selectSupportedServiceDiscoveryProtocolVersion(acceptVersionsString) + + if serviceDiscoveryProtocolVersion == discovery.ServiceDiscoveryProtocolVersion_SERVICE_DISCOVERY_PROTOCOL_VERSION_UNSPECIFIED { + writer.Write([]byte(fmt.Sprint("Unsupported service discovery protocol version '%s'", acceptVersionsString))) + writer.WriteHeader(http.StatusUnsupportedMediaType) + return + } response, err := r.discover() if err != nil { @@ -82,7 +123,7 @@ func (r *Restate) discoverHandler(writer http.ResponseWriter, _ *http.Request) { return } - bytes, err := proto.Marshal(response) + bytes, err := json.Marshal(response) if err != nil { writer.Write([]byte(err.Error())) writer.WriteHeader(http.StatusInternalServerError) @@ -90,17 +131,72 @@ func (r *Restate) discoverHandler(writer http.ResponseWriter, _ *http.Request) { return } + writer.Header().Add("Content-Type", serviceDiscoveryProtocolVersionToHeaderValue(serviceDiscoveryProtocolVersion)) writer.WriteHeader(200) if _, err := writer.Write(bytes); err != nil { log.Error().Err(err).Msg("failed to write discovery information") } } +func selectSupportedServiceDiscoveryProtocolVersion(accept string) discovery.ServiceDiscoveryProtocolVersion { + maxVersion := discovery.ServiceDiscoveryProtocolVersion_SERVICE_DISCOVERY_PROTOCOL_VERSION_UNSPECIFIED + + for _, versionString := range strings.Split(accept, ",") { + version := parseServiceDiscoveryProtocolVersion(versionString) + if isServiceDiscoveryProtocolVersionSupported(version) && version > maxVersion { + maxVersion = version + } + } + + return maxVersion +} + +func parseServiceDiscoveryProtocolVersion(versionString string) discovery.ServiceDiscoveryProtocolVersion { + if strings.TrimSpace(versionString) == "application/vnd.restate.endpointmanifest.v1+json" { + return discovery.ServiceDiscoveryProtocolVersion_V1 + } + + return discovery.ServiceDiscoveryProtocolVersion_SERVICE_DISCOVERY_PROTOCOL_VERSION_UNSPECIFIED +} + +func isServiceDiscoveryProtocolVersionSupported(version discovery.ServiceDiscoveryProtocolVersion) bool { + return version >= MIN_SERVICE_DISCOVERY_PROTOCOL_VERSION && version <= MAX_SERVICE_DISCOVERY_PROTOCOL_VERSION +} + +func serviceDiscoveryProtocolVersionToHeaderValue(serviceDiscoveryProtocolVersion discovery.ServiceDiscoveryProtocolVersion) string { + switch serviceDiscoveryProtocolVersion { + case discovery.ServiceDiscoveryProtocolVersion_V1: + return "application/vnd.restate.endpointmanifest.v1+json" + } + panic(fmt.Sprintf("unexpected service discovery protocol version %d", serviceDiscoveryProtocolVersion)) +} + +func parseServiceProtocolVersion(versionString string) protocol.ServiceProtocolVersion { + if strings.TrimSpace(versionString) == "application/vnd.restate.invocation.v1" { + return protocol.ServiceProtocolVersion_V1 + } + + return protocol.ServiceProtocolVersion_SERVICE_PROTOCOL_VERSION_UNSPECIFIED +} + +func isServiceProtocolVersionSupported(version protocol.ServiceProtocolVersion) bool { + return version >= MIN_SERVICE_PROTOCOL_VERSION && version <= MAX_SERVICE_PROTOCOL_VERSION +} + +func serviceProtocolVersionToHeaderValue(serviceProtocolVersion protocol.ServiceProtocolVersion) string { + switch serviceProtocolVersion { + case protocol.ServiceProtocolVersion_V1: + return "application/vnd.restate.invocation.v1" + } + panic(fmt.Sprintf("unexpected service protocol version %d", serviceProtocolVersion)) +} + // takes care of function call -func (r *Restate) callHandler(service, fn string, writer http.ResponseWriter, request *http.Request) { +func (r *Restate) callHandler(serviceProtocolVersion protocol.ServiceProtocolVersion, service, fn string, writer http.ResponseWriter, request *http.Request) { log.Debug().Str("service", service).Str("handler", fn).Msg("new request") - writer.Header().Add("content-type", "application/restate") + writer.Header().Add("x-restate-server", X_RESTATE_SERVER) + writer.Header().Add("content-type", serviceProtocolVersionToHeaderValue(serviceProtocolVersion)) router, ok := r.routers[service] if !ok { @@ -133,15 +229,28 @@ func (r *Restate) callHandler(service, fn string, writer http.ResponseWriter, re func (r *Restate) handler(writer http.ResponseWriter, request *http.Request) { log.Trace().Str("proto", request.Proto).Str("method", request.Method).Str("path", request.RequestURI).Msg("got request") - if request.Method != http.MethodPost { - writer.WriteHeader(http.StatusMethodNotAllowed) + if request.RequestURI == "/discover" { + r.discoverHandler(writer, request) return } - if request.RequestURI == "/discover" { - r.discoverHandler(writer, request) + serviceProtocolVersionString := request.Header.Get("content-type") + if serviceProtocolVersionString == "" { + writer.Write([]byte("missing content-type header")) + writer.WriteHeader(http.StatusUnsupportedMediaType) + return } + + serviceProtocolVersion := parseServiceProtocolVersion(serviceProtocolVersionString) + + if !isServiceProtocolVersionSupported(serviceProtocolVersion) { + writer.Write([]byte(fmt.Sprintf("Unsupported service protocol version '%s'", serviceProtocolVersionString))) + writer.WriteHeader(http.StatusUnsupportedMediaType) + + return + } + // we expecting the uri to be something like `/invoke/{service}/{method}` // so if !strings.HasPrefix(request.RequestURI, "/invoke/") { @@ -155,7 +264,7 @@ func (r *Restate) handler(writer http.ResponseWriter, request *http.Request) { return } - r.callHandler(parts[0], parts[1], writer, request) + r.callHandler(serviceProtocolVersion, parts[0], parts[1], writer, request) } func (r *Restate) Start(ctx context.Context, address string) error { From 22397130d0a7ff0a34f33414ae986f71cb9791a8 Mon Sep 17 00:00:00 2001 From: Jack Kleeman <jackkleeman@gmail.com> Date: Sat, 6 Jul 2024 20:24:52 +0100 Subject: [PATCH 02/13] experimental awakeable support --- error.go | 139 +------------------------------ internal/state/awakeable.go | 160 ++++++++++++++++++++++++++++++++++++ internal/state/state.go | 22 +++-- internal/wire/wire.go | 32 +++++++- router.go | 56 +++++++++++++ server/restate.go | 2 +- 6 files changed, 265 insertions(+), 146 deletions(-) create mode 100644 internal/state/awakeable.go diff --git a/error.go b/error.go index 56d19e9..7ff33b1 100644 --- a/error.go +++ b/error.go @@ -7,143 +7,6 @@ import ( type Code uint16 -const ( - /** - * The operation was cancelled, typically by the caller. - * HTTP 408 - */ - CANCELLED Code = 1 - /** - * Unknown error. For example, this error may be returned when a - * Status value received from another address space belongs to an error - * space that is not known in this address space. Also errors raised by APIs - * that do not return enough error information may be converted to this - * error. - * HTTP 500 - */ - UNKNOWN Code = 2 - /** - * The client specified an invalid argument. Note that - * this differs from FAILED_PRECONDITION. INVALID_ARGUMENT indicates - * arguments that are problematic regardless of the state of the system - * (e.g., a malformed file name). - * HTTP 400 - */ - INVALID_ARGUMENT Code = 3 - /** - * The deadline expired before the operation could - * complete. For operations that change the state of the system, this error - * may be returned even if the operation has completed successfully. For - * example, a successful response from a server could have been delayed - * long. - * HTTP 408 - */ - DEADLINE_EXCEEDED Code = 4 - /** - * Some requested entity (e.g., file or directory) was not - * found. Note to server developers: if a request is denied for an entire - * class of users, such as gradual feature rollout or undocumented - * allowlist, NOT_FOUND may be used. If a request is denied for some users - * within a class of users, such as user-based access control, - * PERMISSION_DENIED must be used. - * HTTP 404 - */ - NOT_FOUND Code = 5 - /** - * The entity that a client attempted to create (e.g., file - * or directory) already exists. - * HTTP 409 - */ - ALREADY_EXISTS Code = 6 - /** - * The caller does not have permission to execute the - * specified operation. PERMISSION_DENIED must not be used for rejections - * caused by exhausting some resource (use RESOURCE_EXHAUSTED instead for - * those errors). PERMISSION_DENIED must not be used if the caller can not - * be identified (use UNAUTHENTICATED instead for those errors). This error - * code does not imply the request is valid or the requested entity exists - * or satisfies other pre-conditions. - * HTTP 403 - */ - PERMISSION_DENIED Code = 7 - /** - * Some resource has been exhausted, perhaps a per-user - * quota, or perhaps the entire file system is out of space. - * HTTP 413 - */ - RESOURCE_EXHAUSTED Code = 8 - /** - * The operation was rejected because the system is - * not in a state required for the operation's execution. For example, the - * directory to be deleted is non-empty, an rmdir operation is applied to a - * non-directory, etc. Service implementors can use the following guidelines - * to decide between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE: (a) Use - * UNAVAILABLE if the client can retry just the failing call. (b) Use - * ABORTED if the client should retry at a higher level (e.g., when a - * client-specified test-and-set fails, indicating the client should restart - * a read-modify-write sequence). (c) Use FAILED_PRECONDITION if the client - * should not retry until the system state has been explicitly fixed. E.g., - * if an "rmdir" fails because the directory is non-empty, - * FAILED_PRECONDITION should be returned since the client should not retry - * unless the files are deleted from the directory. - * HTTP 412 - */ - FAILED_PRECONDITION Code = 9 - /** - * The operation was aborted, typically due to a concurrency issue - * such as a sequencer check failure or transaction abort. See the - * guidelines above for deciding between FAILED_PRECONDITION, ABORTED, and - * UNAVAILABLE. - * HTTP 409 - */ - ABORTED Code = 10 - /** - * The operation was attempted past the valid range. E.g., - * seeking or reading past end-of-file. Unlike INVALID_ARGUMENT, this error - * indicates a problem that may be fixed if the system state changes. For - * example, a 32-bit file system will generate INVALID_ARGUMENT if asked to - * read at an offset that is not in the range [0,2^32-1], but it will - * generate OUT_OF_RANGE if asked to read from an offset past the current - * file size. There is a fair bit of overlap between FAILED_PRECONDITION and - * OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error) - * when it applies so that callers who are iterating through a space can - * easily look for an OUT_OF_RANGE error to detect when they are done. - * HTTP 400 - */ - OUT_OF_RANGE Code = 11 - /** - * The operation is not implemented or is not - * supported/enabled in this service. - * HTTP 501 - */ - UNIMPLEMENTED Code = 12 - /** - * Internal errors. This means that some invariants expected by - * the underlying system have been broken. This error code is reserved for - * serious errors. - * HTTP 500 - */ - INTERNAL Code = 13 - /** - * The service is currently unavailable. This is most likely a - * transient condition, which can be corrected by retrying with a backoff. - * Note that it is not always safe to retry non-idempotent operations. - * HTTP 503 - */ - UNAVAILABLE Code = 14 - /** - * Unrecoverable data loss or corruption. - * HTTP 500 - */ - DATA_LOSS Code = 15 - /** - * The request does not have valid authentication - * credentials for the operation. - * HTTP 401 - */ - UNAUTHENTICATED Code = 16 -) - type codeError struct { code Code inner error @@ -224,5 +87,5 @@ func ErrorCode(err error) Code { return e.code } - return UNKNOWN + return 500 } diff --git a/internal/state/awakeable.go b/internal/state/awakeable.go new file mode 100644 index 0000000..9af4360 --- /dev/null +++ b/internal/state/awakeable.go @@ -0,0 +1,160 @@ +package state + +import ( + "bytes" + "encoding/base64" + "encoding/binary" + "fmt" + + restate "github.com/restatedev/sdk-go" + "github.com/restatedev/sdk-go/generated/proto/protocol" + "github.com/restatedev/sdk-go/internal/wire" +) + +const AWAKEABLE_IDENTIFIER_PREFIX = "prom_1" + +type awakeable[T any] interface { + restate.Awakeable[T] + setEntryIndex(entryIndex uint32) +} + +type completedAwakeable[T any] struct { + invocationID []byte + entryIndex uint32 + result restate.Result[T] +} + +func (c completedAwakeable[T]) Id() string { return awakeableID(c.invocationID, c.entryIndex) } +func (c completedAwakeable[T]) Chan() <-chan restate.Result[T] { + ch := make(chan restate.Result[T], 1) + ch <- c.result + return ch +} +func (c completedAwakeable[T]) setEntryIndex(entryIndex uint32) { c.entryIndex = entryIndex } + +type suspendingAwakeable[T any] struct { + invocationID []byte + entryIndex uint32 +} + +func (c suspendingAwakeable[T]) Id() string { return awakeableID(c.invocationID, c.entryIndex) } + +// this is a temporary hack; always suspend when this channel is read +// currently needed because we don't have a way to process the completion while the invocation is in progress +// and so can only deal with it on replay +func (c suspendingAwakeable[T]) Chan() <-chan restate.Result[T] { + panic(&suspend{resumeEntry: c.entryIndex}) +} +func (c suspendingAwakeable[T]) setEntryIndex(entryIndex uint32) { c.entryIndex = entryIndex } + +func awakeableID(invocationID []byte, entryIndex uint32) string { + bytes := make([]byte, 0, len(invocationID)+4) + bytes = append(bytes, invocationID...) + bytes = binary.BigEndian.AppendUint32(bytes, entryIndex) + return base64.URLEncoding.EncodeToString(bytes) +} + +func (c *Machine) awakeable() (restate.Awakeable[[]byte], error) { + awakeable, err := replayOrNew( + c, + wire.AwakeableEntryMessageType, + func(entry *wire.AwakeableEntryMessage) (awakeable[[]byte], error) { + if entry.Payload.Result == nil { + return suspendingAwakeable[[]byte]{invocationID: c.id}, nil + } + switch result := entry.Payload.Result.(type) { + case *protocol.AwakeableEntryMessage_Value: + return completedAwakeable[[]byte]{invocationID: c.id, result: restate.Result[[]byte]{Value: result.Value}}, nil + case *protocol.AwakeableEntryMessage_Failure: + return completedAwakeable[[]byte]{invocationID: c.id, result: restate.Result[[]byte]{Err: restate.TerminalError(fmt.Errorf(result.Failure.Message), restate.Code(result.Failure.Code))}}, nil + default: + panic("unreachable") + } + }, + func() (awakeable[[]byte], error) { + if err := c._awakeable(); err != nil { + return nil, err + } + return suspendingAwakeable[[]byte]{invocationID: c.id}, nil + }, + ) + if err != nil { + return nil, err + } + // This needs to be done after handling the message in the state machine + // otherwise the index is not yet incremented. + awakeable.setEntryIndex(uint32(c.entryIndex)) + return awakeable, nil +} + +func (c *Machine) _awakeable() error { + if err := c.protocol.Write(&protocol.AwakeableEntryMessage{}); err != nil { + return err + } + return nil +} + +func (c *Machine) resolveAwakeable(id string, value []byte) error { + _, err := replayOrNew( + c, + wire.CompleteAwakeableEntryMessageType, + func(entry *wire.CompleteAwakeableEntryMessage) (restate.Void, error) { + messageValue, ok := entry.Payload.Result.(*protocol.CompleteAwakeableEntryMessage_Value) + if entry.Payload.Id != id || !ok || !bytes.Equal(messageValue.Value, value) { + return restate.Void{}, errEntryMismatch + } + return restate.Void{}, nil + }, + func() (restate.Void, error) { + if err := c._resolveAwakeable(id, value); err != nil { + return restate.Void{}, err + } + return restate.Void{}, nil + }, + ) + return err +} + +func (c *Machine) _resolveAwakeable(id string, value []byte) error { + if err := c.protocol.Write(&protocol.CompleteAwakeableEntryMessage{ + Id: id, + Result: &protocol.CompleteAwakeableEntryMessage_Value{Value: value}, + }); err != nil { + return err + } + return nil +} + +func (c *Machine) rejectAwakeable(id string, reason error) error { + _, err := replayOrNew( + c, + wire.CompleteAwakeableEntryMessageType, + func(entry *wire.CompleteAwakeableEntryMessage) (restate.Void, error) { + messageFailure, ok := entry.Payload.Result.(*protocol.CompleteAwakeableEntryMessage_Failure) + if entry.Payload.Id != id || !ok || messageFailure.Failure.Code != 500 || messageFailure.Failure.Message != reason.Error() { + return restate.Void{}, errEntryMismatch + } + return restate.Void{}, nil + }, + func() (restate.Void, error) { + if err := c._rejectAwakeable(id, reason); err != nil { + return restate.Void{}, err + } + return restate.Void{}, nil + }, + ) + return err +} + +func (c *Machine) _rejectAwakeable(id string, reason error) error { + if err := c.protocol.Write(&protocol.CompleteAwakeableEntryMessage{ + Id: id, + Result: &protocol.CompleteAwakeableEntryMessage_Failure{Failure: &protocol.Failure{ + Code: 500, + Message: reason.Error(), + }}, + }); err != nil { + return err + } + return nil +} diff --git a/internal/state/state.go b/internal/state/state.go index 66c6abd..080c3f6 100644 --- a/internal/state/state.go +++ b/internal/state/state.go @@ -93,6 +93,18 @@ func (c *Context) SideEffect(fn func() ([]byte, error)) ([]byte, error) { return c.machine.sideEffect(fn) } +func (c *Context) Awakeable() (restate.Awakeable[[]byte], error) { + return c.machine.awakeable() +} + +func (c *Context) ResolveAwakeable(id string, value []byte) error { + return c.machine.resolveAwakeable(id, value) +} + +func (c *Context) RejectAwakeable(id string, reason error) error { + return c.machine.rejectAwakeable(id, reason) +} + func (c *Context) Key() string { return c.machine.key } @@ -118,7 +130,7 @@ type Machine struct { mutex sync.Mutex // state - id string + id []byte key string partial bool @@ -153,7 +165,7 @@ func (m *Machine) Start(inner context.Context, trace string) error { start := msg.(*wire.StartMessage) - m.id = start.Payload.DebugId + m.id = start.Payload.Id m.key = start.Payload.Key m.log = log.With().Str("id", start.Payload.DebugId).Str("method", trace).Logger() @@ -197,7 +209,7 @@ func (m *Machine) output(bytes []byte, err error) proto.Message { } } -func (m *Machine) invoke(ctx *Context, key string, input []byte) error { +func (m *Machine) invoke(ctx *Context, input []byte) error { // always terminate the invocation with // an end message. // this will always terminate the connection @@ -228,7 +240,7 @@ func (m *Machine) invoke(ctx *Context, key string, input []byte) error { // unknown panic! // send an error message (retryable) err := m.protocol.Write(&protocol.ErrorMessage{ - Code: uint32(restate.INTERNAL), + Code: 500, Message: fmt.Sprint(typ), Description: string(debug.Stack()), }) @@ -279,7 +291,7 @@ func (m *Machine) process(ctx *Context, start *wire.StartMessage) error { inputMsg := msg.(*wire.InputEntryMessage) value := inputMsg.Payload.GetValue() - return m.invoke(ctx, start.Payload.Key, value) + return m.invoke(ctx, value) } diff --git a/internal/wire/wire.go b/internal/wire/wire.go index a750d0f..46f2d62 100644 --- a/internal/wire/wire.go +++ b/internal/wire/wire.go @@ -203,14 +203,18 @@ func (s *Protocol) Write(message proto.Message, flags ...Flag) error { typ = ClearStateEntryMessageType case *protocol.ClearAllStateEntryMessage: typ = ClearAllStateEntryMessageType + case *protocol.GetStateKeysEntryMessage: + typ = GetStateKeysEntryMessageType case *protocol.SleepEntryMessage: typ = SleepEntryMessageType case *protocol.CallEntryMessage: typ = CallEntryMessageType case *protocol.OneWayCallEntryMessage: typ = OneWayCallEntryMessageType - case *protocol.GetStateKeysEntryMessage: - typ = GetStateKeysEntryMessageType + case *protocol.AwakeableEntryMessage: + typ = AwakeableEntryMessageType + case *protocol.CompletePromiseEntryMessage: + typ = CompleteAwakeableEntryMessageType case *protocol.RunEntryMessage: typ = RunEntryMessageType default: @@ -341,6 +345,20 @@ var ( return msg, proto.Unmarshal(bytes, &msg.Payload) }, + AwakeableEntryMessageType: func(header Header, bytes []byte) (Message, error) { + msg := &AwakeableEntryMessage{ + Header: header, + } + + return msg, proto.Unmarshal(bytes, &msg.Payload) + }, + CompleteAwakeableEntryMessageType: func(header Header, bytes []byte) (Message, error) { + msg := &CompleteAwakeableEntryMessage{ + Header: header, + } + + return msg, proto.Unmarshal(bytes, &msg.Payload) + }, RunEntryMessageType: func(header Header, bytes []byte) (Message, error) { msg := &RunEntryMessage{ Header: header, @@ -411,6 +429,16 @@ type OneWayCallEntryMessage struct { Payload protocol.OneWayCallEntryMessage } +type AwakeableEntryMessage struct { + Header + Payload protocol.AwakeableEntryMessage +} + +type CompleteAwakeableEntryMessage struct { + Header + Payload protocol.CompleteAwakeableEntryMessage +} + type RunEntryMessage struct { Header Payload protocol.RunEntryMessage diff --git a/router.go b/router.go index de8f5bb..6a5fe14 100644 --- a/router.go +++ b/router.go @@ -2,6 +2,7 @@ package restate import ( "context" + "encoding/json" "fmt" "time" @@ -48,6 +49,10 @@ type Context interface { // will produce the same value (think generating a unique id for example) // Note: use the SideEffectAs helper function SideEffect(fn func() ([]byte, error)) ([]byte, error) + + Awakeable() (Awakeable[[]byte], error) + ResolveAwakeable(id string, value []byte) error + RejectAwakeable(id string, reason error) error } // Router interface @@ -225,3 +230,54 @@ func SideEffectAs[T any](ctx Context, fn func() (T, error)) (output T, err error return output, TerminalError(err) } + +type Awakeable[T any] interface { + Id() string + Chan() <-chan Result[T] +} + +type Result[T any] struct { + Value T + Err error +} + +type decodingAwakeable[T any] struct { + inner Awakeable[[]byte] +} + +func (d decodingAwakeable[T]) Id() string { return d.inner.Id() } +func (d decodingAwakeable[T]) Chan() <-chan Result[T] { + inner := d.inner.Chan() + out := make(chan Result[T], 1) + go func() { + result := <-inner + if result.Err != nil { + out <- Result[T]{Err: result.Err} + } else { + var value T + if err := json.Unmarshal(result.Value, &value); err != nil { + out <- Result[T]{Err: TerminalError(err)} + } else { + out <- Result[T]{Value: value} + } + } + }() + return out +} + +func AwakeableAs[T any](ctx Context) (Awakeable[T], error) { + inner, err := ctx.Awakeable() + if err != nil { + return nil, err + } + + return decodingAwakeable[T]{inner: inner}, nil +} + +func ResolveAwakeableAs[T any](ctx Context, id string, value T) error { + bytes, err := json.Marshal(value) + if err != nil { + return TerminalError(err) + } + return ctx.ResolveAwakeable(id, bytes) +} diff --git a/server/restate.go b/server/restate.go index 5b90144..c8b0256 100644 --- a/server/restate.go +++ b/server/restate.go @@ -110,7 +110,7 @@ func (r *Restate) discoverHandler(writer http.ResponseWriter, req *http.Request) serviceDiscoveryProtocolVersion := selectSupportedServiceDiscoveryProtocolVersion(acceptVersionsString) if serviceDiscoveryProtocolVersion == discovery.ServiceDiscoveryProtocolVersion_SERVICE_DISCOVERY_PROTOCOL_VERSION_UNSPECIFIED { - writer.Write([]byte(fmt.Sprint("Unsupported service discovery protocol version '%s'", acceptVersionsString))) + writer.Write([]byte(fmt.Sprintf("Unsupported service discovery protocol version '%s'", acceptVersionsString))) writer.WriteHeader(http.StatusUnsupportedMediaType) return } From 990bf71f4aa61b8931e152353769b273f210de48 Mon Sep 17 00:00:00 2001 From: Jack Kleeman <jackkleeman@gmail.com> Date: Sat, 6 Jul 2024 21:25:59 +0100 Subject: [PATCH 03/13] handle the case with no input data --- handler.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/handler.go b/handler.go index 8d9e5fb..d6b0220 100644 --- a/handler.go +++ b/handler.go @@ -37,8 +37,11 @@ func NewServiceHandler[I any, O any](fn ServiceHandlerFn[I, O]) *ServiceHandler func (h *ServiceHandler) Call(ctx Context, bytes []byte) ([]byte, error) { input := reflect.New(h.input) - if err := json.Unmarshal(bytes, input.Interface()); err != nil { - return nil, TerminalError(fmt.Errorf("request doesn't match handler signature: %w", err)) + if len(bytes) > 0 { + // use the zero value if there is no input data at all + if err := json.Unmarshal(bytes, input.Interface()); err != nil { + return nil, TerminalError(fmt.Errorf("request doesn't match handler signature: %w", err)) + } } // we are sure about the fn signature so it's safe to do this @@ -80,8 +83,11 @@ func NewObjectHandler[I any, O any](fn ObjectHandlerFn[I, O]) *ObjectHandler { func (h *ObjectHandler) Call(ctx ObjectContext, bytes []byte) ([]byte, error) { input := reflect.New(h.input) - if err := json.Unmarshal(bytes, input.Interface()); err != nil { - return nil, TerminalError(fmt.Errorf("request doesn't match handler signature: %w", err)) + if len(bytes) > 0 { + // use the zero value if there is no input data at all + if err := json.Unmarshal(bytes, input.Interface()); err != nil { + return nil, TerminalError(fmt.Errorf("request doesn't match handler signature: %w", err)) + } } // we are sure about the fn signature so it's safe to do this From 149b38e005b7d583e5b9094297cab87f65a322b6 Mon Sep 17 00:00:00 2001 From: Jack Kleeman <jackkleeman@gmail.com> Date: Mon, 8 Jul 2024 10:41:54 +0100 Subject: [PATCH 04/13] Add key to logs --- internal/state/call.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/state/call.go b/internal/state/call.go index 03bc670..f3d9bef 100644 --- a/internal/state/call.go +++ b/internal/state/call.go @@ -52,8 +52,6 @@ func (c *serviceCall) Send(body any, delay time.Duration) error { } func (m *Machine) doDynCall(service, key, method string, input, output any) error { - m.log.Debug().Str("service", service).Str("method", method).Msg("in do call") - params, err := json.Marshal(input) if err != nil { return err @@ -73,6 +71,8 @@ func (m *Machine) doDynCall(service, key, method string, input, output any) erro } func (m *Machine) doCall(service, key, method string, params []byte) ([]byte, error) { + m.log.Debug().Str("service", service).Str("method", method).Str("key", key).Msg("executing sync call") + return replayOrNew( m, wire.CallEntryMessageType, @@ -133,6 +133,8 @@ func (m *Machine) _doCall(service, key, method string, params []byte) ([]byte, e } func (c *Machine) sendCall(service, method, key string, body any, delay time.Duration) error { + c.log.Debug().Str("service", service).Str("method", method).Str("key", key).Msg("executing async call") + params, err := json.Marshal(body) if err != nil { return err From 03d8276fc67113da70893f5d329328fa502b0e5a Mon Sep 17 00:00:00 2001 From: Jack Kleeman <jackkleeman@gmail.com> Date: Mon, 8 Jul 2024 10:52:42 +0100 Subject: [PATCH 05/13] Missing key in Send --- internal/state/call.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/internal/state/call.go b/internal/state/call.go index f3d9bef..5f99ecb 100644 --- a/internal/state/call.go +++ b/internal/state/call.go @@ -48,7 +48,7 @@ func (c *serviceCall) Do(input any, output any) error { // Send runs a call in the background after delay duration func (c *serviceCall) Send(body any, delay time.Duration) error { - return c.machine.sendCall(c.service, c.method, c.key, body, delay) + return c.machine.sendCall(c.service, c.key, c.method, body, delay) } func (m *Machine) doDynCall(service, key, method string, input, output any) error { @@ -132,7 +132,7 @@ func (m *Machine) _doCall(service, key, method string, params []byte) ([]byte, e return nil, errUnreachable } -func (c *Machine) sendCall(service, method, key string, body any, delay time.Duration) error { +func (c *Machine) sendCall(service, key, method string, body any, delay time.Duration) error { c.log.Debug().Str("service", service).Str("method", method).Str("key", key).Msg("executing async call") params, err := json.Marshal(body) @@ -154,14 +154,14 @@ func (c *Machine) sendCall(service, method, key string, body any, delay time.Dur return restate.Void{}, nil }, func() (restate.Void, error) { - return restate.Void{}, c._sendCall(service, method, params, delay) + return restate.Void{}, c._sendCall(service, key, method, params, delay) }, ) return err } -func (c *Machine) _sendCall(service, method string, params []byte, delay time.Duration) error { +func (c *Machine) _sendCall(service, key, method string, params []byte, delay time.Duration) error { var invokeTime uint64 if delay != 0 { invokeTime = uint64(time.Now().Add(delay).UnixMilli()) @@ -171,6 +171,7 @@ func (c *Machine) _sendCall(service, method string, params []byte, delay time.Du ServiceName: service, HandlerName: method, Parameter: params, + Key: key, InvokeTime: invokeTime, }) From 988d15c9754346c104383379fd533b2c9453a9bd Mon Sep 17 00:00:00 2001 From: Jack Kleeman <jackkleeman@gmail.com> Date: Mon, 8 Jul 2024 11:10:21 +0100 Subject: [PATCH 06/13] Avoid ominous 'unreachable' errors --- error.go | 5 +++++ internal/state/awakeable.go | 2 +- internal/state/call.go | 4 ++-- internal/state/sys.go | 10 +++++----- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/error.go b/error.go index 7ff33b1..2818ef3 100644 --- a/error.go +++ b/error.go @@ -7,6 +7,11 @@ import ( type Code uint16 +const ( + ErrJournalMismatch Code = 570 + ErrProtocolViolation Code = 571 +) + type codeError struct { code Code inner error diff --git a/internal/state/awakeable.go b/internal/state/awakeable.go index 9af4360..1947cdf 100644 --- a/internal/state/awakeable.go +++ b/internal/state/awakeable.go @@ -68,7 +68,7 @@ func (c *Machine) awakeable() (restate.Awakeable[[]byte], error) { case *protocol.AwakeableEntryMessage_Failure: return completedAwakeable[[]byte]{invocationID: c.id, result: restate.Result[[]byte]{Err: restate.TerminalError(fmt.Errorf(result.Failure.Message), restate.Code(result.Failure.Code))}}, nil default: - panic("unreachable") + return nil, restate.TerminalError(fmt.Errorf("awakeable entry had invalid result: %v", entry.Payload.Result), restate.ErrProtocolViolation) } }, func() (awakeable[[]byte], error) { diff --git a/internal/state/call.go b/internal/state/call.go index 5f99ecb..a548d62 100644 --- a/internal/state/call.go +++ b/internal/state/call.go @@ -91,7 +91,7 @@ func (m *Machine) doCall(service, key, method string, params []byte) ([]byte, er return result.Value, nil } - return nil, errUnreachable + return nil, restate.TerminalError(fmt.Errorf("sync call entry had invalid result: %v", entry.Payload.Result), restate.ErrProtocolViolation) }, func() ([]byte, error) { return m._doCall(service, key, method, params) }) @@ -129,7 +129,7 @@ func (m *Machine) _doCall(service, key, method string, params []byte) ([]byte, e return result.Value, nil } - return nil, errUnreachable + return nil, restate.TerminalError(fmt.Errorf("sync call completion had invalid result: %v", completion.Payload.Result), restate.ErrProtocolViolation) } func (c *Machine) sendCall(service, key, method string, body any, delay time.Duration) error { diff --git a/internal/state/sys.go b/internal/state/sys.go index da03ac3..3dc3c3d 100644 --- a/internal/state/sys.go +++ b/internal/state/sys.go @@ -14,7 +14,6 @@ import ( var ( errEntryMismatch = restate.WithErrorCode(fmt.Errorf("log entry mismatch"), 32) - errUnreachable = fmt.Errorf("unreachable") ) func (m *Machine) set(key string, value []byte) error { @@ -126,7 +125,7 @@ func (m *Machine) get(key string) ([]byte, error) { return result.Value, nil } - return nil, fmt.Errorf("unreachable") + return nil, restate.TerminalError(fmt.Errorf("get state entry had invalid result: %v", entry.Payload.Result), restate.ErrProtocolViolation) }, func() ([]byte, error) { return m._get(key) }) @@ -199,13 +198,14 @@ func (m *Machine) _get(key string) ([]byte, error) { case *protocol.CompletionMessage_Failure: // the get state entry message is not failable so this should // never happen + // TODO terminal? return nil, fmt.Errorf("[%d] %s", value.Failure.Code, value.Failure.Message) case *protocol.CompletionMessage_Value: m.current[key] = value.Value return value.Value, nil } - return nil, fmt.Errorf("unreachable") + return nil, restate.TerminalError(fmt.Errorf("get state completion had invalid result: %v", completion.Payload.Result), restate.ErrProtocolViolation) } func (m *Machine) keys() ([]string, error) { @@ -224,7 +224,7 @@ func (m *Machine) keys() ([]string, error) { return keys, nil } - return nil, errUnreachable + return nil, restate.TerminalError(fmt.Errorf("found get state keys entry with invalid completion: %v", entry.Payload.Result), 571) }, m._keys, ) @@ -332,7 +332,7 @@ func (m *Machine) sideEffect(fn func() ([]byte, error)) ([]byte, error) { return result.Value, nil } - return nil, errUnreachable + return nil, restate.TerminalError(fmt.Errorf("side effect entry had invalid result: %v", entry.Payload.Result), restate.ErrProtocolViolation) }, func() ([]byte, error) { return m._sideEffect(fn) From ba9e68d72a389fa85de3eba3efd81ba142e46646 Mon Sep 17 00:00:00 2001 From: Jack Kleeman <jackkleeman@gmail.com> Date: Mon, 8 Jul 2024 11:35:00 +0100 Subject: [PATCH 07/13] Accept nil side effect results --- internal/state/sys.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/state/sys.go b/internal/state/sys.go index 3dc3c3d..c65c7c6 100644 --- a/internal/state/sys.go +++ b/internal/state/sys.go @@ -330,6 +330,9 @@ func (m *Machine) sideEffect(fn func() ([]byte, error)) ([]byte, error) { return nil, restate.TerminalError(errors.New(result.Failure.Message), restate.Code(result.Failure.Code)) case *protocol.RunEntryMessage_Value: return result.Value, nil + case nil: + // Empty result is valid + return nil, nil } return nil, restate.TerminalError(fmt.Errorf("side effect entry had invalid result: %v", entry.Payload.Result), restate.ErrProtocolViolation) From 75677153c3820ed668b77a5eeaca241675b39a11 Mon Sep 17 00:00:00 2001 From: Jack Kleeman <jackkleeman@gmail.com> Date: Mon, 8 Jul 2024 14:20:45 +0100 Subject: [PATCH 08/13] Log out messages with trace --- internal/state/awakeable.go | 4 ++-- internal/state/state.go | 12 +++++++----- internal/wire/wire.go | 17 +++++++++++------ 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/internal/state/awakeable.go b/internal/state/awakeable.go index 1947cdf..be8f3a9 100644 --- a/internal/state/awakeable.go +++ b/internal/state/awakeable.go @@ -131,7 +131,7 @@ func (c *Machine) rejectAwakeable(id string, reason error) error { wire.CompleteAwakeableEntryMessageType, func(entry *wire.CompleteAwakeableEntryMessage) (restate.Void, error) { messageFailure, ok := entry.Payload.Result.(*protocol.CompleteAwakeableEntryMessage_Failure) - if entry.Payload.Id != id || !ok || messageFailure.Failure.Code != 500 || messageFailure.Failure.Message != reason.Error() { + if entry.Payload.Id != id || !ok || messageFailure.Failure.Code != uint32(restate.ErrorCode(reason)) || messageFailure.Failure.Message != reason.Error() { return restate.Void{}, errEntryMismatch } return restate.Void{}, nil @@ -150,7 +150,7 @@ func (c *Machine) _rejectAwakeable(id string, reason error) error { if err := c.protocol.Write(&protocol.CompleteAwakeableEntryMessage{ Id: id, Result: &protocol.CompleteAwakeableEntryMessage_Failure{Failure: &protocol.Failure{ - Code: 500, + Code: uint32(restate.ErrorCode(reason)), Message: reason.Error(), }}, }); err != nil { diff --git a/internal/state/state.go b/internal/state/state.go index 080c3f6..85313d6 100644 --- a/internal/state/state.go +++ b/internal/state/state.go @@ -143,11 +143,13 @@ type Machine struct { } func NewMachine(handler restate.Handler, conn io.ReadWriter) *Machine { - return &Machine{ - handler: handler, - protocol: wire.NewProtocol(conn), - current: make(map[string][]byte), + m := &Machine{ + handler: handler, + current: make(map[string][]byte), + log: log.Logger, } + m.protocol = wire.NewProtocol(&m.log, conn) + return m } // Start starts the state machine @@ -168,7 +170,7 @@ func (m *Machine) Start(inner context.Context, trace string) error { m.id = start.Payload.Id m.key = start.Payload.Key - m.log = log.With().Str("id", start.Payload.DebugId).Str("method", trace).Logger() + m.log = m.log.With().Str("id", start.Payload.DebugId).Str("method", trace).Logger() ctx := newContext(inner, m) diff --git a/internal/wire/wire.go b/internal/wire/wire.go index 46f2d62..9762383 100644 --- a/internal/wire/wire.go +++ b/internal/wire/wire.go @@ -10,7 +10,7 @@ import ( "math" protocol "github.com/restatedev/sdk-go/generated/proto/protocol" - "github.com/rs/zerolog/log" + "github.com/rs/zerolog" "google.golang.org/protobuf/proto" ) @@ -120,11 +120,12 @@ func (r *Reader) Next() <-chan ReaderMessage { // Note that Protocol is not concurrent safe and it's up to the user // to make sure it's used correctly type Protocol struct { + log *zerolog.Logger stream io.ReadWriter } -func NewProtocol(stream io.ReadWriter) *Protocol { - return &Protocol{stream} +func NewProtocol(log *zerolog.Logger, stream io.ReadWriter) *Protocol { + return &Protocol{log, stream} } // ReadHeader from stream @@ -165,9 +166,13 @@ func (s *Protocol) Read() (Message, error) { return nil, fmt.Errorf("unknown message type '%d'", header.TypeCode) } - log.Trace().Stringer("type", header.TypeCode).Msg("received message") - return builder(header, buf) + msg, err := builder(header, buf) + if err != nil { + return nil, err + } + s.log.Trace().Stringer("type", header.TypeCode).Interface("msg", msg).Msg("received message") + return msg, nil } func (s *Protocol) Write(message proto.Message, flags ...Flag) error { @@ -221,7 +226,7 @@ func (s *Protocol) Write(message proto.Message, flags ...Flag) error { return fmt.Errorf("can not send message of unknown message type") } - log.Trace().Stringer("type", typ).Msg("sending message to runtime") + s.log.Trace().Stringer("type", typ).Interface("msg", message).Msg("sending message to runtime") bytes, err := proto.Marshal(message) if err != nil { From c27b6bb472d3c657f00a7c320155b626188320c3 Mon Sep 17 00:00:00 2001 From: Jack Kleeman <jackkleeman@gmail.com> Date: Mon, 8 Jul 2024 14:24:31 +0100 Subject: [PATCH 09/13] Avoid double sending side effect entries --- internal/state/sys.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/internal/state/sys.go b/internal/state/sys.go index c65c7c6..5625342 100644 --- a/internal/state/sys.go +++ b/internal/state/sys.go @@ -346,7 +346,6 @@ func (m *Machine) sideEffect(fn func() ([]byte, error)) ([]byte, error) { func (m *Machine) _sideEffect(fn func() ([]byte, error)) ([]byte, error) { bytes, err := fn() - var msg protocol.RunEntryMessage if err != nil { if restate.IsTerminalError(err) { msg := protocol.RunEntryMessage{ @@ -382,9 +381,5 @@ func (m *Machine) _sideEffect(fn func() ([]byte, error)) ([]byte, error) { } } - if err := m.protocol.Write(&msg); err != nil { - return nil, err - } - return bytes, err } From b62c0a2124612df216d64c4be8cedb9561c3911d Mon Sep 17 00:00:00 2001 From: Jack Kleeman <jackkleeman@gmail.com> Date: Mon, 8 Jul 2024 14:45:33 +0100 Subject: [PATCH 10/13] Awakeables need pointer receivers --- internal/state/awakeable.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/internal/state/awakeable.go b/internal/state/awakeable.go index be8f3a9..e75c034 100644 --- a/internal/state/awakeable.go +++ b/internal/state/awakeable.go @@ -24,28 +24,28 @@ type completedAwakeable[T any] struct { result restate.Result[T] } -func (c completedAwakeable[T]) Id() string { return awakeableID(c.invocationID, c.entryIndex) } -func (c completedAwakeable[T]) Chan() <-chan restate.Result[T] { +func (c *completedAwakeable[T]) Id() string { return awakeableID(c.invocationID, c.entryIndex) } +func (c *completedAwakeable[T]) Chan() <-chan restate.Result[T] { ch := make(chan restate.Result[T], 1) ch <- c.result return ch } -func (c completedAwakeable[T]) setEntryIndex(entryIndex uint32) { c.entryIndex = entryIndex } +func (c *completedAwakeable[T]) setEntryIndex(entryIndex uint32) { c.entryIndex = entryIndex } type suspendingAwakeable[T any] struct { invocationID []byte entryIndex uint32 } -func (c suspendingAwakeable[T]) Id() string { return awakeableID(c.invocationID, c.entryIndex) } +func (c *suspendingAwakeable[T]) Id() string { return awakeableID(c.invocationID, c.entryIndex) } // this is a temporary hack; always suspend when this channel is read // currently needed because we don't have a way to process the completion while the invocation is in progress // and so can only deal with it on replay -func (c suspendingAwakeable[T]) Chan() <-chan restate.Result[T] { +func (c *suspendingAwakeable[T]) Chan() <-chan restate.Result[T] { panic(&suspend{resumeEntry: c.entryIndex}) } -func (c suspendingAwakeable[T]) setEntryIndex(entryIndex uint32) { c.entryIndex = entryIndex } +func (c *suspendingAwakeable[T]) setEntryIndex(entryIndex uint32) { c.entryIndex = entryIndex } func awakeableID(invocationID []byte, entryIndex uint32) string { bytes := make([]byte, 0, len(invocationID)+4) @@ -60,13 +60,13 @@ func (c *Machine) awakeable() (restate.Awakeable[[]byte], error) { wire.AwakeableEntryMessageType, func(entry *wire.AwakeableEntryMessage) (awakeable[[]byte], error) { if entry.Payload.Result == nil { - return suspendingAwakeable[[]byte]{invocationID: c.id}, nil + return &suspendingAwakeable[[]byte]{invocationID: c.id}, nil } switch result := entry.Payload.Result.(type) { case *protocol.AwakeableEntryMessage_Value: - return completedAwakeable[[]byte]{invocationID: c.id, result: restate.Result[[]byte]{Value: result.Value}}, nil + return &completedAwakeable[[]byte]{invocationID: c.id, result: restate.Result[[]byte]{Value: result.Value}}, nil case *protocol.AwakeableEntryMessage_Failure: - return completedAwakeable[[]byte]{invocationID: c.id, result: restate.Result[[]byte]{Err: restate.TerminalError(fmt.Errorf(result.Failure.Message), restate.Code(result.Failure.Code))}}, nil + return &completedAwakeable[[]byte]{invocationID: c.id, result: restate.Result[[]byte]{Err: restate.TerminalError(fmt.Errorf(result.Failure.Message), restate.Code(result.Failure.Code))}}, nil default: return nil, restate.TerminalError(fmt.Errorf("awakeable entry had invalid result: %v", entry.Payload.Result), restate.ErrProtocolViolation) } @@ -75,7 +75,7 @@ func (c *Machine) awakeable() (restate.Awakeable[[]byte], error) { if err := c._awakeable(); err != nil { return nil, err } - return suspendingAwakeable[[]byte]{invocationID: c.id}, nil + return &suspendingAwakeable[[]byte]{invocationID: c.id}, nil }, ) if err != nil { From 9b72604633a5dff565416ede6d95eb10ebfb2eb3 Mon Sep 17 00:00:00 2001 From: Jack Kleeman <jackkleeman@gmail.com> Date: Mon, 8 Jul 2024 14:48:24 +0100 Subject: [PATCH 11/13] Fix match in protocol write --- internal/wire/wire.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/wire/wire.go b/internal/wire/wire.go index 9762383..5560f60 100644 --- a/internal/wire/wire.go +++ b/internal/wire/wire.go @@ -218,7 +218,7 @@ func (s *Protocol) Write(message proto.Message, flags ...Flag) error { typ = OneWayCallEntryMessageType case *protocol.AwakeableEntryMessage: typ = AwakeableEntryMessageType - case *protocol.CompletePromiseEntryMessage: + case *protocol.CompleteAwakeableEntryMessage: typ = CompleteAwakeableEntryMessageType case *protocol.RunEntryMessage: typ = RunEntryMessageType From 503ed45ca9e07483c1023c0039de7138cb1a126a Mon Sep 17 00:00:00 2001 From: Jack Kleeman <jackkleeman@gmail.com> Date: Mon, 8 Jul 2024 14:52:26 +0100 Subject: [PATCH 12/13] Add prom_1 prefix to awakeable --- internal/state/awakeable.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/state/awakeable.go b/internal/state/awakeable.go index e75c034..ed515ea 100644 --- a/internal/state/awakeable.go +++ b/internal/state/awakeable.go @@ -51,7 +51,7 @@ func awakeableID(invocationID []byte, entryIndex uint32) string { bytes := make([]byte, 0, len(invocationID)+4) bytes = append(bytes, invocationID...) bytes = binary.BigEndian.AppendUint32(bytes, entryIndex) - return base64.URLEncoding.EncodeToString(bytes) + return "prom_1" + base64.URLEncoding.EncodeToString(bytes) } func (c *Machine) awakeable() (restate.Awakeable[[]byte], error) { From 067ccd579fa003c3d796e6c17893987d482ace9e Mon Sep 17 00:00:00 2001 From: Jack Kleeman <jackkleeman@gmail.com> Date: Mon, 8 Jul 2024 15:04:45 +0100 Subject: [PATCH 13/13] Fix errors test --- error_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/error_test.go b/error_test.go index 96e82b0..36e471d 100644 --- a/error_test.go +++ b/error_test.go @@ -2,6 +2,7 @@ package restate import ( "fmt" + "net/http" "testing" "github.com/stretchr/testify/require" @@ -14,10 +15,10 @@ func TestTerminal(t *testing.T) { require.True(t, IsTerminalError(err)) //terminal with code - err = TerminalError(fmt.Errorf("terminal with code"), INTERNAL) + err = TerminalError(fmt.Errorf("terminal with code"), 500) require.True(t, IsTerminalError(err)) - require.EqualValues(t, INTERNAL, ErrorCode(err)) + require.EqualValues(t, 500, ErrorCode(err)) } func TestCode(t *testing.T) { @@ -28,7 +29,7 @@ func TestCode(t *testing.T) { require.EqualValues(t, 16, code) - require.EqualValues(t, 2, ErrorCode(fmt.Errorf("unknown error"))) + require.EqualValues(t, http.StatusInternalServerError, ErrorCode(fmt.Errorf("unknown error"))) } func TestCombine(t *testing.T) {