diff --git a/apps/engineering/content/docs/architecture/workflows/creating-services.mdx b/apps/engineering/content/docs/architecture/workflows/creating-services.mdx index 3f360307f6..fe37b0130d 100644 --- a/apps/engineering/content/docs/architecture/workflows/creating-services.mdx +++ b/apps/engineering/content/docs/architecture/workflows/creating-services.mdx @@ -130,31 +130,57 @@ func Run(ctx context.Context, cfg Config) error { ### 5. Call the Service -These are ugly, they're working on generating proper clients from the proto definitions -https://github.com/restatedev/sdk-go/issues/103 +The Restate SDK now generates typed ingress clients from proto definitions. Use these for type-safe, clean service calls. -**Blocking call:** +**Setup - Create a helper method in your service:** ```go -response, err := restateingress.Object[*hydrav1.YourRequest, *hydrav1.YourResponse]( - restateClient, - "hydra.v1.YourService", - keyValue, - "YourOperation", -).Request(ctx, request) +// In your service struct (e.g., apps/ctrl/services/deployment/service.go) +type Service struct { + restate *restateingress.Client + // ... other fields +} + +// Helper method to get typed client +func (s *Service) yourServiceClient(key string) hydrav1.YourServiceIngressClient { + return hydrav1.NewYourServiceIngressClient(s.restate, key) +} +``` + +**Blocking call (Request):** + +```go +response, err := s.yourServiceClient(keyValue). + YourOperation(). + Request(ctx, &hydrav1.YourRequest{ + KeyField: keyValue, + }) +if err != nil { + return nil, fmt.Errorf("operation failed: %w", err) +} ``` -**Fire-and-forget:** +**Fire-and-forget (Send):** ```go -invocation := restateingress.WorkflowSend[*hydrav1.YourRequest]( - restateClient, - "hydra.v1.YourService", - keyValue, - "YourOperation", -).Send(ctx, request) +invocation, err := s.yourServiceClient(keyValue). + YourOperation(). + Send(ctx, &hydrav1.YourRequest{ + KeyField: keyValue, + }) +if err != nil { + return fmt.Errorf("failed to start: %w", err) +} +// Use invocation.Id for tracking ``` +**Benefits:** + +- Type-safe: Compile-time checking of requests/responses +- Discoverable: IDE autocomplete for all operations +- Cleaner: No manual service name strings or type parameters +- Maintainable: Refactors automatically when proto changes + ## Best Practices 1. **Small Steps**: Break operations into focused, single-purpose durable steps diff --git a/go/apps/ctrl/services/deployment/create_deployment.go b/go/apps/ctrl/services/deployment/create_deployment.go index 1057b31b23..f6b04dc4f4 100644 --- a/go/apps/ctrl/services/deployment/create_deployment.go +++ b/go/apps/ctrl/services/deployment/create_deployment.go @@ -9,7 +9,6 @@ import ( "time" "connectrpc.com/connect" - restateingress "github.com/restatedev/sdk-go/ingress" ctrlv1 "github.com/unkeyed/unkey/go/gen/proto/ctrl/v1" hydrav1 "github.com/unkeyed/unkey/go/gen/proto/hydra/v1" "github.com/unkeyed/unkey/go/pkg/db" @@ -134,23 +133,21 @@ func (s *Service) CreateDeployment( if keyspaceID != "" { keyAuthID = &keyspaceID } - deployReq := &hydrav1.DeployRequest{ - DeploymentId: deploymentID, - DockerImage: req.Msg.GetDockerImage(), - KeyAuthId: keyAuthID, - } - // this is ugly, but we're waiting for - // https://github.com/restatedev/sdk-go/issues/103 - invocation := restateingress.WorkflowSend[*hydrav1.DeployRequest]( - s.restate, - "hydra.v1.DeploymentService", - project.ID, - "Deploy", - ).Send(ctx, deployReq) - if invocation.Error != nil { - s.logger.Error("failed to start deployment workflow", "error", invocation.Error.Error()) - return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("unable to start workflow: %w", invocation.Error)) + + // Send deployment request asynchronously (fire-and-forget) + invocation, err := s.deploymentClient(project.ID). + Deploy(). + Send(ctx, &hydrav1.DeployRequest{ + DeploymentId: deploymentID, + DockerImage: req.Msg.GetDockerImage(), + KeyAuthId: keyAuthID, + }) + + if err != nil { + s.logger.Error("failed to start deployment workflow", "error", err) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("unable to start workflow: %w", err)) } + s.logger.Info("deployment workflow started", "deployment_id", deploymentID, "invocation_id", invocation.Id, diff --git a/go/apps/ctrl/services/deployment/promote.go b/go/apps/ctrl/services/deployment/promote.go index b96de8a8d2..9d08ebcf55 100644 --- a/go/apps/ctrl/services/deployment/promote.go +++ b/go/apps/ctrl/services/deployment/promote.go @@ -5,7 +5,6 @@ import ( "fmt" "connectrpc.com/connect" - restateingress "github.com/restatedev/sdk-go/ingress" ctrlv1 "github.com/unkeyed/unkey/go/gen/proto/ctrl/v1" hydrav1 "github.com/unkeyed/unkey/go/gen/proto/hydra/v1" "github.com/unkeyed/unkey/go/pkg/db" @@ -32,14 +31,11 @@ func (s *Service) Promote(ctx context.Context, req *connect.Request[ctrlv1.Promo // Call the Restate workflow using project ID as the key // This ensures only one operation per project can run at a time - _, err = restateingress.Object[*hydrav1.PromoteRequest, *hydrav1.PromoteResponse]( - s.restate, - "hydra.v1.DeploymentService", - targetDeployment.ProjectID, - "Promote", - ).Request(ctx, &hydrav1.PromoteRequest{ - TargetDeploymentId: req.Msg.GetTargetDeploymentId(), - }) + _, err = s.deploymentClient(targetDeployment.ProjectID). + Promote(). + Request(ctx, &hydrav1.PromoteRequest{ + TargetDeploymentId: req.Msg.GetTargetDeploymentId(), + }) if err != nil { s.logger.Error("promotion workflow failed", diff --git a/go/apps/ctrl/services/deployment/rollback.go b/go/apps/ctrl/services/deployment/rollback.go index 04e9cd6ad6..4bc82566e0 100644 --- a/go/apps/ctrl/services/deployment/rollback.go +++ b/go/apps/ctrl/services/deployment/rollback.go @@ -5,7 +5,6 @@ import ( "fmt" "connectrpc.com/connect" - restateingress "github.com/restatedev/sdk-go/ingress" ctrlv1 "github.com/unkeyed/unkey/go/gen/proto/ctrl/v1" hydrav1 "github.com/unkeyed/unkey/go/gen/proto/hydra/v1" "github.com/unkeyed/unkey/go/pkg/db" @@ -34,16 +33,12 @@ func (s *Service) Rollback(ctx context.Context, req *connect.Request[ctrlv1.Roll // Call the Restate workflow using project ID as the key // This ensures only one rollback per project can run at a time - // Using Object for blocking/synchronous invocation - _, err = restateingress.Object[*hydrav1.RollbackRequest, *hydrav1.RollbackResponse]( - s.restate, - "hydra.v1.DeploymentService", - sourceDeployment.ProjectID, - "Rollback", - ).Request(ctx, &hydrav1.RollbackRequest{ - SourceDeploymentId: req.Msg.GetSourceDeploymentId(), - TargetDeploymentId: req.Msg.GetTargetDeploymentId(), - }) + _, err = s.deploymentClient(sourceDeployment.ProjectID). + Rollback(). + Request(ctx, &hydrav1.RollbackRequest{ + SourceDeploymentId: req.Msg.GetSourceDeploymentId(), + TargetDeploymentId: req.Msg.GetTargetDeploymentId(), + }) if err != nil { s.logger.Error("rollback workflow failed", diff --git a/go/apps/ctrl/services/deployment/service.go b/go/apps/ctrl/services/deployment/service.go index c207c8b1e9..941ee421b4 100644 --- a/go/apps/ctrl/services/deployment/service.go +++ b/go/apps/ctrl/services/deployment/service.go @@ -3,6 +3,7 @@ package deployment import ( restateingress "github.com/restatedev/sdk-go/ingress" "github.com/unkeyed/unkey/go/gen/proto/ctrl/v1/ctrlv1connect" + hydrav1 "github.com/unkeyed/unkey/go/gen/proto/hydra/v1" "github.com/unkeyed/unkey/go/pkg/db" "github.com/unkeyed/unkey/go/pkg/otel/logging" ) @@ -17,6 +18,12 @@ type Service struct { logger logging.Logger } +// deploymentClient creates a typed Restate ingress client for the DeploymentService +// keyed by the given project ID to ensure only one operation per project runs at a time. +func (s *Service) deploymentClient(projectID string) hydrav1.DeploymentServiceIngressClient { + return hydrav1.NewDeploymentServiceIngressClient(s.restate, projectID) +} + type Config struct { Database db.Database PartitionDB db.Database diff --git a/go/gen/proto/hydra/v1/certificate_restate.pb.go b/go/gen/proto/hydra/v1/certificate_restate.pb.go index b17513c944..50586574c7 100644 --- a/go/gen/proto/hydra/v1/certificate_restate.pb.go +++ b/go/gen/proto/hydra/v1/certificate_restate.pb.go @@ -9,6 +9,8 @@ package hydrav1 import ( fmt "fmt" sdk_go "github.com/restatedev/sdk-go" + encoding "github.com/restatedev/sdk-go/encoding" + ingress "github.com/restatedev/sdk-go/ingress" ) // CertificateServiceClient is the client API for hydra.v1.CertificateService service. @@ -42,6 +44,34 @@ func (c *certificateServiceClient) ProcessChallenge(opts ...sdk_go.ClientOption) return sdk_go.WithRequestType[*ProcessChallengeRequest](sdk_go.Object[*ProcessChallengeResponse](c.ctx, "hydra.v1.CertificateService", c.key, "ProcessChallenge", cOpts...)) } +// CertificateServiceIngressClient is the ingress client API for hydra.v1.CertificateService service. +// +// This client is used to call the service from outside of a Restate context. +type CertificateServiceIngressClient interface { + // ProcessChallenge handles the complete ACME certificate challenge flow + // Key: domain name (ensures only one challenge per domain at a time) + ProcessChallenge() ingress.Requester[*ProcessChallengeRequest, *ProcessChallengeResponse] +} + +type certificateServiceIngressClient struct { + client *ingress.Client + serviceName string + key string +} + +func NewCertificateServiceIngressClient(client *ingress.Client, key string) CertificateServiceIngressClient { + return &certificateServiceIngressClient{ + client, + "hydra.v1.CertificateService", + key, + } +} + +func (c *certificateServiceIngressClient) ProcessChallenge() ingress.Requester[*ProcessChallengeRequest, *ProcessChallengeResponse] { + codec := encoding.ProtoJSONCodec + return ingress.NewRequester[*ProcessChallengeRequest, *ProcessChallengeResponse](c.client, c.serviceName, "ProcessChallenge", &c.key, &codec) +} + // CertificateServiceServer is the server API for hydra.v1.CertificateService service. // All implementations should embed UnimplementedCertificateServiceServer // for forward compatibility. diff --git a/go/gen/proto/hydra/v1/deployment_restate.pb.go b/go/gen/proto/hydra/v1/deployment_restate.pb.go index 537aa70737..83483b6609 100644 --- a/go/gen/proto/hydra/v1/deployment_restate.pb.go +++ b/go/gen/proto/hydra/v1/deployment_restate.pb.go @@ -9,6 +9,8 @@ package hydrav1 import ( fmt "fmt" sdk_go "github.com/restatedev/sdk-go" + encoding "github.com/restatedev/sdk-go/encoding" + ingress "github.com/restatedev/sdk-go/ingress" ) // DeploymentServiceClient is the client API for hydra.v1.DeploymentService service. @@ -56,6 +58,44 @@ func (c *deploymentServiceClient) Promote(opts ...sdk_go.ClientOption) sdk_go.Cl return sdk_go.WithRequestType[*PromoteRequest](sdk_go.Object[*PromoteResponse](c.ctx, "hydra.v1.DeploymentService", c.key, "Promote", cOpts...)) } +// DeploymentServiceIngressClient is the ingress client API for hydra.v1.DeploymentService service. +// +// This client is used to call the service from outside of a Restate context. +type DeploymentServiceIngressClient interface { + Deploy() ingress.Requester[*DeployRequest, *DeployResponse] + Rollback() ingress.Requester[*RollbackRequest, *RollbackResponse] + Promote() ingress.Requester[*PromoteRequest, *PromoteResponse] +} + +type deploymentServiceIngressClient struct { + client *ingress.Client + serviceName string + key string +} + +func NewDeploymentServiceIngressClient(client *ingress.Client, key string) DeploymentServiceIngressClient { + return &deploymentServiceIngressClient{ + client, + "hydra.v1.DeploymentService", + key, + } +} + +func (c *deploymentServiceIngressClient) Deploy() ingress.Requester[*DeployRequest, *DeployResponse] { + codec := encoding.ProtoJSONCodec + return ingress.NewRequester[*DeployRequest, *DeployResponse](c.client, c.serviceName, "Deploy", &c.key, &codec) +} + +func (c *deploymentServiceIngressClient) Rollback() ingress.Requester[*RollbackRequest, *RollbackResponse] { + codec := encoding.ProtoJSONCodec + return ingress.NewRequester[*RollbackRequest, *RollbackResponse](c.client, c.serviceName, "Rollback", &c.key, &codec) +} + +func (c *deploymentServiceIngressClient) Promote() ingress.Requester[*PromoteRequest, *PromoteResponse] { + codec := encoding.ProtoJSONCodec + return ingress.NewRequester[*PromoteRequest, *PromoteResponse](c.client, c.serviceName, "Promote", &c.key, &codec) +} + // DeploymentServiceServer is the server API for hydra.v1.DeploymentService service. // All implementations should embed UnimplementedDeploymentServiceServer // for forward compatibility. diff --git a/go/gen/proto/hydra/v1/routing_restate.pb.go b/go/gen/proto/hydra/v1/routing_restate.pb.go index 1e24248b9d..7746ae0c59 100644 --- a/go/gen/proto/hydra/v1/routing_restate.pb.go +++ b/go/gen/proto/hydra/v1/routing_restate.pb.go @@ -9,6 +9,8 @@ package hydrav1 import ( fmt "fmt" sdk_go "github.com/restatedev/sdk-go" + encoding "github.com/restatedev/sdk-go/encoding" + ingress "github.com/restatedev/sdk-go/ingress" ) // RoutingServiceClient is the client API for hydra.v1.RoutingService service. @@ -51,6 +53,42 @@ func (c *routingServiceClient) SwitchDomains(opts ...sdk_go.ClientOption) sdk_go return sdk_go.WithRequestType[*SwitchDomainsRequest](sdk_go.Object[*SwitchDomainsResponse](c.ctx, "hydra.v1.RoutingService", c.key, "SwitchDomains", cOpts...)) } +// RoutingServiceIngressClient is the ingress client API for hydra.v1.RoutingService service. +// +// This client is used to call the service from outside of a Restate context. +type RoutingServiceIngressClient interface { + // AssignDomains creates or reassigns domains to a deployment and creates gateway configs + // Used during initial deployment + AssignDomains() ingress.Requester[*AssignDomainsRequest, *AssignDomainsResponse] + // SwitchDomains reassigns existing domains to a different deployment and updates gateway configs + // Used during rollback/promote operations + SwitchDomains() ingress.Requester[*SwitchDomainsRequest, *SwitchDomainsResponse] +} + +type routingServiceIngressClient struct { + client *ingress.Client + serviceName string + key string +} + +func NewRoutingServiceIngressClient(client *ingress.Client, key string) RoutingServiceIngressClient { + return &routingServiceIngressClient{ + client, + "hydra.v1.RoutingService", + key, + } +} + +func (c *routingServiceIngressClient) AssignDomains() ingress.Requester[*AssignDomainsRequest, *AssignDomainsResponse] { + codec := encoding.ProtoJSONCodec + return ingress.NewRequester[*AssignDomainsRequest, *AssignDomainsResponse](c.client, c.serviceName, "AssignDomains", &c.key, &codec) +} + +func (c *routingServiceIngressClient) SwitchDomains() ingress.Requester[*SwitchDomainsRequest, *SwitchDomainsResponse] { + codec := encoding.ProtoJSONCodec + return ingress.NewRequester[*SwitchDomainsRequest, *SwitchDomainsResponse](c.client, c.serviceName, "SwitchDomains", &c.key, &codec) +} + // RoutingServiceServer is the server API for hydra.v1.RoutingService service. // All implementations should embed UnimplementedRoutingServiceServer // for forward compatibility. diff --git a/go/go.mod b/go/go.mod index 3e9f3f9f56..27e2cbe02b 100644 --- a/go/go.mod +++ b/go/go.mod @@ -30,6 +30,7 @@ require ( github.com/pressly/goose/v3 v3.25.0 github.com/prometheus/client_golang v1.23.2 github.com/redis/go-redis/v9 v9.9.0 + github.com/restatedev/sdk-go v0.21.0 github.com/shirou/gopsutil/v4 v4.25.7 github.com/spiffe/go-spiffe/v2 v2.6.0 github.com/sqlc-dev/plugin-sdk-go v1.23.0 @@ -50,7 +51,7 @@ require ( go.opentelemetry.io/otel/trace v1.38.0 golang.org/x/net v0.43.0 golang.org/x/text v0.29.0 - google.golang.org/protobuf v1.36.8 + google.golang.org/protobuf v1.36.10 k8s.io/api v0.34.1 k8s.io/apimachinery v0.34.1 k8s.io/client-go v0.34.1 @@ -262,7 +263,7 @@ require ( github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/macabu/inamedparam v0.2.0 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/manuelarte/embeddedstructfieldcheck v0.3.0 // indirect github.com/manuelarte/funcorder v0.5.0 // indirect github.com/maratori/testableexamples v1.0.0 // indirect @@ -322,7 +323,6 @@ require ( github.com/quic-go/quic-go v0.54.0 // indirect github.com/raeperd/recvcheck v0.2.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect - github.com/restatedev/sdk-go v0.20.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/riza-io/grpc-go v0.2.0 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect diff --git a/go/go.sum b/go/go.sum index 1b048f1c6b..755beec890 100644 --- a/go/go.sum +++ b/go/go.sum @@ -404,8 +404,6 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= -github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-jwt/jwt/v5 v5.2.3 h1:kkGXqQOBSDDWRhWNXTFpqGSCMyh/PLnqUvMGJPDJDs0= github.com/golang-jwt/jwt/v5 v5.2.3/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= @@ -596,8 +594,8 @@ github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2 github.com/macabu/inamedparam v0.2.0 h1:VyPYpOc10nkhI2qeNUdh3Zket4fcZjEWe35poddBCpE= github.com/macabu/inamedparam v0.2.0/go.mod h1:+Pee9/YfGe5LJ62pYXqB89lJ+0k5bsR8Wgz/C0Zlq3U= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/manuelarte/embeddedstructfieldcheck v0.3.0 h1:VhGqK8gANDvFYDxQkjPbv7/gDJtsGU9k6qj/hC2hgso= github.com/manuelarte/embeddedstructfieldcheck v0.3.0/go.mod h1:LSo/IQpPfx1dXMcX4ibZCYA7Yy6ayZHIaOGM70+1Wy8= github.com/manuelarte/funcorder v0.5.0 h1:llMuHXXbg7tD0i/LNw8vGnkDTHFpTnWqKPI85Rknc+8= @@ -665,6 +663,8 @@ github.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhK github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs= github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= +github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1 h1:dOYG7LS/WK00RWZc8XGgcUTlTxpp3mKhdR2Q9z9HbXM= +github.com/nsf/jsondiff v0.0.0-20230430225905-43f6cf3098c1/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8= github.com/nunnatsa/ginkgolinter v0.20.0 h1:OmWLkAFO2HUTYcU6mprnKud1Ey5pVdiVNYGO5HVicx8= github.com/nunnatsa/ginkgolinter v0.20.0/go.mod h1:dCIuFlTPfQerXgGUju3VygfAFPdC5aE1mdacCDKDJcQ= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -781,8 +781,12 @@ github.com/rekby/fixenv v0.6.1 h1:jUFiSPpajT4WY2cYuc++7Y1zWrnCxnovGCIX72PZniM= github.com/rekby/fixenv v0.6.1/go.mod h1:/b5LRc06BYJtslRtHKxsPWFT/ySpHV+rWvzTg+XWk4c= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/restatedev/sdk-go v0.20.0 h1:BjV1CqKoJwvVKxR5Z4e1Ofx2H+k9oeD0AbRGkS0ihZs= -github.com/restatedev/sdk-go v0.20.0/go.mod h1:T3G/P3VBSRTvdverfEiCVVcsNSymzO5ebIyUU6uRqk8= +github.com/restatedev/sdk-go v0.20.3-0.20251014123254-dc9a560d76aa h1:BS+6PlURIQi5mdgbTLIcFc2chpwENwDrPN8YDUslatg= +github.com/restatedev/sdk-go v0.20.3-0.20251014123254-dc9a560d76aa/go.mod h1:T3G/P3VBSRTvdverfEiCVVcsNSymzO5ebIyUU6uRqk8= +github.com/restatedev/sdk-go v0.20.3-0.20251017160129-f65ac3c2e327 h1:/zD5uNZ6g6VcyouS4pWEgc7TwlpvkE94Z3IyZCF3SOw= +github.com/restatedev/sdk-go v0.20.3-0.20251017160129-f65ac3c2e327/go.mod h1:T3G/P3VBSRTvdverfEiCVVcsNSymzO5ebIyUU6uRqk8= +github.com/restatedev/sdk-go v0.21.0 h1:A0Ss0o8ZvUReGmiGJYe9dB8lIXWu/tytsKDt/UIGXAA= +github.com/restatedev/sdk-go v0.21.0/go.mod h1:T3G/P3VBSRTvdverfEiCVVcsNSymzO5ebIyUU6uRqk8= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -1262,8 +1266,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=