diff --git a/.vscode/tasks.json b/.vscode/tasks.json index f11ae9d6be..f6f10339ed 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -11,10 +11,7 @@ "problemMatcher": [ "$go" ], - "group": { - "kind": "build", - "isDefault": true - }, + "group": "build", "detail": "cd ${workspaceFolder}; go test ./..." }, { @@ -33,6 +30,22 @@ "isDefault": true }, "detail": "cd ${workspaceFolder}; golangci-lint run" + }, + { + "type": "go", + "label": "go: build workspace", + "command": "build", + "args": [ + "./..." + ], + "problemMatcher": [ + "$go" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "cd /Users/alec/dev/ftl; go build ./..." } ] } \ No newline at end of file diff --git a/CODEOWNERS b/CODEOWNERS index 6c0834263e..482188c40f 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1 @@ -* @alecthomas @dhanji \ No newline at end of file +* @alecthomas @dhanji @wesbillman diff --git a/Makefile b/Makefile index c383854c5b..91ceb77b09 100644 --- a/Makefile +++ b/Makefile @@ -7,18 +7,20 @@ SCHEMA_IN = schema/schema.go schema/protobuf.go SCHEMA_OUT = protos/xyz/block/ftl/v1/schema/schema.proto SQLC_IN = sqlc.yaml \ - backplane/internal/sql/schema/*.sql \ - backplane/internal/sql/queries.sql + backplane/internal/sql/schema/*.sql \ + backplane/internal/sql/queries.sql SQLC_OUT = backplane/internal/sql/db.go \ - $(shell grep -q copyfrom backplane/internal/sql/queries.sql && echo backplane/internal/sql/copyfrom.go) \ - backplane/internal/sql/models.go \ - backplane/internal/sql/queries.sql.go - -PROTO_IN = protos/xyz/block/ftl/v1/ftl.proto \ - protos/xyz/block/ftl/v1/schema/schema.proto -PROTO_OUT = protos/xyz/block/ftl/v1/ftl_grpc.pb.go \ - protos/xyz/block/ftl/v1/schema/schema.pb.go \ - protos/xyz/block/ftl/v1/ftl.pb.go + $(shell grep -q copyfrom backplane/internal/sql/queries.sql && echo backplane/internal/sql/copyfrom.go) \ + backplane/internal/sql/models.go \ + backplane/internal/sql/queries.sql.go + +PROTO_IN = protos/buf.yaml \ + protos/buf.gen.yaml \ + protos/xyz/block/ftl/v1/ftl.proto \ + protos/xyz/block/ftl/v1/schema/schema.proto +PROTO_OUT = protos/xyz/block/ftl/v1/ftlv1connect/ftl.connect.go \ + protos/xyz/block/ftl/v1/schema/schema.pb.go \ + protos/xyz/block/ftl/v1/ftl.pb.go .DEFAULT_GOAL := help diff --git a/agent/agent.go b/agent/agent.go index a31a52a990..4f172f046f 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -3,9 +3,7 @@ package agent import ( "context" - "encoding/json" - "fmt" - "io/ioutil" + "io" "net" "net/http" "os" @@ -19,25 +17,25 @@ import ( "github.com/alecthomas/atomic" "github.com/alecthomas/errors" "github.com/alecthomas/types" + "github.com/bufbuild/connect-go" + grpcreflect "github.com/bufbuild/connect-grpcreflect-go" "golang.org/x/exp/maps" "golang.org/x/exp/slices" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" "golang.org/x/sync/errgroup" - "google.golang.org/grpc/reflection" - "google.golang.org/protobuf/proto" "github.com/TBD54566975/ftl/common/exec" "github.com/TBD54566975/ftl/common/log" - "github.com/TBD54566975/ftl/common/metadata" "github.com/TBD54566975/ftl/common/plugin" "github.com/TBD54566975/ftl/common/pubsub" + "github.com/TBD54566975/ftl/common/rpc" "github.com/TBD54566975/ftl/common/socket" "github.com/TBD54566975/ftl/console" ftlv1 "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1" + "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1/ftlv1connect" pschema "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1/schema" "github.com/TBD54566975/ftl/schema" - sdkgo "github.com/TBD54566975/ftl/sdk-go" ) // ModuleConfig is the configuration for an FTL module. @@ -49,8 +47,8 @@ type ModuleConfig struct { } type driveContext struct { - *plugin.Plugin[ftlv1.VerbServiceClient] - develService ftlv1.DevelServiceClient + *plugin.Plugin[ftlv1connect.VerbServiceClient] + develService ftlv1connect.DevelServiceClient schema atomic.Value[types.Option[*schema.Module]] root string workingDir string @@ -67,9 +65,8 @@ type Agent struct { listen socket.Socket } -var _ http.Handler = (*Agent)(nil) -var _ ftlv1.VerbServiceServer = (*Agent)(nil) -var _ ftlv1.DevelServiceServer = (*Agent)(nil) +var _ ftlv1connect.VerbServiceHandler = (*Agent)(nil) +var _ ftlv1connect.DevelServiceHandler = (*Agent)(nil) // New creates a new local agent. func New(ctx context.Context, listen socket.Socket) (*Agent, error) { @@ -83,27 +80,27 @@ func New(ctx context.Context, listen socket.Socket) (*Agent, error) { } // Serve starts the agent server. -func (l *Agent) Serve(ctx context.Context) error { - srv := socket.NewGRPCServer(ctx) - // Start agent gRPC and REST servers. - reflection.Register(srv) - ftlv1.RegisterVerbServiceServer(srv, l) - ftlv1.RegisterDevelServiceServer(srv, l) +func (a *Agent) Serve(ctx context.Context) error { + mux := http.NewServeMux() + mux.Handle(ftlv1connect.NewDevelServiceHandler(a, rpc.DefaultHandlerOptions()...)) + mux.Handle(ftlv1connect.NewVerbServiceHandler(a, rpc.DefaultHandlerOptions()...)) + reflector := grpcreflect.NewStaticReflector(ftlv1connect.DevelServiceName, ftlv1connect.VerbServiceName) + mux.Handle(grpcreflect.NewHandlerV1(reflector)) + mux.Handle(grpcreflect.NewHandlerV1Alpha(reflector)) c, err := console.Server(ctx) if err != nil { return errors.WithStack(err) } + mux.Handle("/", c) - mixedHandler := newHTTPandGRPCMux(c, srv) - http2Server := &http2.Server{} http1Server := &http.Server{ - Handler: h2c.NewHandler(mixedHandler, http2Server), + Handler: h2c.NewHandler(rpc.Middleware(ctx, mux), &http2.Server{}), ReadHeaderTimeout: time.Second * 30, BaseContext: func(net.Listener) context.Context { return ctx }, } - listener, err := socket.Listen(l.listen) + listener, err := socket.Listen(a.listen) if err != nil { return errors.WithStack(err) } @@ -112,10 +109,10 @@ func (l *Agent) Serve(ctx context.Context) error { } // Drives returns the list of active drives. -func (l *Agent) Drives() []string { - l.lock.RLock() - defer l.lock.Unlock() - return maps.Keys(l.drives) +func (a *Agent) Drives() []string { + a.lock.RLock() + defer a.lock.Unlock() + return maps.Keys(a.drives) } // Manage starts a new Drive to manage a directory of functions. @@ -126,7 +123,7 @@ func (l *Agent) Drives() []string { // FTL_MODULE_ROOT - Path to a directory containing FTL module source and an ftl.toml file. // FTL_WORKING_DIR - Path to a directory that the Drive can use for temporary files. // FTL_MODULE - The name of the module. -func (l *Agent) Manage(ctx context.Context, dir string) (err error) { +func (a *Agent) Manage(ctx context.Context, dir string) (err error) { dir, err = filepath.Abs(dir) if err != nil { return errors.WithStack(err) @@ -154,18 +151,26 @@ func (l *Agent) Manage(ctx context.Context, dir string) (err error) { return errors.WithStack(err) } - var develClient ftlv1.DevelServiceClient - verbServicePlugin, cmdCtx, err := plugin.Spawn(ctx, config.Module, dir, exe, ftlv1.NewVerbServiceClient, - plugin.WithEnvars("FTL_MODULE_ROOT="+dir), - plugin.WithEnvars("FTL_MODULE="+config.Module), - // Used by sub-processes to call back into FTL. - plugin.WithEnvars("FTL_ENDPOINT="+l.listen.String()), - plugin.WithExtraClient(&develClient, ftlv1.NewDevelServiceClient), + var develClient ftlv1connect.DevelServiceClient + verbServicePlugin, cmdCtx, err := plugin.Spawn(ctx, config.Module, dir, exe, ftlv1connect.NewVerbServiceClient, + plugin.WithEnvars( + "FTL_MODULE_ROOT="+dir, + "FTL_MODULE="+config.Module, + // Used by sub-processes to call back into FTL. + "FTL_ENDPOINT="+a.listen.String(), + ), + plugin.WithExtraClient(&develClient, ftlv1connect.NewDevelServiceClient), ) if err != nil { return errors.WithStack(err) } - l.wg.Go(func() error { + + _, err = develClient.Ping(ctx, connect.NewRequest(&ftlv1.PingRequest{})) + if err != nil { + return errors.WithStack(err) + } + + a.wg.Go(func() error { <-cmdCtx.Done() return errors.WithStack(cmdCtx.Err()) }) @@ -177,8 +182,8 @@ func (l *Agent) Manage(ctx context.Context, dir string) (err error) { } }() - l.lock.Lock() - defer l.lock.Unlock() + a.lock.Lock() + defer a.lock.Unlock() dctx := &driveContext{ Plugin: verbServicePlugin, @@ -187,144 +192,97 @@ func (l *Agent) Manage(ctx context.Context, dir string) (err error) { workingDir: workingDir, config: config, } - l.wg.Go(func() error { return l.syncSchemaFromDrive(cmdCtx, dctx) }) - l.drives[dir] = dctx + a.wg.Go(func() error { return a.syncSchemaFromDrive(cmdCtx, dctx) }) + a.wg.Go(func() error { return a.syncSchemaToDrive(cmdCtx, dctx) }) + a.drives[dir] = dctx return nil } -func (l *Agent) Wait() error { - return errors.WithStack(l.wg.Wait()) +func (a *Agent) Wait() error { + return errors.WithStack(a.wg.Wait()) } -type Error struct { - Error string `json:"error"` -} - -func writeError(w http.ResponseWriter, status int, msg string, args ...any) { - w.WriteHeader(status) - _ = json.NewEncoder(w).Encode(struct { - Error string `json:"error"` - }{fmt.Sprintf(msg, args...)}) -} +func (a *Agent) PullSchema(ctx context.Context, req *connect.Request[ftlv1.PullSchemaRequest], stream *connect.ServerStream[ftlv1.PullSchemaResponse]) error { + drives := a.allDrives() -// ServeHTTP because we want the local agent to also be able to serve Verbs directly via HTTP. -func (l *Agent) ServeHTTP(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - cleanedPath := strings.TrimPrefix(r.URL.Path, "/") + slices.SortStableFunc(drives, func(a, b *driveContext) bool { + return a.config.Module < b.config.Module + }) - // Root of server lists all the verbs. - if cleanedPath == "" { - resp, err := l.List(r.Context(), &ftlv1.ListRequest{}) + for i, drive := range drives { + module, ok := drive.schema.Load().Get() + if !ok { + continue + } + err := stream.Send(&ftlv1.PullSchemaResponse{ //nolint:forcetypeassert + Schema: module.ToProto().(*pschema.Module), + More: i < len(drives)-1, + }) if err != nil { - writeError(w, http.StatusBadGateway, "failed to list Verbs: %s", err) - return + return errors.WithStack(err) } - _ = json.NewEncoder(w).Encode(resp) - return } - verb, err := sdkgo.ParseVerbRef(cleanedPath) - if err != nil { - writeError(w, http.StatusBadRequest, "%s", err.Error()) - return - } - - req, err := ioutil.ReadAll(r.Body) - if err != nil { - writeError(w, http.StatusInternalServerError, "failed to read request: %s", err) - return - } - - if len(req) == 0 { - req = []byte("{}") - } - - resp, err := l.Call(r.Context(), &ftlv1.CallRequest{Verb: verb.ToProto(), Body: req}) - if err != nil { - writeError(w, http.StatusBadGateway, "failed to call Verb %q: %s", verb, err) - return - } - switch resp := resp.Response.(type) { - case *ftlv1.CallResponse_Error_: - writeError(w, http.StatusInternalServerError, "verb failed: %s", resp.Error.Message) + return nil +} - case *ftlv1.CallResponse_Body: - _, _ = w.Write(resp.Body) - } +func (a *Agent) PushSchema(ctx context.Context, req *connect.ClientStream[ftlv1.PushSchemaRequest]) (*connect.Response[ftlv1.PushSchemaResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("FTL agent does not support PushSchema")) } -func (l *Agent) Call(ctx context.Context, req *ftlv1.CallRequest) (*ftlv1.CallResponse, error) { +func (a *Agent) Call(ctx context.Context, req *connect.Request[ftlv1.CallRequest]) (*connect.Response[ftlv1.CallResponse], error) { logger := log.FromContext(ctx) - logger.Infof("Calling %s", req.Verb) - ctx = metadata.WithDirectRouting(ctx) - drive, err := l.findDrive(req.Verb.ToFTL()) + logger.Infof("Calling %s", req.Msg.Verb) + ctx = rpc.WithDirectRouting(ctx) + drive, err := a.findDrive(req.Msg.Verb.ToFTL()) if err != nil { return nil, errors.WithStack(err) } return drive.Client.Call(ctx, req) } -// Send implements ftlv1.VerbServiceServer -func (*Agent) Send(context.Context, *ftlv1.SendRequest) (*ftlv1.SendResponse, error) { - panic("unimplemented") -} - -func (l *Agent) List(ctx context.Context, req *ftlv1.ListRequest) (*ftlv1.ListResponse, error) { - ctx = metadata.WithDirectRouting(ctx) +func (a *Agent) List(ctx context.Context, req *connect.Request[ftlv1.ListRequest]) (*connect.Response[ftlv1.ListResponse], error) { + ctx = rpc.WithDirectRouting(ctx) out := &ftlv1.ListResponse{} - for _, drive := range l.allDrives() { - resp, err := drive.Client.List(ctx, proto.Clone(req).(*ftlv1.ListRequest)) + + for _, drive := range a.allDrives() { + resp, err := drive.Client.List(ctx, req) if err != nil { return nil, errors.Wrapf(err, "failed to list module %q", drive.config.Module) } - out.Verbs = append(out.Verbs, resp.Verbs...) + out.Verbs = append(out.Verbs, resp.Msg.Verbs...) } + slices.SortFunc(out.Verbs, func(a, b *pschema.VerbRef) bool { return a.Module < b.Module || (a.Module == b.Module && a.Name < b.Name) }) - return out, nil + + return connect.NewResponse(out), nil } -func (l *Agent) Ping(ctx context.Context, req *ftlv1.PingRequest) (*ftlv1.PingResponse, error) { - return &ftlv1.PingResponse{}, nil +func (*Agent) Ping(context.Context, *connect.Request[ftlv1.PingRequest]) (*connect.Response[ftlv1.PingResponse], error) { + return connect.NewResponse(&ftlv1.PingResponse{}), nil } -func (l *Agent) SyncSchema(stream ftlv1.DevelService_SyncSchemaServer) error { - drives := l.allDrives() - slices.SortStableFunc(drives, func(a, b *driveContext) bool { - return a.config.Module < b.config.Module - }) - for i, drive := range drives { - module, ok := drive.schema.Load().Get() - if !ok { - continue - } - err := stream.Send(&ftlv1.SyncSchemaResponse{ //nolint:forcetypeassert - Schema: module.ToProto().(*pschema.Module), - More: i < len(drives)-1, - }) - if err != nil { - return errors.WithStack(err) - } - } - return nil +func (*Agent) Send(context.Context, *connect.Request[ftlv1.SendRequest]) (*connect.Response[ftlv1.SendResponse], error) { + panic("unimplemented") } -func (l *Agent) allDrives() []*driveContext { - l.lock.Lock() - defer l.lock.Unlock() - out := make([]*driveContext, 0, len(l.drives)) - for _, drive := range l.drives { +func (a *Agent) allDrives() []*driveContext { + a.lock.Lock() + defer a.lock.Unlock() + out := make([]*driveContext, 0, len(a.drives)) + for _, drive := range a.drives { out = append(out, drive) } return out } -func (l *Agent) findDrive(verb string) (*driveContext, error) { - l.lock.Lock() - defer l.lock.Unlock() - modules := make([]string, 0, len(l.drives)) - for _, drive := range l.drives { +func (a *Agent) findDrive(verb string) (*driveContext, error) { + a.lock.Lock() + defer a.lock.Unlock() + modules := make([]string, 0, len(a.drives)) + for _, drive := range a.drives { modules = append(modules, drive.config.Module) if strings.HasPrefix(verb, drive.config.Module) { return drive, nil @@ -333,58 +291,56 @@ func (l *Agent) findDrive(verb string) (*driveContext, error) { return nil, errors.Errorf("could not find module serving Verb %q among %s", verb, strings.Join(modules, ", ")) } -func (l *Agent) syncSchemaFromDrive(ctx context.Context, drive *driveContext) error { - stream, err := drive.develService.SyncSchema(ctx) - if err != nil { - return errors.WithStack(err) - } - - wg, _ := errgroup.WithContext(ctx) - - // Receive schema changes from the drive. - wg.Go(func() error { - for { - resp, err := stream.Recv() - if err != nil { - return errors.WithStack(err) - } - module := schema.ProtoToModule(resp.Schema) - l.schemaChanges.Publish(module) - drive.schema.Store(types.Some(module)) - } - }) +func (a *Agent) syncSchemaToDrive(ctx context.Context, drive *driveContext) error { + stream := drive.develService.PushSchema(ctx) // Send snapshot. - drives := l.allDrives() + drives := a.allDrives() for _, drive := range drives { module, ok := drive.schema.Load().Get() if !ok { continue } - if err := l.sendSchema(stream, module); err != nil { + if err := a.sendSchema(stream, module); err != nil { return errors.WithStack(err) } } // Send changes to the drive. - changes := l.schemaChanges.Subscribe(make(chan *schema.Module, 64)) - wg.Go(func() error { - for module := range changes { - // Don't send updates back to itself. - if module.Name == drive.config.Module { - continue - } - if err := l.sendSchema(stream, module); err != nil { - return errors.WithStack(err) - } + changes := a.schemaChanges.Subscribe(make(chan *schema.Module, 64)) + for module := range changes { + // Don't send updates back to itself. + if module.Name == drive.config.Module { + continue } - return nil - }) + if err := a.sendSchema(stream, module); err != nil { + return errors.WithStack(err) + } + } + return nil +} + +func (a *Agent) syncSchemaFromDrive(ctx context.Context, drive *driveContext) error { + stream, err := drive.develService.PullSchema(ctx, connect.NewRequest(&ftlv1.PullSchemaRequest{})) + if err != nil { + return errors.WithStack(err) + } - return errors.WithStack(wg.Wait()) + for stream.Receive() { + resp := stream.Msg() + if errors.Is(err, io.EOF) { + return nil + } else if err != nil { + return errors.WithStack(err) + } + module := schema.ProtoToModule(resp.Schema) + a.schemaChanges.Publish(module) + drive.schema.Store(types.Some(module)) + } + return errors.WithStack(stream.Err()) } -func (l *Agent) sendSchema(stream ftlv1.DevelService_SyncSchemaClient, module *schema.Module) error { - err := stream.Send(&ftlv1.SyncSchemaRequest{ //nolint:forcetypeassert +func (a *Agent) sendSchema(stream *connect.ClientStreamForClient[ftlv1.PushSchemaRequest, ftlv1.PushSchemaResponse], module *schema.Module) error { + err := stream.Send(&ftlv1.PushSchemaRequest{ //nolint:forcetypeassert Schema: module.ToProto().(*pschema.Module), }) if err != nil { @@ -392,13 +348,3 @@ func (l *Agent) sendSchema(stream ftlv1.DevelService_SyncSchemaClient, module *s } return nil } - -func newHTTPandGRPCMux(httpHand http.Handler, grpcHandler http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.ProtoMajor == 2 && strings.HasPrefix(r.Header.Get("content-type"), "application/grpc") { - grpcHandler.ServeHTTP(w, r) - return - } - httpHand.ServeHTTP(w, r) - }) -} diff --git a/backplane/service.go b/backplane/service.go index 188fdbcaf8..b94ac8bf7b 100644 --- a/backplane/service.go +++ b/backplane/service.go @@ -2,17 +2,18 @@ package backplane import ( "context" - "io" "github.com/alecthomas/errors" + "github.com/bufbuild/connect-go" "github.com/jackc/pgx/v5/pgxpool" "github.com/TBD54566975/ftl/backplane/internal/dao" - ftlv1 "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1" + v1 "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1" + "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1/ftlv1connect" ) -var _ ftlv1.BackplaneServiceServer = (*Service)(nil) -var _ ftlv1.VerbServiceServer = (*Service)(nil) +var _ ftlv1connect.BackplaneServiceHandler = (*Service)(nil) +var _ ftlv1connect.VerbServiceHandler = (*Service)(nil) func New(ctx context.Context, dsn string) (*Service, error) { conn, err := pgxpool.New(ctx, dsn) @@ -26,38 +27,42 @@ type Service struct { dao *dao.DAO } -func (s *Service) Ping(ctx context.Context, req *ftlv1.PingRequest) (*ftlv1.PingResponse, error) { - return &ftlv1.PingResponse{}, nil +func (s *Service) Call(ctx context.Context, req *connect.Request[v1.CallRequest]) (*connect.Response[v1.CallResponse], error) { + panic("unimplemented") } -func (s *Service) Call(ctx context.Context, req *ftlv1.CallRequest) (*ftlv1.CallResponse, error) { +func (s *Service) List(ctx context.Context, req *connect.Request[v1.ListRequest]) (*connect.Response[v1.ListResponse], error) { panic("unimplemented") } -func (s *Service) List(ctx context.Context, req *ftlv1.ListRequest) (*ftlv1.ListResponse, error) { +func (s *Service) Send(ctx context.Context, req *connect.Request[v1.SendRequest]) (*connect.Response[v1.SendResponse], error) { panic("unimplemented") } -func (s *Service) Send(ctx context.Context, req *ftlv1.SendRequest) (*ftlv1.SendResponse, error) { +func (s *Service) GetArtefactDiffs(ctx context.Context, req *connect.Request[v1.GetArtefactDiffsRequest]) (*connect.Response[v1.GetArtefactDiffsResponse], error) { panic("unimplemented") } -func (s *Service) GetArtefactDiffs(ctx context.Context, req *ftlv1.GetArtefactDiffsRequest) (*ftlv1.GetArtefactDiffsResponse, error) { +func (s *Service) Ping(ctx context.Context, req *connect.Request[v1.PingRequest]) (*connect.Response[v1.PingResponse], error) { panic("unimplemented") } -func (s *Service) UploadArtefact(stream ftlv1.BackplaneService_UploadArtefactServer) error { - for { - req, err := stream.Recv() - if errors.Is(err, io.EOF) { - break - } else if err != nil { - return errors.WithStack(err) - } - _, err = s.dao.CreateArtefact(stream.Context(), req.Path, req.Executable, req.Content) - if err != nil { - return errors.WithStack(err) - } - } - return nil +func (s *Service) UploadArtefact(ctx context.Context, req *connect.ClientStream[v1.UploadArtefactRequest]) (*connect.Response[v1.UploadArtefactResponse], error) { + panic("unimplemented") } + +// func (s *Service) UploadArtefact(stream ftlv1.BackplaneService_UploadArtefactServer) error { +// for { +// req, err := stream.Recv() +// if errors.Is(err, io.EOF) { +// break +// } else if err != nil { +// return errors.WithStack(err) +// } +// _, err = s.dao.CreateArtefact(stream.Context(), req.Path, req.Executable, req.Content) +// if err != nil { +// return errors.WithStack(err) +// } +// } +// return nil +// } diff --git a/bin/.make-4.4.pkg b/bin/.make-4.4.pkg new file mode 120000 index 0000000000..383f4511d4 --- /dev/null +++ b/bin/.make-4.4.pkg @@ -0,0 +1 @@ +hermit \ No newline at end of file diff --git a/bin/.protoc-gen-connect-go-1.5.1.pkg b/bin/.protoc-gen-connect-go-1.5.1.pkg new file mode 120000 index 0000000000..383f4511d4 --- /dev/null +++ b/bin/.protoc-gen-connect-go-1.5.1.pkg @@ -0,0 +1 @@ +hermit \ No newline at end of file diff --git a/bin/make b/bin/make new file mode 120000 index 0000000000..46c1196324 --- /dev/null +++ b/bin/make @@ -0,0 +1 @@ +.make-4.4.pkg \ No newline at end of file diff --git a/bin/protoc-gen-connect-go b/bin/protoc-gen-connect-go new file mode 120000 index 0000000000..82ab7b0051 --- /dev/null +++ b/bin/protoc-gen-connect-go @@ -0,0 +1 @@ +.protoc-gen-connect-go-1.5.1.pkg \ No newline at end of file diff --git a/cmd/ftl-drive-go/main.go b/cmd/ftl-drive-go/main.go index fb74bf5de3..d003908b64 100644 --- a/cmd/ftl-drive-go/main.go +++ b/cmd/ftl-drive-go/main.go @@ -6,10 +6,11 @@ import ( "github.com/TBD54566975/ftl/common/plugin" drivego "github.com/TBD54566975/ftl/drive-go" - ftlv1 "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1" + "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1/ftlv1connect" ) func main() { - plugin.Start(context.Background(), os.Getenv("FTL_MODULE"), drivego.Run, ftlv1.RegisterVerbServiceServer, - plugin.RegisterAdditionalServer[*drivego.Server](ftlv1.RegisterDevelServiceServer)) + plugin.Start(context.Background(), os.Getenv("FTL_MODULE"), drivego.Run, + ftlv1connect.VerbServiceName, ftlv1connect.NewVerbServiceHandler, + plugin.RegisterAdditionalServer[*drivego.Server](ftlv1connect.DevelServiceName, ftlv1connect.NewDevelServiceHandler)) } diff --git a/cmd/ftl/cmd_call.go b/cmd/ftl/cmd_call.go index 307211c5ab..1e3e0b1dd0 100644 --- a/cmd/ftl/cmd_call.go +++ b/cmd/ftl/cmd_call.go @@ -5,8 +5,10 @@ import ( "fmt" "github.com/alecthomas/errors" + "github.com/bufbuild/connect-go" ftlv1 "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1" + "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1/ftlv1connect" sdkgo "github.com/TBD54566975/ftl/sdk-go" ) @@ -15,15 +17,15 @@ type callCmd struct { Request string `arg:"" optional:"" help:"JSON request payload." default:"{}"` } -func (c *callCmd) Run(ctx context.Context, client ftlv1.VerbServiceClient) error { - resp, err := client.Call(ctx, &ftlv1.CallRequest{ +func (c *callCmd) Run(ctx context.Context, client ftlv1connect.VerbServiceClient) error { + resp, err := client.Call(ctx, connect.NewRequest(&ftlv1.CallRequest{ Verb: c.Verb.ToProto(), Body: []byte(c.Request), - }) + })) if err != nil { return errors.Wrap(err, "FTL error") } - switch resp := resp.Response.(type) { + switch resp := resp.Msg.Response.(type) { case *ftlv1.CallResponse_Error_: return errors.Errorf("Verb error: %s", resp.Error.Message) diff --git a/cmd/ftl/cmd_list.go b/cmd/ftl/cmd_list.go index 0acea71d35..ca5a45a20b 100644 --- a/cmd/ftl/cmd_list.go +++ b/cmd/ftl/cmd_list.go @@ -5,18 +5,20 @@ import ( "fmt" "github.com/alecthomas/errors" + "github.com/bufbuild/connect-go" ftlv1 "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1" + "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1/ftlv1connect" ) type listCmd struct{} -func (l *listCmd) Run(ctx context.Context, client ftlv1.VerbServiceClient) error { - resp, err := client.List(ctx, &ftlv1.ListRequest{}) +func (l *listCmd) Run(ctx context.Context, client ftlv1connect.VerbServiceClient) error { + resp, err := client.List(ctx, connect.NewRequest(&ftlv1.ListRequest{})) if err != nil { return errors.WithStack(err) } - for _, verb := range resp.Verbs { + for _, verb := range resp.Msg.Verbs { fmt.Printf("%s.%s\n", verb.Module, verb.Name) } return nil diff --git a/cmd/ftl/cmd_schema.go b/cmd/ftl/cmd_schema.go index 5503937780..9782068ed5 100644 --- a/cmd/ftl/cmd_schema.go +++ b/cmd/ftl/cmd_schema.go @@ -3,13 +3,14 @@ package main import ( "context" "fmt" - "io" "time" "github.com/alecthomas/errors" + "github.com/bufbuild/connect-go" "golang.org/x/sync/errgroup" ftlv1 "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1" + "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1/ftlv1connect" "github.com/TBD54566975/ftl/schema" ) @@ -20,29 +21,23 @@ type schemaCmd struct { type schemaGetCmd struct{} -func (c *schemaGetCmd) Run(client ftlv1.DevelServiceClient) error { - ctx := context.Background() - stream, err := client.SyncSchema(ctx) +func (c *schemaGetCmd) Run(ctx context.Context, client ftlv1connect.DevelServiceClient) error { + stream, err := client.PullSchema(ctx, connect.NewRequest(&ftlv1.PullSchemaRequest{})) if err != nil { return errors.WithStack(err) } wg, _ := errgroup.WithContext(ctx) modules := make(chan *schema.Module) wg.Go(func() (err error) { - for { - resp, err := stream.Recv() - if err != nil { - if errors.Is(err, io.EOF) { - return nil - } - return errors.WithStack(err) - } + for stream.Receive() { + resp := stream.Msg() module := schema.ProtoToModule(resp.Schema) modules <- module if !resp.More { return nil } } + return errors.WithStack(stream.Err()) }) wait := make(chan error) diff --git a/cmd/ftl/main.go b/cmd/ftl/main.go index bb6095ca2a..59d81638ba 100644 --- a/cmd/ftl/main.go +++ b/cmd/ftl/main.go @@ -6,12 +6,12 @@ import ( "os/signal" "syscall" - "github.com/alecthomas/errors" "github.com/alecthomas/kong" "github.com/TBD54566975/ftl/common/log" + "github.com/TBD54566975/ftl/common/rpc" "github.com/TBD54566975/ftl/common/socket" - ftlv1 "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1" + "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1/ftlv1connect" ) var version = "dev" @@ -67,22 +67,14 @@ func main() { kctx.FatalIfErrorf(err) } -func dialVerbService(ctx context.Context) func() (ftlv1.VerbServiceClient, error) { - return func() (ftlv1.VerbServiceClient, error) { - conn, err := socket.DialGRPC(ctx, cli.Endpoint) - if err != nil { - return nil, errors.WithStack(err) - } - return ftlv1.NewVerbServiceClient(conn), nil +func dialVerbService(ctx context.Context) func() (ftlv1connect.VerbServiceClient, error) { + return func() (ftlv1connect.VerbServiceClient, error) { + return rpc.Dial(ftlv1connect.NewVerbServiceClient, cli.Endpoint.URL()), nil } } -func dialDevelService(ctx context.Context) func() (ftlv1.DevelServiceClient, error) { - return func() (ftlv1.DevelServiceClient, error) { - conn, err := socket.DialGRPC(ctx, cli.Endpoint) - if err != nil { - return nil, errors.WithStack(err) - } - return ftlv1.NewDevelServiceClient(conn), nil +func dialDevelService(ctx context.Context) func() (ftlv1connect.DevelServiceClient, error) { + return func() (ftlv1connect.DevelServiceClient, error) { + return rpc.Dial(ftlv1connect.NewDevelServiceClient, cli.Endpoint.URL()), nil } } diff --git a/common/metadata/direct.go b/common/metadata/direct.go deleted file mode 100644 index d6400e38ab..0000000000 --- a/common/metadata/direct.go +++ /dev/null @@ -1,65 +0,0 @@ -package metadata - -import ( - "context" - "strings" - - "google.golang.org/grpc" - "google.golang.org/grpc/metadata" -) - -const directRoutingKey = "ftl.direct" - -// WithDirectRouting ensures any hops in Verb routing do not redirect. -// -// This is used so that eg. calls from Drives do not create recursive loops -// when calling back to the Agent. -func WithDirectRouting(ctx context.Context) context.Context { - return metadata.AppendToOutgoingContext(ctx, directRoutingKey, "1") -} - -// IsDirectRouted returns true if the incoming request should be directly -// routed and never redirected. -func IsDirectRouted(ctx context.Context) bool { - return len(metadata.ValueFromIncomingContext(ctx, directRoutingKey)) > 0 -} - -// MetadataUnaryServerInterceptor propagates FTL metadata through to client calls. -func MetadataUnaryServerInterceptor() grpc.UnaryServerInterceptor { - return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { - md, ok := metadata.FromIncomingContext(ctx) - if ok { - ctx = propagateMetadata(ctx, md) - } - return handler(ctx, req) - } -} - -// MetadataStreamServerInterceptor propagates FTL metadata through to client calls. -func MetadataStreamServerInterceptor() grpc.StreamServerInterceptor { - return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - ctx := ss.Context() - md, ok := metadata.FromIncomingContext(ctx) - if ok { - ctx = propagateMetadata(ss.Context(), md) - } - return handler(srv, &wrappedServerStream{ServerStream: ss, ctx: ctx}) - } -} - -func propagateMetadata(ctx context.Context, md metadata.MD) context.Context { - out := metadata.MD{} - for key, values := range md { - if strings.HasPrefix(key, "ftl.") { - out[key] = values - } - } - return metadata.NewOutgoingContext(ctx, out) -} - -type wrappedServerStream struct { - grpc.ServerStream - ctx context.Context -} - -func (ctx *wrappedServerStream) Context() context.Context { return ctx.ctx } diff --git a/common/plugin/serve.go b/common/plugin/serve.go index 60bf324304..0601f4db3b 100644 --- a/common/plugin/serve.go +++ b/common/plugin/serve.go @@ -2,19 +2,26 @@ package plugin import ( "context" + "fmt" "io/ioutil" "net" + "net/http" "os" "os/signal" + "reflect" "strconv" "syscall" + "time" "github.com/alecthomas/errors" "github.com/alecthomas/kong" - "google.golang.org/grpc" - "google.golang.org/grpc/reflection" + "github.com/bufbuild/connect-go" + grpcreflect "github.com/bufbuild/connect-grpcreflect-go" + "golang.org/x/net/http2" + "golang.org/x/net/http2/h2c" "github.com/TBD54566975/ftl/common/log" + "github.com/TBD54566975/ftl/common/rpc" "github.com/TBD54566975/ftl/common/socket" ) @@ -24,20 +31,30 @@ type serveCli struct { kong.Plugins } +type serverRegister[Impl any] struct { + servicePath string + register func(i Impl, mux *http.ServeMux) +} + type startOptions[Impl any] struct { - register []func(grpc.ServiceRegistrar, Impl) + register []serverRegister[Impl] } type StartOption[Impl any] func(*startOptions[Impl]) +// ConnectHandlerFactory is a type alias for a function that creates a new Connect request handler. +type ConnectHandlerFactory[Iface any] func(Iface, ...connect.HandlerOption) (string, http.Handler) + // RegisterAdditionalServer allows a plugin to serve additional gRPC services. // // "Impl" must be an implementation of "Iface. -func RegisterAdditionalServer[Impl any, Iface any](register func(grpc.ServiceRegistrar, Iface)) StartOption[Impl] { +func RegisterAdditionalServer[Impl any, Iface any](servicePath string, register ConnectHandlerFactory[Iface]) StartOption[Impl] { return func(so *startOptions[Impl]) { - so.register = append(so.register, func(sr grpc.ServiceRegistrar, i Impl) { - register(sr, any(i).(Iface)) //nolint:forcetypeassert - }) + so.register = append(so.register, serverRegister[Impl]{ + servicePath: servicePath, + register: func(i Impl, mux *http.ServeMux) { + mux.Handle(register(any(i).(Iface), rpc.DefaultHandlerOptions()...)) //nolint:forcetypeassert + }}) } } @@ -53,13 +70,16 @@ func Start[Impl any, Iface any, Config any]( ctx context.Context, name string, create func(context.Context, Config) (Impl, error), - register func(grpc.ServiceRegistrar, Iface), + servicePath string, + register ConnectHandlerFactory[Iface], options ...StartOption[Impl], ) { var config Config cli := serveCli{Plugins: kong.Plugins{&config}} kctx := kong.Parse(&cli, kong.Description(`FTL - Towards a 𝝺-calculus for large-scale systems`)) + mux := http.NewServeMux() + so := &startOptions[Impl]{} for _, option := range options { option(so) @@ -92,16 +112,35 @@ func Start[Impl any, Iface any, Config any]( svc, err := create(ctx, config) kctx.FatalIfErrorf(err) + if _, ok := any(svc).(Iface); !ok { + var iface Iface + panic(fmt.Sprintf("%s does not implement %s", reflect.TypeOf(svc), reflect.TypeOf(iface))) + } + l, err := socket.Listen(cli.Bind) kctx.FatalIfErrorf(err) - gs := socket.NewGRPCServer(ctx) - reflection.Register(gs) - register(gs, any(svc).(Iface)) //nolint:forcetypeassert + + servicePaths := []string{servicePath} + + mux.Handle(register(any(svc).(Iface), rpc.DefaultHandlerOptions()...)) //nolint:forcetypeassert for _, register := range so.register { - register(gs, svc) + register.register(svc, mux) + servicePaths = append(servicePaths, register.servicePath) + } + + reflector := grpcreflect.NewStaticReflector(servicePaths...) + mux.Handle(grpcreflect.NewHandlerV1(reflector)) + mux.Handle(grpcreflect.NewHandlerV1Alpha(reflector)) + + // Start the server. + http1Server := &http.Server{ + Handler: h2c.NewHandler(mux, &http2.Server{}), + ReadHeaderTimeout: time.Second * 30, + BaseContext: func(net.Listener) context.Context { return ctx }, } - err = gs.Serve(l) + err = http1Server.Serve(l) kctx.FatalIfErrorf(err) + kctx.Exit(0) } diff --git a/common/plugin/spawn.go b/common/plugin/spawn.go index 33a19fe3cd..64efd45ec8 100644 --- a/common/plugin/spawn.go +++ b/common/plugin/spawn.go @@ -9,22 +9,23 @@ import ( "time" "github.com/alecthomas/errors" - "google.golang.org/grpc" + "github.com/bufbuild/connect-go" "github.com/TBD54566975/ftl/common/exec" "github.com/TBD54566975/ftl/common/log" + "github.com/TBD54566975/ftl/common/rpc" "github.com/TBD54566975/ftl/common/socket" ftlv1 "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1" ) // PingableClient is a gRPC client that can be pinged. type PingableClient interface { - Ping(ctx context.Context, in *ftlv1.PingRequest, opts ...grpc.CallOption) (*ftlv1.PingResponse, error) + Ping(context.Context, *connect.Request[ftlv1.PingRequest]) (*connect.Response[ftlv1.PingResponse], error) } type pluginOptions struct { envars []string - additionalClients []func(grpc.ClientConnInterface) + additionalClients []func(baseURL string, opts ...connect.ClientOption) startTimeout time.Duration } @@ -50,10 +51,10 @@ func WithStartTimeout(timeout time.Duration) Option { // WithExtraClient connects to an additional gRPC service in the same plugin. // // The client instance is written to "out". -func WithExtraClient[Client PingableClient](out *Client, makeClient func(grpc.ClientConnInterface) Client) Option { +func WithExtraClient[Client PingableClient](out *Client, makeClient rpc.ClientFactory[Client]) Option { return func(po *pluginOptions) error { - po.additionalClients = append(po.additionalClients, func(cci grpc.ClientConnInterface) { - *out = makeClient(cci) + po.additionalClients = append(po.additionalClients, func(baseURL string, opts ...connect.ClientOption) { + *out = rpc.Dial(makeClient, baseURL, opts...) }) return nil } @@ -66,7 +67,7 @@ type Plugin[Client PingableClient] struct { // Spawn a new sub-process plugin. // -// Plugins are gRPC servers that listen on a unix socket passed in an envar. +// Plugins are gRPC servers that listen on a socket passed in an envar. // // If the subprocess is a Go plugin, it should call [Start] to start the gRPC // server. @@ -80,7 +81,7 @@ type Plugin[Client PingableClient] struct { func Spawn[Client PingableClient]( ctx context.Context, name, dir, exe string, - makeClient func(grpc.ClientConnInterface) Client, + makeClient rpc.ClientFactory[Client], options ...Option, ) ( plugin *Plugin[Client], @@ -158,19 +159,8 @@ func Spawn[Client PingableClient]( dialCtx, cancel := context.WithTimeout(ctx, opts.startTimeout) defer cancel() - conn, err := socket.DialGRPC(dialCtx, pluginSocket) - if err != nil { - return nil, nil, errors.WithStack(err) - } - - // Close the gRPC connection when the context is cancelled. - go func() { - <-cmdCtx.Done() - _ = conn.Close() - }() - // Wait for the plugin to start. - client := makeClient(conn) + client := rpc.Dial(makeClient, pluginSocket.URL()) pingErr := make(chan error) go func() { defer close(pingErr) @@ -180,8 +170,9 @@ func Spawn[Client PingableClient]( return default: } - _, err := client.Ping(dialCtx, &ftlv1.PingRequest{}) + _, err := client.Ping(dialCtx, connect.NewRequest(&ftlv1.PingRequest{})) if err != nil { + logger.Tracef("Plugin ping failed: %+v", err) time.Sleep(time.Millisecond * 100) continue } @@ -203,7 +194,7 @@ func Spawn[Client PingableClient]( } for _, makeClient := range opts.additionalClients { - makeClient(conn) + makeClient(pluginSocket.URL()) } logger.Infof("Online") diff --git a/common/rpc/metadata.go b/common/rpc/metadata.go new file mode 100644 index 0000000000..6a0b22344c --- /dev/null +++ b/common/rpc/metadata.go @@ -0,0 +1,81 @@ +package rpc + +import ( + "context" + + "github.com/bufbuild/connect-go" + + "github.com/TBD54566975/ftl/common/log" +) + +const ftlDirectRoutingHeader = "FTL-Direct" + +type ftlDirectRoutingKey struct{} + +// WithDirectRouting ensures any hops in Verb routing do not redirect. +// +// This is used so that eg. calls from Drives do not create recursive loops +// when calling back to the Agent. +func WithDirectRouting(ctx context.Context) context.Context { + return context.WithValue(ctx, ftlDirectRoutingKey{}, "1") +} + +// IsDirectRouted returns true if the incoming request should be directly +// routed and never redirected. +func IsDirectRouted(ctx context.Context) bool { + return ctx.Value(ftlDirectRoutingKey{}) != nil +} + +func DefaultClientOptions() []connect.ClientOption { + return []connect.ClientOption{ + connect.WithInterceptors(MetadataInterceptor()), + } +} + +func DefaultHandlerOptions() []connect.HandlerOption { + return []connect.HandlerOption{ + connect.WithInterceptors(MetadataInterceptor()), + } +} + +// MetadataInterceptor propagates FTL metadata through servers and clients. +func MetadataInterceptor() connect.Interceptor { + return &metadataInterceptor{} +} + +type metadataInterceptor struct{} + +func (*metadataInterceptor) WrapStreamingClient(req connect.StreamingClientFunc) connect.StreamingClientFunc { + return func(ctx context.Context, s connect.Spec) connect.StreamingClientConn { + log.FromContext(ctx).Tracef("%s (streaming client)", s.Procedure) + return req(ctx, s) + } +} + +func (*metadataInterceptor) WrapStreamingHandler(req connect.StreamingHandlerFunc) connect.StreamingHandlerFunc { + return func(ctx context.Context, s connect.StreamingHandlerConn) error { + log.FromContext(ctx).Tracef("%s (streaming handler)", s.Spec().Procedure) + if s.Spec().IsClient { + if IsDirectRouted(ctx) { + s.RequestHeader().Set(ftlDirectRoutingHeader, "1") + } + } else if s.RequestHeader().Get(ftlDirectRoutingHeader) != "" { + ctx = WithDirectRouting(ctx) + } + return req(ctx, s) + } +} + +func (*metadataInterceptor) WrapUnary(uf connect.UnaryFunc) connect.UnaryFunc { + return connect.UnaryFunc(func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) { + log.FromContext(ctx).Tracef("%s (unary)", req.Spec().Procedure) + if req.Spec().IsClient { + if IsDirectRouted(ctx) { + req.Header().Set(ftlDirectRoutingHeader, "1") + } + } else if req.Header().Get(ftlDirectRoutingHeader) != "" { + ctx = WithDirectRouting(ctx) + } + return uf(ctx, req) + }) +} diff --git a/common/rpc/rpc.go b/common/rpc/rpc.go new file mode 100644 index 0000000000..38cdd8a51e --- /dev/null +++ b/common/rpc/rpc.go @@ -0,0 +1,59 @@ +package rpc + +import ( + "context" + "net" + "net/http" + "time" + + "github.com/bufbuild/connect-go" + + ftlv1 "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1" +) + +// DefaultClient is the default HTTP client used internally by FTL. +var DefaultClient = func() *http.Client { + var netTransport = &http.Transport{ + Dial: (&net.Dialer{ + Timeout: 10 * time.Second, + }).Dial, + TLSHandshakeTimeout: 10 * time.Second, + } + return &http.Client{ + Timeout: time.Second * 10, + Transport: netTransport, + } +}() + +type PingableClient interface { + Ping(context.Context, *connect.Request[ftlv1.PingRequest]) (*connect.Response[ftlv1.PingResponse], error) +} + +type ClientFactory[Client PingableClient] func(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) Client + +func Dial[Client PingableClient](factory ClientFactory[Client], baseURL string, opts ...connect.ClientOption) Client { + opts = append(opts, DefaultClientOptions()...) + return factory(DefaultClient, baseURL, opts...) +} + +// Middleware to inject values from a Context into the request Context. +func Middleware(ctx context.Context, handler http.Handler) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + r = r.WithContext(mergedContext{values: ctx, Context: r.Context()}) + handler.ServeHTTP(w, r) + } +} + +var _ context.Context = (*mergedContext)(nil) + +type mergedContext struct { + values context.Context + context.Context +} + +func (m mergedContext) Value(key any) any { + if value := m.Context.Value(key); value != nil { + return value + } + return m.values.Value(key) +} diff --git a/common/socket/server.go b/common/socket/server.go deleted file mode 100644 index 492dde781e..0000000000 --- a/common/socket/server.go +++ /dev/null @@ -1,53 +0,0 @@ -package socket - -import ( - "context" - - "google.golang.org/grpc" - - "github.com/TBD54566975/ftl/common/metadata" -) - -// NewGRPCServer returns a new gRPC server with values from the context merged -// in, and FTL metadata propagated from incoming server methods to outbound client calls. -func NewGRPCServer(ctx context.Context) *grpc.Server { - return grpc.NewServer( - grpc.ChainUnaryInterceptor(contextUnaryInterceptor(ctx), metadata.MetadataUnaryServerInterceptor()), - grpc.ChainStreamInterceptor(contextStreamInterceptor(ctx), metadata.MetadataStreamServerInterceptor()), - ) -} - -func contextUnaryInterceptor(root context.Context) grpc.UnaryServerInterceptor { - return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - ctx = mergedContext{values: root, Context: ctx} - return handler(ctx, req) - } -} - -func contextStreamInterceptor(root context.Context) grpc.StreamServerInterceptor { - return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { - ctx := mergedContext{values: root, Context: ss.Context()} - return handler(srv, &wrappedServerStream{ServerStream: ss, ctx: ctx}) - } -} - -var _ context.Context = (*mergedContext)(nil) - -type mergedContext struct { - values context.Context - context.Context -} - -func (m mergedContext) Value(key any) any { - if value := m.Context.Value(key); value != nil { - return value - } - return m.values.Value(key) -} - -type wrappedServerStream struct { - grpc.ServerStream - ctx context.Context -} - -func (ctx *wrappedServerStream) Context() context.Context { return ctx.ctx } diff --git a/common/socket/socket.go b/common/socket/socket.go index 109094ddfa..2b95b7d8f1 100644 --- a/common/socket/socket.go +++ b/common/socket/socket.go @@ -2,15 +2,12 @@ package socket import ( - "context" "fmt" "net" "net/url" "os" "github.com/alecthomas/errors" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" ) // Socket represents a (network, addr) pair. Its serialised form is a URI: @@ -20,6 +17,10 @@ type Socket struct { Addr string } +func (s Socket) URL() string { + return "http://" + s.Addr +} + // Valid returns true if the Socket is valid. func (s Socket) Valid() bool { return s.Network != "" && s.Addr != "" @@ -38,33 +39,6 @@ func (s *Socket) UnmarshalText(b []byte) error { return nil } -// Dialer is a convenience function. -func Dialer(ctx context.Context, addr string) (net.Conn, error) { - sock, err := Parse(addr) - if err != nil { - return nil, errors.WithStack(err) - } - return Dial(ctx, sock) -} - -// Dial a Socket. -func Dial(ctx context.Context, s Socket) (net.Conn, error) { - conn, err := (&net.Dialer{}).DialContext(ctx, s.Network, s.Addr) - return conn, errors.WithStack(err) -} - -// DialGRPC using a Socket. -// -// TODO: Extend this to support TLS etc. automatically. -func DialGRPC(ctx context.Context, s Socket, options ...grpc.DialOption) (*grpc.ClientConn, error) { - options = append([]grpc.DialOption{ - grpc.WithTransportCredentials(insecure.NewCredentials()), - grpc.WithContextDialer(Dialer), - }, options...) - conn, err := grpc.DialContext(ctx, s.String(), options...) - return conn, errors.WithStack(err) -} - // Listen on a socket. // // For unix sockets, the socket will be removed if it already exists. diff --git a/console/release.go b/console/release.go index 7b6f0b22b6..bcb0d8a7d6 100644 --- a/console/release.go +++ b/console/release.go @@ -5,7 +5,6 @@ package console import ( "context" "embed" - "fmt" "io/fs" "net/http" @@ -20,9 +19,5 @@ func Server(ctx context.Context) (http.Handler, error) { if err != nil { return nil, errors.WithStack(err) } - err = fs.WalkDir(dir, ".", func(path string, d fs.DirEntry, err error) error { - fmt.Println(path) - return nil - }) return http.FileServer(http.FS(dir)), nil } diff --git a/drive-go/drive.go b/drive-go/drive.go index 0c1fbd37b8..5105439efd 100644 --- a/drive-go/drive.go +++ b/drive-go/drive.go @@ -17,6 +17,7 @@ import ( "github.com/alecthomas/atomic" "github.com/alecthomas/errors" + "github.com/bufbuild/connect-go" "github.com/fsnotify/fsnotify" "golang.org/x/mod/modfile" "golang.org/x/sync/errgroup" @@ -25,11 +26,12 @@ import ( "github.com/TBD54566975/ftl/common/eventsource" "github.com/TBD54566975/ftl/common/exec" "github.com/TBD54566975/ftl/common/log" - "github.com/TBD54566975/ftl/common/metadata" "github.com/TBD54566975/ftl/common/plugin" + "github.com/TBD54566975/ftl/common/rpc" "github.com/TBD54566975/ftl/common/socket" "github.com/TBD54566975/ftl/drive-go/codewriter" ftlv1 "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1" + "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1/ftlv1connect" pschema "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1/schema" "github.com/TBD54566975/ftl/schema" sdkgo "github.com/TBD54566975/ftl/sdk-go" @@ -58,12 +60,7 @@ func Run(ctx context.Context, config Config) (*Server, error) { if err != nil { return nil, errors.WithStack(err) } - conn, err := socket.DialGRPC(ctx, config.Endpoint) - if err != nil { - return nil, errors.Wrap(err, "failed to dial FTL") - } - router := ftlv1.NewVerbServiceClient(conn) - + router := rpc.Dial(ftlv1connect.NewVerbServiceClient, config.Endpoint.URL()) s := &Server{ Config: config, router: router, @@ -84,7 +81,7 @@ func Run(ctx context.Context, config Config) (*Server, error) { return nil, errors.WithStack(err) } - plugin, cmdCtx, err := plugin.Spawn(ctx, "", s.Config.Dir, exe, ftlv1.NewVerbServiceClient, + plugin, cmdCtx, err := plugin.Spawn(ctx, "", s.Config.Dir, exe, ftlv1connect.NewVerbServiceClient, plugin.WithEnvars("FTL_MODULE="+s.module)) if err != nil { return nil, errors.WithStack(err) @@ -97,12 +94,12 @@ func Run(ctx context.Context, config Config) (*Server, error) { return s, nil } -var _ ftlv1.DevelServiceServer = (*Server)(nil) -var _ ftlv1.VerbServiceServer = (*Server)(nil) +var _ ftlv1connect.DevelServiceHandler = (*Server)(nil) +var _ ftlv1connect.VerbServiceHandler = (*Server)(nil) type Server struct { Config - router ftlv1.VerbServiceClient + router ftlv1connect.VerbServiceClient module string goModule *modfile.File wg *errgroup.Group @@ -111,7 +108,7 @@ type Server struct { fullSchema atomic.Value[schema.Schema] moduleSchema *eventsource.EventSource[*schema.Module] - plugin atomic.Value[*plugin.Plugin[ftlv1.VerbServiceClient]] + plugin atomic.Value[*plugin.Plugin[ftlv1connect.VerbServiceClient]] rebuildMu sync.Mutex lastRebuild time.Time @@ -122,55 +119,24 @@ func (s *Server) Wait() error { return errors.WithStack(s.wg.Wait()) } -func (s *Server) SyncSchema(stream ftlv1.DevelService_SyncSchemaServer) error { - wg, ctx := errgroup.WithContext(stream.Context()) - - logger := log.FromContext(ctx) - - // Send initial and subsequent schema updates. - err := s.sendSchema(stream, s.moduleSchema.Load()) +func (s *Server) Call(ctx context.Context, req *connect.Request[ftlv1.CallRequest]) (*connect.Response[ftlv1.CallResponse], error) { + if rpc.IsDirectRouted(ctx) || req.Msg.Verb.Module == s.module { + return s.plugin.Load().Client.Call(ctx, req) + } + resp, err := s.router.Call(ctx, req) if err != nil { - return errors.WithStack(err) + return nil, errors.WithStack(err) } - changes := s.moduleSchema.Subscribe(make(chan *schema.Module, 64)) - defer s.moduleSchema.Unsubscribe(changes) - wg.Go(func() error { - for module := range changes { - if err := s.sendSchema(stream, module); err != nil { - return errors.WithStack(err) - } - } - return nil - }) - - // Receive schema updates. - wg.Go(func() error { - for { - received, err := stream.Recv() - if err != nil { - return errors.WithStack(err) - } - module := schema.ProtoToModule(received.Schema) - - logger.Debugf("Received schema update from %s", module.Name) - - fullSchema := s.fullSchema.Load() - oldHash := fullSchema.Hash() - fullSchema.Upsert(module) - newHash := fullSchema.Hash() - if oldHash != newHash { - s.fullSchema.Store(fullSchema) - s.triggerRebuild <- struct{}{} - } - } - }) - - return errors.WithStack(wg.Wait()) + return resp, nil } -func (s *Server) List(ctx context.Context, req *ftlv1.ListRequest) (*ftlv1.ListResponse, error) { - if !metadata.IsDirectRouted(ctx) { - return s.router.List(ctx, req) +func (s *Server) List(ctx context.Context, req *connect.Request[ftlv1.ListRequest]) (*connect.Response[ftlv1.ListResponse], error) { + if !rpc.IsDirectRouted(ctx) { + resp, err := s.router.List(ctx, req) + if err != nil { + return nil, errors.WithStack(err) + } + return resp, nil } out := &ftlv1.ListResponse{} module := s.moduleSchema.Load() @@ -179,22 +145,54 @@ func (s *Server) List(ctx context.Context, req *ftlv1.ListRequest) (*ftlv1.ListR out.Verbs = append(out.Verbs, &pschema.VerbRef{Module: module.Name, Name: verb.Name}) } } - return out, nil + return connect.NewResponse(out), nil } -func (s *Server) Call(ctx context.Context, req *ftlv1.CallRequest) (*ftlv1.CallResponse, error) { - if metadata.IsDirectRouted(ctx) || req.Verb.Module == s.module { - return s.plugin.Load().Client.Call(ctx, req) +func (s *Server) Send(ctx context.Context, req *connect.Request[ftlv1.SendRequest]) (*connect.Response[ftlv1.SendResponse], error) { + panic("unimplemented") +} + +func (s *Server) Ping(ctx context.Context, req *connect.Request[ftlv1.PingRequest]) (*connect.Response[ftlv1.PingResponse], error) { + return connect.NewResponse(&ftlv1.PingResponse{}), nil +} + +func (s *Server) PullSchema(ctx context.Context, req *connect.Request[ftlv1.PullSchemaRequest], stream *connect.ServerStream[ftlv1.PullSchemaResponse]) error { + // Send initial and subsequent schema updates. + err := s.sendSchema(stream, s.moduleSchema.Load()) + if err != nil { + return errors.WithStack(err) } - return s.router.Call(ctx, req) + changes := s.moduleSchema.Subscribe(make(chan *schema.Module, 64)) + defer s.moduleSchema.Unsubscribe(changes) + for module := range changes { + if err := s.sendSchema(stream, module); err != nil { + return errors.WithStack(err) + } + } + return nil } -// Send implements ftlv1.VerbServiceServer -func (*Server) Send(context.Context, *ftlv1.SendRequest) (*ftlv1.SendResponse, error) { - panic("unimplemented") +func (s *Server) PushSchema(ctx context.Context, stream *connect.ClientStream[ftlv1.PushSchemaRequest]) (*connect.Response[ftlv1.PushSchemaResponse], error) { + logger := log.FromContext(ctx) + for stream.Receive() { + received := stream.Msg() + module := schema.ProtoToModule(received.Schema) + + logger.Debugf("Received schema update from %s", module.Name) + + fullSchema := s.fullSchema.Load() + oldHash := fullSchema.Hash() + fullSchema.Upsert(module) + newHash := fullSchema.Hash() + if oldHash != newHash { + s.fullSchema.Store(fullSchema) + s.triggerRebuild <- struct{}{} + } + } + return connect.NewResponse(&ftlv1.PushSchemaResponse{}), nil } -// func (s *Server) FileChange(ctx context.Context, req *ftlv1.FileChangeRequest) (*ftlv1.FileChangeResponse, error) { +// func (s *Server) _FileChange(ctx context.Context, req *ftlv1.FileChangeRequest) (*ftlv1.FileChangeResponse, error) { // _, err := s.rebuild(ctx) // if err != nil { // return nil, errors.WithStack(err) @@ -206,10 +204,6 @@ func (*Server) Send(context.Context, *ftlv1.SendRequest) (*ftlv1.SendResponse, e // return &ftlv1.FileChangeResponse{}, errors.WithStack(err) // } -func (*Server) Ping(context.Context, *ftlv1.PingRequest) (*ftlv1.PingResponse, error) { - return &ftlv1.PingResponse{}, nil -} - // Restart the FTL hot reload module if it terminates unexpectedly. func (s *Server) restartModuleOnExit(ctx, cmdCtx context.Context) error { logger := log.FromContext(ctx) @@ -228,8 +222,8 @@ func (s *Server) restartModuleOnExit(ctx, cmdCtx context.Context) error { logger.Errorf(err, "Failed to rebuild FTL module") continue } - var nextPlugin *plugin.Plugin[ftlv1.VerbServiceClient] - nextPlugin, cmdCtx, err = plugin.Spawn(ctx, s.Config.Module, s.Config.Dir, exe, ftlv1.NewVerbServiceClient) + var nextPlugin *plugin.Plugin[ftlv1connect.VerbServiceClient] + nextPlugin, cmdCtx, err = plugin.Spawn(ctx, s.Config.Module, s.Config.Dir, exe, ftlv1connect.NewVerbServiceClient) if err != nil { logger.Errorf(err, "Failed to restart FTL module") continue @@ -441,8 +435,8 @@ func (s *Server) watchForChanges(ctx context.Context) error { } } -func (s *Server) sendSchema(stream ftlv1.DevelService_SyncSchemaServer, module *schema.Module) error { - err := stream.Send(&ftlv1.SyncSchemaResponse{ //nolint:forcetypeassert +func (s *Server) sendSchema(stream *connect.ServerStream[ftlv1.PullSchemaResponse], module *schema.Module) error { + err := stream.Send(&ftlv1.PullSchemaResponse{ //nolint:forcetypeassert Schema: module.ToProto().(*pschema.Module), }) if err != nil { @@ -480,12 +474,11 @@ func generate(config Config) (*codewriter.Writer, error) { w.Import("github.com/TBD54566975/ftl/sdk-go") w.Import("github.com/TBD54566975/ftl/common/plugin") w.Import("github.com/TBD54566975/ftl/common/socket") - w.Import(`github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1`) + w.Import(`github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1/ftlv1connect`) w.L(`func main() {`) w.In(func(w *codewriter.Writer) { - w.L(`ctx, err := sdkgo.ContextWithClient(context.Background(), socket.MustParse(os.Getenv("FTL_ENDPOINT")))`) - w.L(`if err != nil { panic(err) }`) + w.L(`ctx := sdkgo.ContextWithClient(context.Background(), socket.MustParse(os.Getenv("FTL_ENDPOINT")))`) w.L(`plugin.Start(ctx, %q, drivego.NewUserVerbServer(`, config.Module) for pkg, endpoints := range endpoints { pkgImp := w.Import(pkg) @@ -493,7 +486,7 @@ func generate(config Config) (*codewriter.Writer, error) { w.L(` drivego.Handle(%s.%s),`, pkgImp, endpoint.fn.Name()) } } - w.L(`), ftlv1.RegisterVerbServiceServer)`) + w.L(`), ftlv1connect.VerbServiceName, ftlv1connect.NewVerbServiceHandler)`) }) w.L(`}`) diff --git a/drive-go/server.go b/drive-go/server.go index 8fe16caaea..572f26d978 100644 --- a/drive-go/server.go +++ b/drive-go/server.go @@ -5,8 +5,10 @@ import ( "encoding/json" "github.com/alecthomas/errors" + "github.com/bufbuild/connect-go" ftlv1 "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1" + "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1/ftlv1connect" sdkgo "github.com/TBD54566975/ftl/sdk-go" ) @@ -15,8 +17,8 @@ type UserVerbConfig struct{} // NewUserVerbServer starts a new code-generated drive for user Verbs. // // This function is intended to be used by the code generator. -func NewUserVerbServer(handlers ...Handler) func(context.Context, UserVerbConfig) (ftlv1.VerbServiceServer, error) { - return func(ctx context.Context, mc UserVerbConfig) (ftlv1.VerbServiceServer, error) { +func NewUserVerbServer(handlers ...Handler) func(context.Context, UserVerbConfig) (ftlv1connect.VerbServiceHandler, error) { + return func(ctx context.Context, mc UserVerbConfig) (ftlv1connect.VerbServiceHandler, error) { hmap := map[sdkgo.VerbRef]Handler{} for _, handler := range handlers { hmap[handler.ref] = handler @@ -59,43 +61,45 @@ func Handle[Req, Resp any](verb func(ctx context.Context, req Req) (Resp, error) } } -var _ ftlv1.VerbServiceServer = (*moduleServer)(nil) +var _ ftlv1connect.VerbServiceHandler = (*moduleServer)(nil) // This is the server that is compiled into the same binary as user-defined Verbs. type moduleServer struct { handlers map[sdkgo.VerbRef]Handler } -// Send implements ftlv1.VerbServiceServer -func (*moduleServer) Send(context.Context, *ftlv1.SendRequest) (*ftlv1.SendResponse, error) { - panic("unimplemented") +func (m *moduleServer) Call(ctx context.Context, req *connect.Request[ftlv1.CallRequest]) (*connect.Response[ftlv1.CallResponse], error) { + handler, ok := m.handlers[sdkgo.VerbRefFromProto(req.Msg.Verb)] + + if !ok { + return nil, errors.Errorf("verb %q not found", req.Msg.Verb) + } + + respdata, err := handler.fn(ctx, req.Msg.Body) + if err != nil { + // This makes me slightly ill. + return connect.NewResponse(&ftlv1.CallResponse{ + Response: &ftlv1.CallResponse_Error_{Error: &ftlv1.CallResponse_Error{Message: err.Error()}}, + }), nil + } + + return connect.NewResponse(&ftlv1.CallResponse{ + Response: &ftlv1.CallResponse_Body{Body: respdata}, + }), nil } -func (m *moduleServer) List(ctx context.Context, req *ftlv1.ListRequest) (*ftlv1.ListResponse, error) { +func (m *moduleServer) List(ctx context.Context, req *connect.Request[ftlv1.ListRequest]) (*connect.Response[ftlv1.ListResponse], error) { out := &ftlv1.ListResponse{} for handler := range m.handlers { out.Verbs = append(out.Verbs, handler.ToProto()) } - return out, nil + return connect.NewResponse(out), nil } -func (*moduleServer) Ping(context.Context, *ftlv1.PingRequest) (*ftlv1.PingResponse, error) { - return &ftlv1.PingResponse{}, nil +func (m *moduleServer) Ping(ctx context.Context, req *connect.Request[ftlv1.PingRequest]) (*connect.Response[ftlv1.PingResponse], error) { + return connect.NewResponse(&ftlv1.PingResponse{}), nil } -func (m *moduleServer) Call(ctx context.Context, req *ftlv1.CallRequest) (*ftlv1.CallResponse, error) { - handler, ok := m.handlers[sdkgo.VerbRefFromProto(req.Verb)] - if !ok { - return nil, errors.Errorf("verb %q not found", req.Verb) - } - respdata, err := handler.fn(ctx, req.Body) - if err != nil { - // This makes me slightly ill. - return &ftlv1.CallResponse{ - Response: &ftlv1.CallResponse_Error_{Error: &ftlv1.CallResponse_Error{Message: err.Error()}}, - }, nil - } - return &ftlv1.CallResponse{ - Response: &ftlv1.CallResponse_Body{Body: respdata}, - }, nil +func (m *moduleServer) Send(ctx context.Context, req *connect.Request[ftlv1.SendRequest]) (*connect.Response[ftlv1.SendResponse], error) { + panic("unimplemented") } diff --git a/drive-kotlin/src/main/proto b/drive-kotlin/src/main/proto deleted file mode 120000 index 21f63ff310..0000000000 --- a/drive-kotlin/src/main/proto +++ /dev/null @@ -1 +0,0 @@ -../../../protos \ No newline at end of file diff --git a/examples/echo/go.mod b/examples/echo/go.mod index 3401eaccd1..1a5d94dd13 100644 --- a/examples/echo/go.mod +++ b/examples/echo/go.mod @@ -15,15 +15,12 @@ require ( github.com/alecthomas/errors v0.3.0 // indirect github.com/alecthomas/participle/v2 v2.0.0 // indirect github.com/alecthomas/types v0.0.0-20230329042226-25f53f031fd9 // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/bufbuild/connect-go v1.7.0 // indirect github.com/iancoleman/strcase v0.2.0 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 // indirect golang.org/x/mod v0.9.0 // indirect - golang.org/x/net v0.9.0 // indirect golang.org/x/sys v0.7.0 // indirect - golang.org/x/text v0.9.0 // indirect golang.org/x/tools v0.7.0 // indirect - google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/grpc v1.54.0 // indirect google.golang.org/protobuf v1.30.0 // indirect ) diff --git a/examples/echo/go.sum b/examples/echo/go.sum index aa60e27853..d5b651e4af 100644 --- a/examples/echo/go.sum +++ b/examples/echo/go.sum @@ -6,33 +6,27 @@ github.com/alecthomas/participle/v2 v2.0.0/go.mod h1:rAKZdJldHu8084ojcWevWAL8KmE github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= github.com/alecthomas/types v0.0.0-20230329042226-25f53f031fd9 h1:D15xxPSKWIu5WSVRzNzxFYDO7XLA3RZ0S2n2EXh2C0c= github.com/alecthomas/types v0.0.0-20230329042226-25f53f031fd9/go.mod h1:+0cnSjIFNpEFoyhqHgvyYuCSJxvNydquHfbrrRrAUgE= +github.com/bufbuild/connect-go v1.7.0 h1:MGp82v7SCza+3RhsVhV7aMikwxvI3ZfD72YiGt8FYJo= +github.com/bufbuild/connect-go v1.7.0/go.mod h1:GmMJYR6orFqD0Y6ZgX8pwQ8j9baizDrIQMm1/a6LnHk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI= golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= -google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/go.mod b/go.mod index eb30a9052c..e402d0fcf5 100644 --- a/go.mod +++ b/go.mod @@ -4,19 +4,18 @@ go 1.20 require ( github.com/alecthomas/kong v0.7.1 + github.com/bufbuild/connect-go v1.7.0 github.com/google/uuid v1.3.0 github.com/jackc/pgx/v5 v5.3.1 golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 golang.org/x/net v0.9.0 golang.org/x/sync v0.1.0 golang.org/x/tools v0.7.0 - google.golang.org/grpc v1.54.0 google.golang.org/protobuf v1.30.0 ) require ( github.com/alecthomas/repr v0.2.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect @@ -25,7 +24,6 @@ require ( github.com/rogpeppe/go-internal v1.10.0 // indirect golang.org/x/crypto v0.7.0 // indirect golang.org/x/text v0.9.0 // indirect - google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect ) require ( @@ -35,6 +33,7 @@ require ( github.com/alecthomas/errors v0.3.0 github.com/alecthomas/participle/v2 v2.0.0 github.com/alecthomas/types v0.0.0-20230329042226-25f53f031fd9 + github.com/bufbuild/connect-grpcreflect-go v1.0.0 github.com/fsnotify/fsnotify v1.6.0 github.com/gofrs/flock v0.8.1 github.com/iancoleman/strcase v0.2.0 diff --git a/go.sum b/go.sum index e871d3c566..01eef6ed15 100644 --- a/go.sum +++ b/go.sum @@ -14,6 +14,10 @@ github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/types v0.0.0-20230329042226-25f53f031fd9 h1:D15xxPSKWIu5WSVRzNzxFYDO7XLA3RZ0S2n2EXh2C0c= github.com/alecthomas/types v0.0.0-20230329042226-25f53f031fd9/go.mod h1:+0cnSjIFNpEFoyhqHgvyYuCSJxvNydquHfbrrRrAUgE= +github.com/bufbuild/connect-go v1.7.0 h1:MGp82v7SCza+3RhsVhV7aMikwxvI3ZfD72YiGt8FYJo= +github.com/bufbuild/connect-go v1.7.0/go.mod h1:GmMJYR6orFqD0Y6ZgX8pwQ8j9baizDrIQMm1/a6LnHk= +github.com/bufbuild/connect-grpcreflect-go v1.0.0 h1:zWsLFYqrT1O2sNJFYfTXI5WxbAyiY2dvevvnJHPtV5A= +github.com/bufbuild/connect-grpcreflect-go v1.0.0/go.mod h1:825I20H8bfE9rLnBH/046JSpmm3uwpNYdG4duCARetc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -23,8 +27,6 @@ github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbS github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= @@ -78,12 +80,7 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= -google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/protos/buf.gen.yaml b/protos/buf.gen.yaml index f48d6b8771..4efb9a9c83 100644 --- a/protos/buf.gen.yaml +++ b/protos/buf.gen.yaml @@ -3,6 +3,6 @@ plugins: - plugin: go out: . opt: paths=source_relative - - plugin: go-grpc + - plugin: connect-go out: . - opt: paths=source_relative,require_unimplemented_servers=false + opt: paths=source_relative \ No newline at end of file diff --git a/protos/xyz/block/ftl/v1/ftl.pb.go b/protos/xyz/block/ftl/v1/ftl.pb.go index c40e9daddc..19e06c145d 100644 --- a/protos/xyz/block/ftl/v1/ftl.pb.go +++ b/protos/xyz/block/ftl/v1/ftl.pb.go @@ -473,7 +473,7 @@ func (*SendResponse) Descriptor() ([]byte, []int) { return file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP(), []int{8} } -type SyncSchemaRequest struct { +type PushSchemaRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -481,8 +481,8 @@ type SyncSchemaRequest struct { Schema *schema.Module `protobuf:"bytes,1,opt,name=schema,proto3" json:"schema,omitempty"` } -func (x *SyncSchemaRequest) Reset() { - *x = SyncSchemaRequest{} +func (x *PushSchemaRequest) Reset() { + *x = PushSchemaRequest{} if protoimpl.UnsafeEnabled { mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -490,13 +490,13 @@ func (x *SyncSchemaRequest) Reset() { } } -func (x *SyncSchemaRequest) String() string { +func (x *PushSchemaRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SyncSchemaRequest) ProtoMessage() {} +func (*PushSchemaRequest) ProtoMessage() {} -func (x *SyncSchemaRequest) ProtoReflect() protoreflect.Message { +func (x *PushSchemaRequest) ProtoReflect() protoreflect.Message { mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -508,19 +508,95 @@ func (x *SyncSchemaRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SyncSchemaRequest.ProtoReflect.Descriptor instead. -func (*SyncSchemaRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use PushSchemaRequest.ProtoReflect.Descriptor instead. +func (*PushSchemaRequest) Descriptor() ([]byte, []int) { return file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP(), []int{9} } -func (x *SyncSchemaRequest) GetSchema() *schema.Module { +func (x *PushSchemaRequest) GetSchema() *schema.Module { if x != nil { return x.Schema } return nil } -type SyncSchemaResponse struct { +type PushSchemaResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PushSchemaResponse) Reset() { + *x = PushSchemaResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PushSchemaResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PushSchemaResponse) ProtoMessage() {} + +func (x *PushSchemaResponse) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[10] + 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 PushSchemaResponse.ProtoReflect.Descriptor instead. +func (*PushSchemaResponse) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP(), []int{10} +} + +type PullSchemaRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PullSchemaRequest) Reset() { + *x = PullSchemaRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PullSchemaRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PullSchemaRequest) ProtoMessage() {} + +func (x *PullSchemaRequest) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[11] + 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 PullSchemaRequest.ProtoReflect.Descriptor instead. +func (*PullSchemaRequest) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP(), []int{11} +} + +type PullSchemaResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -531,23 +607,23 @@ type SyncSchemaResponse struct { More bool `protobuf:"varint,2,opt,name=more,proto3" json:"more,omitempty"` } -func (x *SyncSchemaResponse) Reset() { - *x = SyncSchemaResponse{} +func (x *PullSchemaResponse) Reset() { + *x = PullSchemaResponse{} if protoimpl.UnsafeEnabled { - mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[10] + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *SyncSchemaResponse) String() string { +func (x *PullSchemaResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SyncSchemaResponse) ProtoMessage() {} +func (*PullSchemaResponse) ProtoMessage() {} -func (x *SyncSchemaResponse) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[10] +func (x *PullSchemaResponse) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -558,19 +634,19 @@ func (x *SyncSchemaResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SyncSchemaResponse.ProtoReflect.Descriptor instead. -func (*SyncSchemaResponse) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP(), []int{10} +// Deprecated: Use PullSchemaResponse.ProtoReflect.Descriptor instead. +func (*PullSchemaResponse) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP(), []int{12} } -func (x *SyncSchemaResponse) GetSchema() *schema.Module { +func (x *PullSchemaResponse) GetSchema() *schema.Module { if x != nil { return x.Schema } return nil } -func (x *SyncSchemaResponse) GetMore() bool { +func (x *PullSchemaResponse) GetMore() bool { if x != nil { return x.More } @@ -588,7 +664,7 @@ type GetArtefactDiffsRequest struct { func (x *GetArtefactDiffsRequest) Reset() { *x = GetArtefactDiffsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[11] + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -601,7 +677,7 @@ func (x *GetArtefactDiffsRequest) String() string { func (*GetArtefactDiffsRequest) ProtoMessage() {} func (x *GetArtefactDiffsRequest) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[11] + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -614,7 +690,7 @@ func (x *GetArtefactDiffsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetArtefactDiffsRequest.ProtoReflect.Descriptor instead. func (*GetArtefactDiffsRequest) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP(), []int{11} + return file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP(), []int{13} } func (x *GetArtefactDiffsRequest) GetClientDigests() []string { @@ -635,7 +711,7 @@ type GetArtefactDiffsResponse struct { func (x *GetArtefactDiffsResponse) Reset() { *x = GetArtefactDiffsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[12] + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -648,7 +724,7 @@ func (x *GetArtefactDiffsResponse) String() string { func (*GetArtefactDiffsResponse) ProtoMessage() {} func (x *GetArtefactDiffsResponse) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[12] + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -661,7 +737,7 @@ func (x *GetArtefactDiffsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetArtefactDiffsResponse.ProtoReflect.Descriptor instead. func (*GetArtefactDiffsResponse) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP(), []int{12} + return file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP(), []int{14} } func (x *GetArtefactDiffsResponse) GetMissingDigests() []string { @@ -685,7 +761,7 @@ type UploadArtefactRequest struct { func (x *UploadArtefactRequest) Reset() { *x = UploadArtefactRequest{} if protoimpl.UnsafeEnabled { - mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[13] + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -698,7 +774,7 @@ func (x *UploadArtefactRequest) String() string { func (*UploadArtefactRequest) ProtoMessage() {} func (x *UploadArtefactRequest) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[13] + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -711,7 +787,7 @@ func (x *UploadArtefactRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadArtefactRequest.ProtoReflect.Descriptor instead. func (*UploadArtefactRequest) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP(), []int{13} + return file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP(), []int{15} } func (x *UploadArtefactRequest) GetPath() string { @@ -751,7 +827,7 @@ type UploadArtefactResponse struct { func (x *UploadArtefactResponse) Reset() { *x = UploadArtefactResponse{} if protoimpl.UnsafeEnabled { - mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[14] + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -764,7 +840,7 @@ func (x *UploadArtefactResponse) String() string { func (*UploadArtefactResponse) ProtoMessage() {} func (x *UploadArtefactResponse) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[14] + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -777,7 +853,7 @@ func (x *UploadArtefactResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadArtefactResponse.ProtoReflect.Descriptor instead. func (*UploadArtefactResponse) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP(), []int{14} + return file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP(), []int{16} } type Metadata_Pair struct { @@ -792,7 +868,7 @@ type Metadata_Pair struct { func (x *Metadata_Pair) Reset() { *x = Metadata_Pair{} if protoimpl.UnsafeEnabled { - mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[15] + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -805,7 +881,7 @@ func (x *Metadata_Pair) String() string { func (*Metadata_Pair) ProtoMessage() {} func (x *Metadata_Pair) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[15] + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -846,7 +922,7 @@ type CallResponse_Error struct { func (x *CallResponse_Error) Reset() { *x = CallResponse_Error{} if protoimpl.UnsafeEnabled { - mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[16] + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -859,7 +935,7 @@ func (x *CallResponse_Error) String() string { func (*CallResponse_Error) ProtoMessage() {} func (x *CallResponse_Error) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[16] + mi := &file_xyz_block_ftl_v1_ftl_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -933,89 +1009,98 @@ var file_xyz_block_ftl_v1_ftl_proto_rawDesc = []byte{ 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x56, 0x65, 0x72, 0x62, 0x52, 0x65, 0x66, 0x52, 0x04, 0x76, 0x65, 0x72, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x0e, 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4c, 0x0a, 0x11, 0x53, 0x79, 0x6e, 0x63, 0x53, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4c, 0x0a, 0x11, 0x50, 0x75, 0x73, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x06, 0x73, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x61, 0x0a, 0x12, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x73, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x79, - 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x06, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x04, 0x6d, 0x6f, 0x72, 0x65, 0x22, 0x40, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, - 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, 0x74, 0x44, 0x69, 0x66, 0x66, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x69, - 0x67, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x73, 0x22, 0x43, 0x0a, 0x18, 0x47, 0x65, - 0x74, 0x41, 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, 0x74, 0x44, 0x69, 0x66, 0x66, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, - 0x67, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0e, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x73, 0x22, - 0x7d, 0x0a, 0x15, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, - 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1e, 0x0a, 0x0a, - 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, - 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, - 0x67, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x18, - 0x0a, 0x16, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xa9, 0x02, 0x0a, 0x0b, 0x56, 0x65, 0x72, - 0x62, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x14, 0x0a, 0x12, 0x50, 0x75, 0x73, 0x68, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x13, 0x0a, 0x11, 0x50, + 0x75, 0x6c, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x22, 0x61, 0x0a, 0x12, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, + 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x6d, + 0x6f, 0x72, 0x65, 0x22, 0x40, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x65, 0x66, 0x61, + 0x63, 0x74, 0x44, 0x69, 0x66, 0x66, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, + 0x0a, 0x0e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x44, 0x69, + 0x67, 0x65, 0x73, 0x74, 0x73, 0x22, 0x43, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x65, + 0x66, 0x61, 0x63, 0x74, 0x44, 0x69, 0x66, 0x66, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x69, 0x67, + 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x6d, 0x69, 0x73, 0x73, + 0x69, 0x6e, 0x67, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x73, 0x22, 0x7d, 0x0a, 0x15, 0x55, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x65, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, + 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x18, 0x0a, 0x16, 0x55, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x41, 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x32, 0xa9, 0x02, 0x0a, 0x0b, 0x56, 0x65, 0x72, 0x62, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1d, 0x2e, 0x78, 0x79, + 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x78, 0x79, 0x7a, + 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x04, 0x43, 0x61, + 0x6c, 0x6c, 0x12, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, + 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, + 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x45, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x45, 0x0a, 0x04, 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x04, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x1d, - 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, - 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, - 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xb2, 0x01, 0x0a, 0x0c, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1d, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, + 0x8b, 0x02, 0x0a, 0x0c, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x12, 0x45, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x0a, 0x50, 0x75, 0x73, 0x68, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x23, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x78, 0x79, 0x7a, + 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, + 0x73, 0x68, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x28, 0x01, 0x12, 0x59, 0x0a, 0x0a, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x12, 0x23, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x6c, 0x6c, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x32, 0xab, 0x02, + 0x0a, 0x10, 0x42, 0x61, 0x63, 0x6b, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x45, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1d, 0x2e, 0x78, 0x79, 0x7a, + 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, + 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x69, 0x0a, 0x10, 0x47, 0x65, 0x74, + 0x41, 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, 0x74, 0x44, 0x69, 0x66, 0x66, 0x73, 0x12, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x78, - 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a, 0x0a, - 0x53, 0x79, 0x6e, 0x63, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x23, 0x2e, 0x78, 0x79, 0x7a, - 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, - 0x6e, 0x63, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x32, 0xab, 0x02, 0x0a, 0x10, 0x42, 0x61, - 0x63, 0x6b, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x45, - 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x69, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x65, - 0x66, 0x61, 0x63, 0x74, 0x44, 0x69, 0x66, 0x66, 0x73, 0x12, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x2e, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x41, 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, 0x74, 0x44, 0x69, 0x66, 0x66, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x65, 0x66, - 0x61, 0x63, 0x74, 0x44, 0x69, 0x66, 0x66, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x65, 0x0a, 0x0e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x72, 0x74, 0x65, 0x66, 0x61, - 0x63, 0x74, 0x12, 0x27, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, - 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x72, 0x74, 0x65, - 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x78, 0x79, - 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x55, - 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x42, 0x3c, 0x50, 0x01, 0x5a, 0x38, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x42, 0x44, 0x35, 0x34, 0x35, 0x36, 0x36, - 0x39, 0x37, 0x35, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x78, - 0x79, 0x7a, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x76, 0x31, 0x3b, - 0x66, 0x74, 0x6c, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, 0x74, 0x44, 0x69, 0x66, 0x66, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, + 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, 0x74, 0x44, 0x69, 0x66, 0x66, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x65, 0x0a, 0x0e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x72, + 0x74, 0x65, 0x66, 0x61, 0x63, 0x74, 0x12, 0x27, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, + 0x41, 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x28, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, + 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x72, 0x74, 0x65, 0x66, 0x61, 0x63, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x42, 0x3c, 0x50, 0x01, 0x5a, + 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x42, 0x44, 0x35, + 0x34, 0x35, 0x36, 0x36, 0x39, 0x37, 0x35, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x73, 0x2f, 0x78, 0x79, 0x7a, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, + 0x2f, 0x76, 0x31, 0x3b, 0x66, 0x74, 0x6c, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -1030,7 +1115,7 @@ func file_xyz_block_ftl_v1_ftl_proto_rawDescGZIP() []byte { return file_xyz_block_ftl_v1_ftl_proto_rawDescData } -var file_xyz_block_ftl_v1_ftl_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_xyz_block_ftl_v1_ftl_proto_msgTypes = make([]protoimpl.MessageInfo, 19) var file_xyz_block_ftl_v1_ftl_proto_goTypes = []interface{}{ (*PingRequest)(nil), // 0: xyz.block.ftl.v1.PingRequest (*PingResponse)(nil), // 1: xyz.block.ftl.v1.PingResponse @@ -1041,47 +1126,51 @@ var file_xyz_block_ftl_v1_ftl_proto_goTypes = []interface{}{ (*ListResponse)(nil), // 6: xyz.block.ftl.v1.ListResponse (*SendRequest)(nil), // 7: xyz.block.ftl.v1.SendRequest (*SendResponse)(nil), // 8: xyz.block.ftl.v1.SendResponse - (*SyncSchemaRequest)(nil), // 9: xyz.block.ftl.v1.SyncSchemaRequest - (*SyncSchemaResponse)(nil), // 10: xyz.block.ftl.v1.SyncSchemaResponse - (*GetArtefactDiffsRequest)(nil), // 11: xyz.block.ftl.v1.GetArtefactDiffsRequest - (*GetArtefactDiffsResponse)(nil), // 12: xyz.block.ftl.v1.GetArtefactDiffsResponse - (*UploadArtefactRequest)(nil), // 13: xyz.block.ftl.v1.UploadArtefactRequest - (*UploadArtefactResponse)(nil), // 14: xyz.block.ftl.v1.UploadArtefactResponse - (*Metadata_Pair)(nil), // 15: xyz.block.ftl.v1.Metadata.Pair - (*CallResponse_Error)(nil), // 16: xyz.block.ftl.v1.CallResponse.Error - (*schema.VerbRef)(nil), // 17: xyz.block.ftl.v1.schema.VerbRef - (*schema.Module)(nil), // 18: xyz.block.ftl.v1.schema.Module + (*PushSchemaRequest)(nil), // 9: xyz.block.ftl.v1.PushSchemaRequest + (*PushSchemaResponse)(nil), // 10: xyz.block.ftl.v1.PushSchemaResponse + (*PullSchemaRequest)(nil), // 11: xyz.block.ftl.v1.PullSchemaRequest + (*PullSchemaResponse)(nil), // 12: xyz.block.ftl.v1.PullSchemaResponse + (*GetArtefactDiffsRequest)(nil), // 13: xyz.block.ftl.v1.GetArtefactDiffsRequest + (*GetArtefactDiffsResponse)(nil), // 14: xyz.block.ftl.v1.GetArtefactDiffsResponse + (*UploadArtefactRequest)(nil), // 15: xyz.block.ftl.v1.UploadArtefactRequest + (*UploadArtefactResponse)(nil), // 16: xyz.block.ftl.v1.UploadArtefactResponse + (*Metadata_Pair)(nil), // 17: xyz.block.ftl.v1.Metadata.Pair + (*CallResponse_Error)(nil), // 18: xyz.block.ftl.v1.CallResponse.Error + (*schema.VerbRef)(nil), // 19: xyz.block.ftl.v1.schema.VerbRef + (*schema.Module)(nil), // 20: xyz.block.ftl.v1.schema.Module } var file_xyz_block_ftl_v1_ftl_proto_depIdxs = []int32{ - 15, // 0: xyz.block.ftl.v1.Metadata.values:type_name -> xyz.block.ftl.v1.Metadata.Pair + 17, // 0: xyz.block.ftl.v1.Metadata.values:type_name -> xyz.block.ftl.v1.Metadata.Pair 2, // 1: xyz.block.ftl.v1.CallRequest.metadata:type_name -> xyz.block.ftl.v1.Metadata - 17, // 2: xyz.block.ftl.v1.CallRequest.verb:type_name -> xyz.block.ftl.v1.schema.VerbRef - 16, // 3: xyz.block.ftl.v1.CallResponse.error:type_name -> xyz.block.ftl.v1.CallResponse.Error - 17, // 4: xyz.block.ftl.v1.ListResponse.verbs:type_name -> xyz.block.ftl.v1.schema.VerbRef + 19, // 2: xyz.block.ftl.v1.CallRequest.verb:type_name -> xyz.block.ftl.v1.schema.VerbRef + 18, // 3: xyz.block.ftl.v1.CallResponse.error:type_name -> xyz.block.ftl.v1.CallResponse.Error + 19, // 4: xyz.block.ftl.v1.ListResponse.verbs:type_name -> xyz.block.ftl.v1.schema.VerbRef 2, // 5: xyz.block.ftl.v1.SendRequest.metadata:type_name -> xyz.block.ftl.v1.Metadata - 17, // 6: xyz.block.ftl.v1.SendRequest.verb:type_name -> xyz.block.ftl.v1.schema.VerbRef - 18, // 7: xyz.block.ftl.v1.SyncSchemaRequest.schema:type_name -> xyz.block.ftl.v1.schema.Module - 18, // 8: xyz.block.ftl.v1.SyncSchemaResponse.schema:type_name -> xyz.block.ftl.v1.schema.Module + 19, // 6: xyz.block.ftl.v1.SendRequest.verb:type_name -> xyz.block.ftl.v1.schema.VerbRef + 20, // 7: xyz.block.ftl.v1.PushSchemaRequest.schema:type_name -> xyz.block.ftl.v1.schema.Module + 20, // 8: xyz.block.ftl.v1.PullSchemaResponse.schema:type_name -> xyz.block.ftl.v1.schema.Module 0, // 9: xyz.block.ftl.v1.VerbService.Ping:input_type -> xyz.block.ftl.v1.PingRequest 3, // 10: xyz.block.ftl.v1.VerbService.Call:input_type -> xyz.block.ftl.v1.CallRequest 7, // 11: xyz.block.ftl.v1.VerbService.Send:input_type -> xyz.block.ftl.v1.SendRequest 5, // 12: xyz.block.ftl.v1.VerbService.List:input_type -> xyz.block.ftl.v1.ListRequest 0, // 13: xyz.block.ftl.v1.DevelService.Ping:input_type -> xyz.block.ftl.v1.PingRequest - 9, // 14: xyz.block.ftl.v1.DevelService.SyncSchema:input_type -> xyz.block.ftl.v1.SyncSchemaRequest - 0, // 15: xyz.block.ftl.v1.BackplaneService.Ping:input_type -> xyz.block.ftl.v1.PingRequest - 11, // 16: xyz.block.ftl.v1.BackplaneService.GetArtefactDiffs:input_type -> xyz.block.ftl.v1.GetArtefactDiffsRequest - 13, // 17: xyz.block.ftl.v1.BackplaneService.UploadArtefact:input_type -> xyz.block.ftl.v1.UploadArtefactRequest - 1, // 18: xyz.block.ftl.v1.VerbService.Ping:output_type -> xyz.block.ftl.v1.PingResponse - 4, // 19: xyz.block.ftl.v1.VerbService.Call:output_type -> xyz.block.ftl.v1.CallResponse - 8, // 20: xyz.block.ftl.v1.VerbService.Send:output_type -> xyz.block.ftl.v1.SendResponse - 6, // 21: xyz.block.ftl.v1.VerbService.List:output_type -> xyz.block.ftl.v1.ListResponse - 1, // 22: xyz.block.ftl.v1.DevelService.Ping:output_type -> xyz.block.ftl.v1.PingResponse - 10, // 23: xyz.block.ftl.v1.DevelService.SyncSchema:output_type -> xyz.block.ftl.v1.SyncSchemaResponse - 1, // 24: xyz.block.ftl.v1.BackplaneService.Ping:output_type -> xyz.block.ftl.v1.PingResponse - 12, // 25: xyz.block.ftl.v1.BackplaneService.GetArtefactDiffs:output_type -> xyz.block.ftl.v1.GetArtefactDiffsResponse - 14, // 26: xyz.block.ftl.v1.BackplaneService.UploadArtefact:output_type -> xyz.block.ftl.v1.UploadArtefactResponse - 18, // [18:27] is the sub-list for method output_type - 9, // [9:18] is the sub-list for method input_type + 9, // 14: xyz.block.ftl.v1.DevelService.PushSchema:input_type -> xyz.block.ftl.v1.PushSchemaRequest + 11, // 15: xyz.block.ftl.v1.DevelService.PullSchema:input_type -> xyz.block.ftl.v1.PullSchemaRequest + 0, // 16: xyz.block.ftl.v1.BackplaneService.Ping:input_type -> xyz.block.ftl.v1.PingRequest + 13, // 17: xyz.block.ftl.v1.BackplaneService.GetArtefactDiffs:input_type -> xyz.block.ftl.v1.GetArtefactDiffsRequest + 15, // 18: xyz.block.ftl.v1.BackplaneService.UploadArtefact:input_type -> xyz.block.ftl.v1.UploadArtefactRequest + 1, // 19: xyz.block.ftl.v1.VerbService.Ping:output_type -> xyz.block.ftl.v1.PingResponse + 4, // 20: xyz.block.ftl.v1.VerbService.Call:output_type -> xyz.block.ftl.v1.CallResponse + 8, // 21: xyz.block.ftl.v1.VerbService.Send:output_type -> xyz.block.ftl.v1.SendResponse + 6, // 22: xyz.block.ftl.v1.VerbService.List:output_type -> xyz.block.ftl.v1.ListResponse + 1, // 23: xyz.block.ftl.v1.DevelService.Ping:output_type -> xyz.block.ftl.v1.PingResponse + 10, // 24: xyz.block.ftl.v1.DevelService.PushSchema:output_type -> xyz.block.ftl.v1.PushSchemaResponse + 12, // 25: xyz.block.ftl.v1.DevelService.PullSchema:output_type -> xyz.block.ftl.v1.PullSchemaResponse + 1, // 26: xyz.block.ftl.v1.BackplaneService.Ping:output_type -> xyz.block.ftl.v1.PingResponse + 14, // 27: xyz.block.ftl.v1.BackplaneService.GetArtefactDiffs:output_type -> xyz.block.ftl.v1.GetArtefactDiffsResponse + 16, // 28: xyz.block.ftl.v1.BackplaneService.UploadArtefact:output_type -> xyz.block.ftl.v1.UploadArtefactResponse + 19, // [19:29] is the sub-list for method output_type + 9, // [9:19] is the sub-list for method input_type 9, // [9:9] is the sub-list for extension type_name 9, // [9:9] is the sub-list for extension extendee 0, // [0:9] is the sub-list for field type_name @@ -1202,7 +1291,7 @@ func file_xyz_block_ftl_v1_ftl_proto_init() { } } file_xyz_block_ftl_v1_ftl_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncSchemaRequest); i { + switch v := v.(*PushSchemaRequest); i { case 0: return &v.state case 1: @@ -1214,7 +1303,7 @@ func file_xyz_block_ftl_v1_ftl_proto_init() { } } file_xyz_block_ftl_v1_ftl_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SyncSchemaResponse); i { + switch v := v.(*PushSchemaResponse); i { case 0: return &v.state case 1: @@ -1226,7 +1315,7 @@ func file_xyz_block_ftl_v1_ftl_proto_init() { } } file_xyz_block_ftl_v1_ftl_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetArtefactDiffsRequest); i { + switch v := v.(*PullSchemaRequest); i { case 0: return &v.state case 1: @@ -1238,7 +1327,7 @@ func file_xyz_block_ftl_v1_ftl_proto_init() { } } file_xyz_block_ftl_v1_ftl_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetArtefactDiffsResponse); i { + switch v := v.(*PullSchemaResponse); i { case 0: return &v.state case 1: @@ -1250,7 +1339,7 @@ func file_xyz_block_ftl_v1_ftl_proto_init() { } } file_xyz_block_ftl_v1_ftl_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UploadArtefactRequest); i { + switch v := v.(*GetArtefactDiffsRequest); i { case 0: return &v.state case 1: @@ -1262,7 +1351,7 @@ func file_xyz_block_ftl_v1_ftl_proto_init() { } } file_xyz_block_ftl_v1_ftl_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UploadArtefactResponse); i { + switch v := v.(*GetArtefactDiffsResponse); i { case 0: return &v.state case 1: @@ -1274,7 +1363,7 @@ func file_xyz_block_ftl_v1_ftl_proto_init() { } } file_xyz_block_ftl_v1_ftl_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Metadata_Pair); i { + switch v := v.(*UploadArtefactRequest); i { case 0: return &v.state case 1: @@ -1286,6 +1375,30 @@ func file_xyz_block_ftl_v1_ftl_proto_init() { } } file_xyz_block_ftl_v1_ftl_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UploadArtefactResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_xyz_block_ftl_v1_ftl_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Metadata_Pair); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_xyz_block_ftl_v1_ftl_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CallResponse_Error); i { case 0: return &v.state @@ -1308,7 +1421,7 @@ func file_xyz_block_ftl_v1_ftl_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_xyz_block_ftl_v1_ftl_proto_rawDesc, NumEnums: 0, - NumMessages: 17, + NumMessages: 19, NumExtensions: 0, NumServices: 3, }, diff --git a/protos/xyz/block/ftl/v1/ftl.proto b/protos/xyz/block/ftl/v1/ftl.proto index a073a46656..bafe90abc5 100644 --- a/protos/xyz/block/ftl/v1/ftl.proto +++ b/protos/xyz/block/ftl/v1/ftl.proto @@ -64,10 +64,13 @@ service VerbService { rpc List(ListRequest) returns (ListResponse); } -message SyncSchemaRequest { +message PushSchemaRequest { schema.Module schema = 1; } -message SyncSchemaResponse { +message PushSchemaResponse {} + +message PullSchemaRequest {} +message PullSchemaResponse { schema.Module schema = 1; // If true, there are more schema changes immediately following this one. // If false, there still may be more schema changes in the future. @@ -83,10 +86,11 @@ service DevelService { // Ping service for readiness. rpc Ping(PingRequest) returns (PingResponse); - // Sync schema changes to and from the service. - // - // Each request and response contains the schema for a single module. - rpc SyncSchema(stream SyncSchemaRequest) returns (stream SyncSchemaResponse); + // Push schema changes to the server. + rpc PushSchema(stream PushSchemaRequest) returns (PushSchemaResponse); + + // Pull schema changes from the server. + rpc PullSchema(PullSchemaRequest) returns (stream PullSchemaResponse); } message GetArtefactDiffsRequest { diff --git a/protos/xyz/block/ftl/v1/ftl_grpc.pb.go b/protos/xyz/block/ftl/v1/ftl_grpc.pb.go deleted file mode 100644 index 841775b344..0000000000 --- a/protos/xyz/block/ftl/v1/ftl_grpc.pb.go +++ /dev/null @@ -1,573 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. - -package ftlv1 - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -// VerbServiceClient is the client API for VerbService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type VerbServiceClient interface { - // Ping service for readiness. - Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) - // Issue a synchronous call to a Verb. - Call(ctx context.Context, in *CallRequest, opts ...grpc.CallOption) (*CallResponse, error) - // Issue an asynchronous call to a Verb. - Send(ctx context.Context, in *SendRequest, opts ...grpc.CallOption) (*SendResponse, error) - // List the available Verbs. - List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) -} - -type verbServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewVerbServiceClient(cc grpc.ClientConnInterface) VerbServiceClient { - return &verbServiceClient{cc} -} - -func (c *verbServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { - out := new(PingResponse) - err := c.cc.Invoke(ctx, "/xyz.block.ftl.v1.VerbService/Ping", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *verbServiceClient) Call(ctx context.Context, in *CallRequest, opts ...grpc.CallOption) (*CallResponse, error) { - out := new(CallResponse) - err := c.cc.Invoke(ctx, "/xyz.block.ftl.v1.VerbService/Call", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *verbServiceClient) Send(ctx context.Context, in *SendRequest, opts ...grpc.CallOption) (*SendResponse, error) { - out := new(SendResponse) - err := c.cc.Invoke(ctx, "/xyz.block.ftl.v1.VerbService/Send", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *verbServiceClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) { - out := new(ListResponse) - err := c.cc.Invoke(ctx, "/xyz.block.ftl.v1.VerbService/List", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// VerbServiceServer is the server API for VerbService service. -// All implementations should embed UnimplementedVerbServiceServer -// for forward compatibility -type VerbServiceServer interface { - // Ping service for readiness. - Ping(context.Context, *PingRequest) (*PingResponse, error) - // Issue a synchronous call to a Verb. - Call(context.Context, *CallRequest) (*CallResponse, error) - // Issue an asynchronous call to a Verb. - Send(context.Context, *SendRequest) (*SendResponse, error) - // List the available Verbs. - List(context.Context, *ListRequest) (*ListResponse, error) -} - -// UnimplementedVerbServiceServer should be embedded to have forward compatible implementations. -type UnimplementedVerbServiceServer struct { -} - -func (UnimplementedVerbServiceServer) Ping(context.Context, *PingRequest) (*PingResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") -} -func (UnimplementedVerbServiceServer) Call(context.Context, *CallRequest) (*CallResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Call not implemented") -} -func (UnimplementedVerbServiceServer) Send(context.Context, *SendRequest) (*SendResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Send not implemented") -} -func (UnimplementedVerbServiceServer) List(context.Context, *ListRequest) (*ListResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method List not implemented") -} - -// UnsafeVerbServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to VerbServiceServer will -// result in compilation errors. -type UnsafeVerbServiceServer interface { - mustEmbedUnimplementedVerbServiceServer() -} - -func RegisterVerbServiceServer(s grpc.ServiceRegistrar, srv VerbServiceServer) { - s.RegisterService(&VerbService_ServiceDesc, srv) -} - -func _VerbService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PingRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(VerbServiceServer).Ping(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/xyz.block.ftl.v1.VerbService/Ping", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(VerbServiceServer).Ping(ctx, req.(*PingRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _VerbService_Call_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CallRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(VerbServiceServer).Call(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/xyz.block.ftl.v1.VerbService/Call", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(VerbServiceServer).Call(ctx, req.(*CallRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _VerbService_Send_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SendRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(VerbServiceServer).Send(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/xyz.block.ftl.v1.VerbService/Send", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(VerbServiceServer).Send(ctx, req.(*SendRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _VerbService_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(VerbServiceServer).List(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/xyz.block.ftl.v1.VerbService/List", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(VerbServiceServer).List(ctx, req.(*ListRequest)) - } - return interceptor(ctx, in, info, handler) -} - -// VerbService_ServiceDesc is the grpc.ServiceDesc for VerbService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var VerbService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "xyz.block.ftl.v1.VerbService", - HandlerType: (*VerbServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Ping", - Handler: _VerbService_Ping_Handler, - }, - { - MethodName: "Call", - Handler: _VerbService_Call_Handler, - }, - { - MethodName: "Send", - Handler: _VerbService_Send_Handler, - }, - { - MethodName: "List", - Handler: _VerbService_List_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "xyz/block/ftl/v1/ftl.proto", -} - -// DevelServiceClient is the client API for DevelService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type DevelServiceClient interface { - // Ping service for readiness. - Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) - // Sync schema changes to and from the service. - // - // Each request and response contains the schema for a single module. - SyncSchema(ctx context.Context, opts ...grpc.CallOption) (DevelService_SyncSchemaClient, error) -} - -type develServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewDevelServiceClient(cc grpc.ClientConnInterface) DevelServiceClient { - return &develServiceClient{cc} -} - -func (c *develServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { - out := new(PingResponse) - err := c.cc.Invoke(ctx, "/xyz.block.ftl.v1.DevelService/Ping", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *develServiceClient) SyncSchema(ctx context.Context, opts ...grpc.CallOption) (DevelService_SyncSchemaClient, error) { - stream, err := c.cc.NewStream(ctx, &DevelService_ServiceDesc.Streams[0], "/xyz.block.ftl.v1.DevelService/SyncSchema", opts...) - if err != nil { - return nil, err - } - x := &develServiceSyncSchemaClient{stream} - return x, nil -} - -type DevelService_SyncSchemaClient interface { - Send(*SyncSchemaRequest) error - Recv() (*SyncSchemaResponse, error) - grpc.ClientStream -} - -type develServiceSyncSchemaClient struct { - grpc.ClientStream -} - -func (x *develServiceSyncSchemaClient) Send(m *SyncSchemaRequest) error { - return x.ClientStream.SendMsg(m) -} - -func (x *develServiceSyncSchemaClient) Recv() (*SyncSchemaResponse, error) { - m := new(SyncSchemaResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -// DevelServiceServer is the server API for DevelService service. -// All implementations should embed UnimplementedDevelServiceServer -// for forward compatibility -type DevelServiceServer interface { - // Ping service for readiness. - Ping(context.Context, *PingRequest) (*PingResponse, error) - // Sync schema changes to and from the service. - // - // Each request and response contains the schema for a single module. - SyncSchema(DevelService_SyncSchemaServer) error -} - -// UnimplementedDevelServiceServer should be embedded to have forward compatible implementations. -type UnimplementedDevelServiceServer struct { -} - -func (UnimplementedDevelServiceServer) Ping(context.Context, *PingRequest) (*PingResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") -} -func (UnimplementedDevelServiceServer) SyncSchema(DevelService_SyncSchemaServer) error { - return status.Errorf(codes.Unimplemented, "method SyncSchema not implemented") -} - -// UnsafeDevelServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to DevelServiceServer will -// result in compilation errors. -type UnsafeDevelServiceServer interface { - mustEmbedUnimplementedDevelServiceServer() -} - -func RegisterDevelServiceServer(s grpc.ServiceRegistrar, srv DevelServiceServer) { - s.RegisterService(&DevelService_ServiceDesc, srv) -} - -func _DevelService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PingRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(DevelServiceServer).Ping(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/xyz.block.ftl.v1.DevelService/Ping", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(DevelServiceServer).Ping(ctx, req.(*PingRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _DevelService_SyncSchema_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(DevelServiceServer).SyncSchema(&develServiceSyncSchemaServer{stream}) -} - -type DevelService_SyncSchemaServer interface { - Send(*SyncSchemaResponse) error - Recv() (*SyncSchemaRequest, error) - grpc.ServerStream -} - -type develServiceSyncSchemaServer struct { - grpc.ServerStream -} - -func (x *develServiceSyncSchemaServer) Send(m *SyncSchemaResponse) error { - return x.ServerStream.SendMsg(m) -} - -func (x *develServiceSyncSchemaServer) Recv() (*SyncSchemaRequest, error) { - m := new(SyncSchemaRequest) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -// DevelService_ServiceDesc is the grpc.ServiceDesc for DevelService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var DevelService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "xyz.block.ftl.v1.DevelService", - HandlerType: (*DevelServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Ping", - Handler: _DevelService_Ping_Handler, - }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "SyncSchema", - Handler: _DevelService_SyncSchema_Handler, - ServerStreams: true, - ClientStreams: true, - }, - }, - Metadata: "xyz/block/ftl/v1/ftl.proto", -} - -// BackplaneServiceClient is the client API for BackplaneService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type BackplaneServiceClient interface { - // Ping service for readiness. - Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) - // Get list of artefacts that differ between the server and client. - GetArtefactDiffs(ctx context.Context, in *GetArtefactDiffsRequest, opts ...grpc.CallOption) (*GetArtefactDiffsResponse, error) - // Upload artefacts to the server. - UploadArtefact(ctx context.Context, opts ...grpc.CallOption) (BackplaneService_UploadArtefactClient, error) -} - -type backplaneServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewBackplaneServiceClient(cc grpc.ClientConnInterface) BackplaneServiceClient { - return &backplaneServiceClient{cc} -} - -func (c *backplaneServiceClient) Ping(ctx context.Context, in *PingRequest, opts ...grpc.CallOption) (*PingResponse, error) { - out := new(PingResponse) - err := c.cc.Invoke(ctx, "/xyz.block.ftl.v1.BackplaneService/Ping", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *backplaneServiceClient) GetArtefactDiffs(ctx context.Context, in *GetArtefactDiffsRequest, opts ...grpc.CallOption) (*GetArtefactDiffsResponse, error) { - out := new(GetArtefactDiffsResponse) - err := c.cc.Invoke(ctx, "/xyz.block.ftl.v1.BackplaneService/GetArtefactDiffs", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *backplaneServiceClient) UploadArtefact(ctx context.Context, opts ...grpc.CallOption) (BackplaneService_UploadArtefactClient, error) { - stream, err := c.cc.NewStream(ctx, &BackplaneService_ServiceDesc.Streams[0], "/xyz.block.ftl.v1.BackplaneService/UploadArtefact", opts...) - if err != nil { - return nil, err - } - x := &backplaneServiceUploadArtefactClient{stream} - return x, nil -} - -type BackplaneService_UploadArtefactClient interface { - Send(*UploadArtefactRequest) error - CloseAndRecv() (*UploadArtefactResponse, error) - grpc.ClientStream -} - -type backplaneServiceUploadArtefactClient struct { - grpc.ClientStream -} - -func (x *backplaneServiceUploadArtefactClient) Send(m *UploadArtefactRequest) error { - return x.ClientStream.SendMsg(m) -} - -func (x *backplaneServiceUploadArtefactClient) CloseAndRecv() (*UploadArtefactResponse, error) { - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - m := new(UploadArtefactResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -// BackplaneServiceServer is the server API for BackplaneService service. -// All implementations should embed UnimplementedBackplaneServiceServer -// for forward compatibility -type BackplaneServiceServer interface { - // Ping service for readiness. - Ping(context.Context, *PingRequest) (*PingResponse, error) - // Get list of artefacts that differ between the server and client. - GetArtefactDiffs(context.Context, *GetArtefactDiffsRequest) (*GetArtefactDiffsResponse, error) - // Upload artefacts to the server. - UploadArtefact(BackplaneService_UploadArtefactServer) error -} - -// UnimplementedBackplaneServiceServer should be embedded to have forward compatible implementations. -type UnimplementedBackplaneServiceServer struct { -} - -func (UnimplementedBackplaneServiceServer) Ping(context.Context, *PingRequest) (*PingResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") -} -func (UnimplementedBackplaneServiceServer) GetArtefactDiffs(context.Context, *GetArtefactDiffsRequest) (*GetArtefactDiffsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetArtefactDiffs not implemented") -} -func (UnimplementedBackplaneServiceServer) UploadArtefact(BackplaneService_UploadArtefactServer) error { - return status.Errorf(codes.Unimplemented, "method UploadArtefact not implemented") -} - -// UnsafeBackplaneServiceServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to BackplaneServiceServer will -// result in compilation errors. -type UnsafeBackplaneServiceServer interface { - mustEmbedUnimplementedBackplaneServiceServer() -} - -func RegisterBackplaneServiceServer(s grpc.ServiceRegistrar, srv BackplaneServiceServer) { - s.RegisterService(&BackplaneService_ServiceDesc, srv) -} - -func _BackplaneService_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PingRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(BackplaneServiceServer).Ping(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/xyz.block.ftl.v1.BackplaneService/Ping", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BackplaneServiceServer).Ping(ctx, req.(*PingRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _BackplaneService_GetArtefactDiffs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetArtefactDiffsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(BackplaneServiceServer).GetArtefactDiffs(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/xyz.block.ftl.v1.BackplaneService/GetArtefactDiffs", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BackplaneServiceServer).GetArtefactDiffs(ctx, req.(*GetArtefactDiffsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _BackplaneService_UploadArtefact_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(BackplaneServiceServer).UploadArtefact(&backplaneServiceUploadArtefactServer{stream}) -} - -type BackplaneService_UploadArtefactServer interface { - SendAndClose(*UploadArtefactResponse) error - Recv() (*UploadArtefactRequest, error) - grpc.ServerStream -} - -type backplaneServiceUploadArtefactServer struct { - grpc.ServerStream -} - -func (x *backplaneServiceUploadArtefactServer) SendAndClose(m *UploadArtefactResponse) error { - return x.ServerStream.SendMsg(m) -} - -func (x *backplaneServiceUploadArtefactServer) Recv() (*UploadArtefactRequest, error) { - m := new(UploadArtefactRequest) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -// BackplaneService_ServiceDesc is the grpc.ServiceDesc for BackplaneService service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var BackplaneService_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "xyz.block.ftl.v1.BackplaneService", - HandlerType: (*BackplaneServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Ping", - Handler: _BackplaneService_Ping_Handler, - }, - { - MethodName: "GetArtefactDiffs", - Handler: _BackplaneService_GetArtefactDiffs_Handler, - }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "UploadArtefact", - Handler: _BackplaneService_UploadArtefact_Handler, - ClientStreams: true, - }, - }, - Metadata: "xyz/block/ftl/v1/ftl.proto", -} diff --git a/protos/xyz/block/ftl/v1/ftlv1connect/ftl.connect.go b/protos/xyz/block/ftl/v1/ftlv1connect/ftl.connect.go new file mode 100644 index 0000000000..bb0f466e01 --- /dev/null +++ b/protos/xyz/block/ftl/v1/ftlv1connect/ftl.connect.go @@ -0,0 +1,384 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: xyz/block/ftl/v1/ftl.proto + +package ftlv1connect + +import ( + context "context" + errors "errors" + v1 "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1" + connect_go "github.com/bufbuild/connect-go" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect_go.IsAtLeastVersion0_1_0 + +const ( + // VerbServiceName is the fully-qualified name of the VerbService service. + VerbServiceName = "xyz.block.ftl.v1.VerbService" + // DevelServiceName is the fully-qualified name of the DevelService service. + DevelServiceName = "xyz.block.ftl.v1.DevelService" + // BackplaneServiceName is the fully-qualified name of the BackplaneService service. + BackplaneServiceName = "xyz.block.ftl.v1.BackplaneService" +) + +// VerbServiceClient is a client for the xyz.block.ftl.v1.VerbService service. +type VerbServiceClient interface { + // Ping service for readiness. + Ping(context.Context, *connect_go.Request[v1.PingRequest]) (*connect_go.Response[v1.PingResponse], error) + // Issue a synchronous call to a Verb. + Call(context.Context, *connect_go.Request[v1.CallRequest]) (*connect_go.Response[v1.CallResponse], error) + // Issue an asynchronous call to a Verb. + Send(context.Context, *connect_go.Request[v1.SendRequest]) (*connect_go.Response[v1.SendResponse], error) + // List the available Verbs. + List(context.Context, *connect_go.Request[v1.ListRequest]) (*connect_go.Response[v1.ListResponse], error) +} + +// NewVerbServiceClient constructs a client for the xyz.block.ftl.v1.VerbService service. By +// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, +// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the +// connect.WithGRPC() or connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewVerbServiceClient(httpClient connect_go.HTTPClient, baseURL string, opts ...connect_go.ClientOption) VerbServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + return &verbServiceClient{ + ping: connect_go.NewClient[v1.PingRequest, v1.PingResponse]( + httpClient, + baseURL+"/xyz.block.ftl.v1.VerbService/Ping", + opts..., + ), + call: connect_go.NewClient[v1.CallRequest, v1.CallResponse]( + httpClient, + baseURL+"/xyz.block.ftl.v1.VerbService/Call", + opts..., + ), + send: connect_go.NewClient[v1.SendRequest, v1.SendResponse]( + httpClient, + baseURL+"/xyz.block.ftl.v1.VerbService/Send", + opts..., + ), + list: connect_go.NewClient[v1.ListRequest, v1.ListResponse]( + httpClient, + baseURL+"/xyz.block.ftl.v1.VerbService/List", + opts..., + ), + } +} + +// verbServiceClient implements VerbServiceClient. +type verbServiceClient struct { + ping *connect_go.Client[v1.PingRequest, v1.PingResponse] + call *connect_go.Client[v1.CallRequest, v1.CallResponse] + send *connect_go.Client[v1.SendRequest, v1.SendResponse] + list *connect_go.Client[v1.ListRequest, v1.ListResponse] +} + +// Ping calls xyz.block.ftl.v1.VerbService.Ping. +func (c *verbServiceClient) Ping(ctx context.Context, req *connect_go.Request[v1.PingRequest]) (*connect_go.Response[v1.PingResponse], error) { + return c.ping.CallUnary(ctx, req) +} + +// Call calls xyz.block.ftl.v1.VerbService.Call. +func (c *verbServiceClient) Call(ctx context.Context, req *connect_go.Request[v1.CallRequest]) (*connect_go.Response[v1.CallResponse], error) { + return c.call.CallUnary(ctx, req) +} + +// Send calls xyz.block.ftl.v1.VerbService.Send. +func (c *verbServiceClient) Send(ctx context.Context, req *connect_go.Request[v1.SendRequest]) (*connect_go.Response[v1.SendResponse], error) { + return c.send.CallUnary(ctx, req) +} + +// List calls xyz.block.ftl.v1.VerbService.List. +func (c *verbServiceClient) List(ctx context.Context, req *connect_go.Request[v1.ListRequest]) (*connect_go.Response[v1.ListResponse], error) { + return c.list.CallUnary(ctx, req) +} + +// VerbServiceHandler is an implementation of the xyz.block.ftl.v1.VerbService service. +type VerbServiceHandler interface { + // Ping service for readiness. + Ping(context.Context, *connect_go.Request[v1.PingRequest]) (*connect_go.Response[v1.PingResponse], error) + // Issue a synchronous call to a Verb. + Call(context.Context, *connect_go.Request[v1.CallRequest]) (*connect_go.Response[v1.CallResponse], error) + // Issue an asynchronous call to a Verb. + Send(context.Context, *connect_go.Request[v1.SendRequest]) (*connect_go.Response[v1.SendResponse], error) + // List the available Verbs. + List(context.Context, *connect_go.Request[v1.ListRequest]) (*connect_go.Response[v1.ListResponse], error) +} + +// NewVerbServiceHandler builds an HTTP handler from the service implementation. It returns the path +// on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewVerbServiceHandler(svc VerbServiceHandler, opts ...connect_go.HandlerOption) (string, http.Handler) { + mux := http.NewServeMux() + mux.Handle("/xyz.block.ftl.v1.VerbService/Ping", connect_go.NewUnaryHandler( + "/xyz.block.ftl.v1.VerbService/Ping", + svc.Ping, + opts..., + )) + mux.Handle("/xyz.block.ftl.v1.VerbService/Call", connect_go.NewUnaryHandler( + "/xyz.block.ftl.v1.VerbService/Call", + svc.Call, + opts..., + )) + mux.Handle("/xyz.block.ftl.v1.VerbService/Send", connect_go.NewUnaryHandler( + "/xyz.block.ftl.v1.VerbService/Send", + svc.Send, + opts..., + )) + mux.Handle("/xyz.block.ftl.v1.VerbService/List", connect_go.NewUnaryHandler( + "/xyz.block.ftl.v1.VerbService/List", + svc.List, + opts..., + )) + return "/xyz.block.ftl.v1.VerbService/", mux +} + +// UnimplementedVerbServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedVerbServiceHandler struct{} + +func (UnimplementedVerbServiceHandler) Ping(context.Context, *connect_go.Request[v1.PingRequest]) (*connect_go.Response[v1.PingResponse], error) { + return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("xyz.block.ftl.v1.VerbService.Ping is not implemented")) +} + +func (UnimplementedVerbServiceHandler) Call(context.Context, *connect_go.Request[v1.CallRequest]) (*connect_go.Response[v1.CallResponse], error) { + return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("xyz.block.ftl.v1.VerbService.Call is not implemented")) +} + +func (UnimplementedVerbServiceHandler) Send(context.Context, *connect_go.Request[v1.SendRequest]) (*connect_go.Response[v1.SendResponse], error) { + return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("xyz.block.ftl.v1.VerbService.Send is not implemented")) +} + +func (UnimplementedVerbServiceHandler) List(context.Context, *connect_go.Request[v1.ListRequest]) (*connect_go.Response[v1.ListResponse], error) { + return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("xyz.block.ftl.v1.VerbService.List is not implemented")) +} + +// DevelServiceClient is a client for the xyz.block.ftl.v1.DevelService service. +type DevelServiceClient interface { + // Ping service for readiness. + Ping(context.Context, *connect_go.Request[v1.PingRequest]) (*connect_go.Response[v1.PingResponse], error) + // Push schema changes to the server. + PushSchema(context.Context) *connect_go.ClientStreamForClient[v1.PushSchemaRequest, v1.PushSchemaResponse] + // Pull schema changes from the server. + PullSchema(context.Context, *connect_go.Request[v1.PullSchemaRequest]) (*connect_go.ServerStreamForClient[v1.PullSchemaResponse], error) +} + +// NewDevelServiceClient constructs a client for the xyz.block.ftl.v1.DevelService service. By +// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, +// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the +// connect.WithGRPC() or connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewDevelServiceClient(httpClient connect_go.HTTPClient, baseURL string, opts ...connect_go.ClientOption) DevelServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + return &develServiceClient{ + ping: connect_go.NewClient[v1.PingRequest, v1.PingResponse]( + httpClient, + baseURL+"/xyz.block.ftl.v1.DevelService/Ping", + opts..., + ), + pushSchema: connect_go.NewClient[v1.PushSchemaRequest, v1.PushSchemaResponse]( + httpClient, + baseURL+"/xyz.block.ftl.v1.DevelService/PushSchema", + opts..., + ), + pullSchema: connect_go.NewClient[v1.PullSchemaRequest, v1.PullSchemaResponse]( + httpClient, + baseURL+"/xyz.block.ftl.v1.DevelService/PullSchema", + opts..., + ), + } +} + +// develServiceClient implements DevelServiceClient. +type develServiceClient struct { + ping *connect_go.Client[v1.PingRequest, v1.PingResponse] + pushSchema *connect_go.Client[v1.PushSchemaRequest, v1.PushSchemaResponse] + pullSchema *connect_go.Client[v1.PullSchemaRequest, v1.PullSchemaResponse] +} + +// Ping calls xyz.block.ftl.v1.DevelService.Ping. +func (c *develServiceClient) Ping(ctx context.Context, req *connect_go.Request[v1.PingRequest]) (*connect_go.Response[v1.PingResponse], error) { + return c.ping.CallUnary(ctx, req) +} + +// PushSchema calls xyz.block.ftl.v1.DevelService.PushSchema. +func (c *develServiceClient) PushSchema(ctx context.Context) *connect_go.ClientStreamForClient[v1.PushSchemaRequest, v1.PushSchemaResponse] { + return c.pushSchema.CallClientStream(ctx) +} + +// PullSchema calls xyz.block.ftl.v1.DevelService.PullSchema. +func (c *develServiceClient) PullSchema(ctx context.Context, req *connect_go.Request[v1.PullSchemaRequest]) (*connect_go.ServerStreamForClient[v1.PullSchemaResponse], error) { + return c.pullSchema.CallServerStream(ctx, req) +} + +// DevelServiceHandler is an implementation of the xyz.block.ftl.v1.DevelService service. +type DevelServiceHandler interface { + // Ping service for readiness. + Ping(context.Context, *connect_go.Request[v1.PingRequest]) (*connect_go.Response[v1.PingResponse], error) + // Push schema changes to the server. + PushSchema(context.Context, *connect_go.ClientStream[v1.PushSchemaRequest]) (*connect_go.Response[v1.PushSchemaResponse], error) + // Pull schema changes from the server. + PullSchema(context.Context, *connect_go.Request[v1.PullSchemaRequest], *connect_go.ServerStream[v1.PullSchemaResponse]) error +} + +// NewDevelServiceHandler builds an HTTP handler from the service implementation. It returns the +// path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewDevelServiceHandler(svc DevelServiceHandler, opts ...connect_go.HandlerOption) (string, http.Handler) { + mux := http.NewServeMux() + mux.Handle("/xyz.block.ftl.v1.DevelService/Ping", connect_go.NewUnaryHandler( + "/xyz.block.ftl.v1.DevelService/Ping", + svc.Ping, + opts..., + )) + mux.Handle("/xyz.block.ftl.v1.DevelService/PushSchema", connect_go.NewClientStreamHandler( + "/xyz.block.ftl.v1.DevelService/PushSchema", + svc.PushSchema, + opts..., + )) + mux.Handle("/xyz.block.ftl.v1.DevelService/PullSchema", connect_go.NewServerStreamHandler( + "/xyz.block.ftl.v1.DevelService/PullSchema", + svc.PullSchema, + opts..., + )) + return "/xyz.block.ftl.v1.DevelService/", mux +} + +// UnimplementedDevelServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedDevelServiceHandler struct{} + +func (UnimplementedDevelServiceHandler) Ping(context.Context, *connect_go.Request[v1.PingRequest]) (*connect_go.Response[v1.PingResponse], error) { + return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("xyz.block.ftl.v1.DevelService.Ping is not implemented")) +} + +func (UnimplementedDevelServiceHandler) PushSchema(context.Context, *connect_go.ClientStream[v1.PushSchemaRequest]) (*connect_go.Response[v1.PushSchemaResponse], error) { + return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("xyz.block.ftl.v1.DevelService.PushSchema is not implemented")) +} + +func (UnimplementedDevelServiceHandler) PullSchema(context.Context, *connect_go.Request[v1.PullSchemaRequest], *connect_go.ServerStream[v1.PullSchemaResponse]) error { + return connect_go.NewError(connect_go.CodeUnimplemented, errors.New("xyz.block.ftl.v1.DevelService.PullSchema is not implemented")) +} + +// BackplaneServiceClient is a client for the xyz.block.ftl.v1.BackplaneService service. +type BackplaneServiceClient interface { + // Ping service for readiness. + Ping(context.Context, *connect_go.Request[v1.PingRequest]) (*connect_go.Response[v1.PingResponse], error) + // Get list of artefacts that differ between the server and client. + GetArtefactDiffs(context.Context, *connect_go.Request[v1.GetArtefactDiffsRequest]) (*connect_go.Response[v1.GetArtefactDiffsResponse], error) + // Upload artefacts to the server. + UploadArtefact(context.Context) *connect_go.ClientStreamForClient[v1.UploadArtefactRequest, v1.UploadArtefactResponse] +} + +// NewBackplaneServiceClient constructs a client for the xyz.block.ftl.v1.BackplaneService service. +// By default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped +// responses, and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the +// connect.WithGRPC() or connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewBackplaneServiceClient(httpClient connect_go.HTTPClient, baseURL string, opts ...connect_go.ClientOption) BackplaneServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + return &backplaneServiceClient{ + ping: connect_go.NewClient[v1.PingRequest, v1.PingResponse]( + httpClient, + baseURL+"/xyz.block.ftl.v1.BackplaneService/Ping", + opts..., + ), + getArtefactDiffs: connect_go.NewClient[v1.GetArtefactDiffsRequest, v1.GetArtefactDiffsResponse]( + httpClient, + baseURL+"/xyz.block.ftl.v1.BackplaneService/GetArtefactDiffs", + opts..., + ), + uploadArtefact: connect_go.NewClient[v1.UploadArtefactRequest, v1.UploadArtefactResponse]( + httpClient, + baseURL+"/xyz.block.ftl.v1.BackplaneService/UploadArtefact", + opts..., + ), + } +} + +// backplaneServiceClient implements BackplaneServiceClient. +type backplaneServiceClient struct { + ping *connect_go.Client[v1.PingRequest, v1.PingResponse] + getArtefactDiffs *connect_go.Client[v1.GetArtefactDiffsRequest, v1.GetArtefactDiffsResponse] + uploadArtefact *connect_go.Client[v1.UploadArtefactRequest, v1.UploadArtefactResponse] +} + +// Ping calls xyz.block.ftl.v1.BackplaneService.Ping. +func (c *backplaneServiceClient) Ping(ctx context.Context, req *connect_go.Request[v1.PingRequest]) (*connect_go.Response[v1.PingResponse], error) { + return c.ping.CallUnary(ctx, req) +} + +// GetArtefactDiffs calls xyz.block.ftl.v1.BackplaneService.GetArtefactDiffs. +func (c *backplaneServiceClient) GetArtefactDiffs(ctx context.Context, req *connect_go.Request[v1.GetArtefactDiffsRequest]) (*connect_go.Response[v1.GetArtefactDiffsResponse], error) { + return c.getArtefactDiffs.CallUnary(ctx, req) +} + +// UploadArtefact calls xyz.block.ftl.v1.BackplaneService.UploadArtefact. +func (c *backplaneServiceClient) UploadArtefact(ctx context.Context) *connect_go.ClientStreamForClient[v1.UploadArtefactRequest, v1.UploadArtefactResponse] { + return c.uploadArtefact.CallClientStream(ctx) +} + +// BackplaneServiceHandler is an implementation of the xyz.block.ftl.v1.BackplaneService service. +type BackplaneServiceHandler interface { + // Ping service for readiness. + Ping(context.Context, *connect_go.Request[v1.PingRequest]) (*connect_go.Response[v1.PingResponse], error) + // Get list of artefacts that differ between the server and client. + GetArtefactDiffs(context.Context, *connect_go.Request[v1.GetArtefactDiffsRequest]) (*connect_go.Response[v1.GetArtefactDiffsResponse], error) + // Upload artefacts to the server. + UploadArtefact(context.Context, *connect_go.ClientStream[v1.UploadArtefactRequest]) (*connect_go.Response[v1.UploadArtefactResponse], error) +} + +// NewBackplaneServiceHandler builds an HTTP handler from the service implementation. It returns the +// path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewBackplaneServiceHandler(svc BackplaneServiceHandler, opts ...connect_go.HandlerOption) (string, http.Handler) { + mux := http.NewServeMux() + mux.Handle("/xyz.block.ftl.v1.BackplaneService/Ping", connect_go.NewUnaryHandler( + "/xyz.block.ftl.v1.BackplaneService/Ping", + svc.Ping, + opts..., + )) + mux.Handle("/xyz.block.ftl.v1.BackplaneService/GetArtefactDiffs", connect_go.NewUnaryHandler( + "/xyz.block.ftl.v1.BackplaneService/GetArtefactDiffs", + svc.GetArtefactDiffs, + opts..., + )) + mux.Handle("/xyz.block.ftl.v1.BackplaneService/UploadArtefact", connect_go.NewClientStreamHandler( + "/xyz.block.ftl.v1.BackplaneService/UploadArtefact", + svc.UploadArtefact, + opts..., + )) + return "/xyz.block.ftl.v1.BackplaneService/", mux +} + +// UnimplementedBackplaneServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedBackplaneServiceHandler struct{} + +func (UnimplementedBackplaneServiceHandler) Ping(context.Context, *connect_go.Request[v1.PingRequest]) (*connect_go.Response[v1.PingResponse], error) { + return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("xyz.block.ftl.v1.BackplaneService.Ping is not implemented")) +} + +func (UnimplementedBackplaneServiceHandler) GetArtefactDiffs(context.Context, *connect_go.Request[v1.GetArtefactDiffsRequest]) (*connect_go.Response[v1.GetArtefactDiffsResponse], error) { + return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("xyz.block.ftl.v1.BackplaneService.GetArtefactDiffs is not implemented")) +} + +func (UnimplementedBackplaneServiceHandler) UploadArtefact(context.Context, *connect_go.ClientStream[v1.UploadArtefactRequest]) (*connect_go.Response[v1.UploadArtefactResponse], error) { + return nil, connect_go.NewError(connect_go.CodeUnimplemented, errors.New("xyz.block.ftl.v1.BackplaneService.UploadArtefact is not implemented")) +} diff --git a/schema/protobuf.go b/schema/protobuf.go index 7cb270e094..40b5b94300 100644 --- a/schema/protobuf.go +++ b/schema/protobuf.go @@ -50,12 +50,6 @@ func reflectUnion[T any](union ...T) []reflect.Type { return out } -var unions = map[reflect.Type][]reflect.Type{ - reflect.TypeOf((*Type)(nil)).Elem(): reflectUnion(typeUnion...), - reflect.TypeOf((*Metadata)(nil)).Elem(): reflectUnion(metadataUnion...), - reflect.TypeOf((*Decl)(nil)).Elem(): reflectUnion(declUnion...), -} - func generateMessage(et reflect.Type, messages map[string]string) { et = indirect(et) if et.Kind() == reflect.Interface { diff --git a/schema/schema.go b/schema/schema.go index 5a06caf579..fadd4cab5d 100644 --- a/schema/schema.go +++ b/schema/schema.go @@ -3,6 +3,7 @@ package schema import ( "fmt" "io" + "reflect" "strings" "github.com/alecthomas/errors" @@ -15,6 +16,13 @@ var ( declUnion = []Decl{&Data{}, &Verb{}} typeUnion = []Type{&Int{}, &Float{}, &String{}, &Bool{}, &Time{}, &Array{}, &Map{}, &VerbRef{}, &DataRef{}} metadataUnion = []Metadata{&MetadataCalls{}} + + // Used by protobuf generation. + unions = map[reflect.Type][]reflect.Type{ + reflect.TypeOf((*Type)(nil)).Elem(): reflectUnion(typeUnion...), + reflect.TypeOf((*Metadata)(nil)).Elem(): reflectUnion(metadataUnion...), + reflect.TypeOf((*Decl)(nil)).Elem(): reflectUnion(declUnion...), + } ) // A Node in the schema grammar. diff --git a/scripts/autofmt b/scripts/autofmt index 645b486bd1..61420af3c1 100755 --- a/scripts/autofmt +++ b/scripts/autofmt @@ -15,6 +15,6 @@ gosimports -w --local github.com/TBD54566975/ftl $(go list -f '{{.Dir}}' ./...) buf format -w # Revert changes to generated files. -find protos -name '*.pb.go' -print0 | xargs -0 -r git checkout > /dev/null +find protos \( -name '*.pb.go' -o -name '*.connect.go' \) -print0 | xargs -0 -r git checkout > /dev/null git diff diff --git a/sdk-go/call.go b/sdk-go/call.go index ad61991a83..d68c0be08b 100644 --- a/sdk-go/call.go +++ b/sdk-go/call.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/alecthomas/errors" + "github.com/bufbuild/connect-go" "github.com/iancoleman/strcase" ftlv1 "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1" @@ -22,11 +23,11 @@ func Call[Req, Resp any](ctx context.Context, verb Verb[Req, Resp], req Req) (re if err != nil { return resp, errors.Wrapf(err, "%s: failed to marshal request", callee) } - cresp, err := client.Call(ctx, &ftlv1.CallRequest{Verb: callee.ToProto(), Body: reqData}) + cresp, err := client.Call(ctx, connect.NewRequest(&ftlv1.CallRequest{Verb: callee.ToProto(), Body: reqData})) if err != nil { return resp, errors.Wrapf(err, "%s: failed to call Verb", callee) } - switch cresp := cresp.Response.(type) { + switch cresp := cresp.Msg.Response.(type) { case *ftlv1.CallResponse_Error_: return resp, errors.Errorf("%s: %s", callee, cresp.Error.Message) diff --git a/sdk-go/context.go b/sdk-go/context.go index 115e1bb295..95cf40cc0c 100644 --- a/sdk-go/context.go +++ b/sdk-go/context.go @@ -3,29 +3,24 @@ package sdkgo import ( "context" - "github.com/alecthomas/errors" - + "github.com/TBD54566975/ftl/common/rpc" "github.com/TBD54566975/ftl/common/socket" - ftlv1 "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1" + "github.com/TBD54566975/ftl/protos/xyz/block/ftl/v1/ftlv1connect" ) type clientKey struct{} // ContextWithClient returns a context with an ftlv1.VerbServiceClient attached. -func ContextWithClient(ctx context.Context, endpoint socket.Socket) (context.Context, error) { - conn, err := socket.DialGRPC(ctx, endpoint) - if err != nil { - return nil, errors.WithStack(err) - } - client := ftlv1.NewVerbServiceClient(conn) - return context.WithValue(ctx, clientKey{}, client), nil +func ContextWithClient(ctx context.Context, endpoint socket.Socket) context.Context { + client := rpc.Dial(ftlv1connect.NewVerbServiceClient, endpoint.URL()) + return context.WithValue(ctx, clientKey{}, client) } // ClientFromContext returns the ftlv1.VerbServiceClient from the context, or panics. -func ClientFromContext(ctx context.Context) ftlv1.VerbServiceClient { +func ClientFromContext(ctx context.Context) ftlv1connect.VerbServiceClient { value := ctx.Value(clientKey{}) if value == nil { - panic("no ftlv1.VerbServiceClient in context") + panic("no ftlv1connect.VerbServiceClient in context") } - return value.(ftlv1.VerbServiceClient) //nolint:forcetypeassert + return value.(ftlv1connect.VerbServiceClient) //nolint:forcetypeassert }