diff --git a/.gitignore b/.gitignore index 570d41da2a..ad3a92273f 100644 --- a/.gitignore +++ b/.gitignore @@ -29,7 +29,6 @@ testdata/**/go.work.sum **/smoketest/**/ftl-module-schema/**/* go-runtime/schema/testdata/test/test.go .cache -.ftl-runner-info # Leaving old _ftl for now to avoid old stuff getting checked in **/testdata/**/_ftl diff --git a/backend/protos/xyz/block/ftl/hotreload/v1/hotreload.pb.go b/backend/protos/xyz/block/ftl/hotreload/v1/hotreload.pb.go index 1f1dbf8543..fc39c2b4c2 100644 --- a/backend/protos/xyz/block/ftl/hotreload/v1/hotreload.pb.go +++ b/backend/protos/xyz/block/ftl/hotreload/v1/hotreload.pb.go @@ -283,6 +283,154 @@ func (*WatchResponse_ReloadSuccess) isWatchResponse_Event() {} func (*WatchResponse_ReloadFailed) isWatchResponse_Event() {} +type RunnerInfoRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + Deployment string `protobuf:"bytes,2,opt,name=deployment,proto3" json:"deployment,omitempty"` + Databases []*Database `protobuf:"bytes,3,rep,name=databases,proto3" json:"databases,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RunnerInfoRequest) Reset() { + *x = RunnerInfoRequest{} + mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RunnerInfoRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RunnerInfoRequest) ProtoMessage() {} + +func (x *RunnerInfoRequest) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RunnerInfoRequest.ProtoReflect.Descriptor instead. +func (*RunnerInfoRequest) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_hotreload_v1_hotreload_proto_rawDescGZIP(), []int{4} +} + +func (x *RunnerInfoRequest) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +func (x *RunnerInfoRequest) GetDeployment() string { + if x != nil { + return x.Deployment + } + return "" +} + +func (x *RunnerInfoRequest) GetDatabases() []*Database { + if x != nil { + return x.Databases + } + return nil +} + +type Database struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Database) Reset() { + *x = Database{} + mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Database) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Database) ProtoMessage() {} + +func (x *Database) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Database.ProtoReflect.Descriptor instead. +func (*Database) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_hotreload_v1_hotreload_proto_rawDescGZIP(), []int{5} +} + +func (x *Database) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Database) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +type RunnerInfoResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *RunnerInfoResponse) Reset() { + *x = RunnerInfoResponse{} + mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RunnerInfoResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RunnerInfoResponse) ProtoMessage() {} + +func (x *RunnerInfoResponse) ProtoReflect() protoreflect.Message { + mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RunnerInfoResponse.ProtoReflect.Descriptor instead. +func (*RunnerInfoResponse) Descriptor() ([]byte, []int) { + return file_xyz_block_ftl_hotreload_v1_hotreload_proto_rawDescGZIP(), []int{6} +} + type ReloadNotRequired struct { state protoimpl.MessageState `protogen:"open.v1"` unknownFields protoimpl.UnknownFields @@ -291,7 +439,7 @@ type ReloadNotRequired struct { func (x *ReloadNotRequired) Reset() { *x = ReloadNotRequired{} - mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[4] + mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -303,7 +451,7 @@ func (x *ReloadNotRequired) String() string { func (*ReloadNotRequired) ProtoMessage() {} func (x *ReloadNotRequired) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[4] + mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -316,7 +464,7 @@ func (x *ReloadNotRequired) ProtoReflect() protoreflect.Message { // Deprecated: Use ReloadNotRequired.ProtoReflect.Descriptor instead. func (*ReloadNotRequired) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_hotreload_v1_hotreload_proto_rawDescGZIP(), []int{4} + return file_xyz_block_ftl_hotreload_v1_hotreload_proto_rawDescGZIP(), []int{7} } type ReloadSuccess struct { @@ -331,7 +479,7 @@ type ReloadSuccess struct { func (x *ReloadSuccess) Reset() { *x = ReloadSuccess{} - mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[5] + mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -343,7 +491,7 @@ func (x *ReloadSuccess) String() string { func (*ReloadSuccess) ProtoMessage() {} func (x *ReloadSuccess) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[5] + mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -356,7 +504,7 @@ func (x *ReloadSuccess) ProtoReflect() protoreflect.Message { // Deprecated: Use ReloadSuccess.ProtoReflect.Descriptor instead. func (*ReloadSuccess) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_hotreload_v1_hotreload_proto_rawDescGZIP(), []int{5} + return file_xyz_block_ftl_hotreload_v1_hotreload_proto_rawDescGZIP(), []int{8} } func (x *ReloadSuccess) GetModule() *v1.Module { @@ -383,7 +531,7 @@ type ReloadFailed struct { func (x *ReloadFailed) Reset() { *x = ReloadFailed{} - mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[6] + mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -395,7 +543,7 @@ func (x *ReloadFailed) String() string { func (*ReloadFailed) ProtoMessage() {} func (x *ReloadFailed) ProtoReflect() protoreflect.Message { - mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[6] + mi := &file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -408,7 +556,7 @@ func (x *ReloadFailed) ProtoReflect() protoreflect.Message { // Deprecated: Use ReloadFailed.ProtoReflect.Descriptor instead. func (*ReloadFailed) Descriptor() ([]byte, []int) { - return file_xyz_block_ftl_hotreload_v1_hotreload_proto_rawDescGZIP(), []int{6} + return file_xyz_block_ftl_hotreload_v1_hotreload_proto_rawDescGZIP(), []int{9} } func (x *ReloadFailed) GetErrors() *v11.ErrorList { @@ -465,46 +613,67 @@ var file_xyz_block_ftl_hotreload_v1_hotreload_proto_rawDesc = []byte{ 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x68, 0x6f, 0x74, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x61, - 0x69, 0x6c, 0x65, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x13, 0x0a, - 0x11, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x4e, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x64, 0x22, 0x86, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x75, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x12, 0x37, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x3c, 0x0a, - 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, - 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, - 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x4c, 0x0a, 0x0c, 0x52, - 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x3c, 0x0a, 0x06, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x79, - 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, - 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x32, 0x9f, 0x02, 0x0a, 0x10, 0x48, 0x6f, - 0x74, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4a, - 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, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x5f, 0x0a, 0x06, 0x52, 0x65, - 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x68, 0x6f, 0x74, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, - 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2a, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, - 0x68, 0x6f, 0x74, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, - 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x05, 0x57, - 0x61, 0x74, 0x63, 0x68, 0x12, 0x28, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x68, 0x6f, 0x74, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, - 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, - 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x68, - 0x6f, 0x74, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, - 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x42, 0x4e, 0x50, 0x01, 0x5a, - 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x78, 0x79, 0x7a, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x66, - 0x74, 0x6c, 0x2f, 0x68, 0x6f, 0x74, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x2f, 0x76, 0x31, 0x3b, - 0x68, 0x6f, 0x74, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x69, 0x6c, 0x65, 0x64, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x91, 0x01, + 0x0a, 0x11, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1e, 0x0a, + 0x0a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x42, 0x0a, + 0x09, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, + 0x2e, 0x68, 0x6f, 0x74, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x61, + 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, + 0x73, 0x22, 0x38, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x52, + 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x13, 0x0a, 0x11, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x4e, 0x6f, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x22, 0x86, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x6c, 0x6f, 0x61, + 0x64, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x37, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x12, 0x3c, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, + 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, + 0x4c, 0x0a, 0x0c, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, + 0x3c, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, + 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x32, 0x8c, 0x03, + 0x0a, 0x10, 0x48, 0x6f, 0x74, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x4a, 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, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x5f, + 0x0a, 0x06, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x68, 0x6f, 0x74, 0x72, 0x65, 0x6c, 0x6f, + 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, + 0x66, 0x74, 0x6c, 0x2e, 0x68, 0x6f, 0x74, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x5e, 0x0a, 0x05, 0x57, 0x61, 0x74, 0x63, 0x68, 0x12, 0x28, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x68, 0x6f, 0x74, 0x72, 0x65, 0x6c, 0x6f, + 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, + 0x74, 0x6c, 0x2e, 0x68, 0x6f, 0x74, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, + 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, + 0x6b, 0x0a, 0x0a, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2d, 0x2e, + 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x68, 0x6f, + 0x74, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, + 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x78, + 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x68, 0x6f, 0x74, + 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x4e, 0x50, 0x01, + 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x78, 0x79, 0x7a, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, + 0x66, 0x74, 0x6c, 0x2f, 0x68, 0x6f, 0x74, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x2f, 0x76, 0x31, + 0x3b, 0x68, 0x6f, 0x74, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -519,40 +688,46 @@ func file_xyz_block_ftl_hotreload_v1_hotreload_proto_rawDescGZIP() []byte { return file_xyz_block_ftl_hotreload_v1_hotreload_proto_rawDescData } -var file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_xyz_block_ftl_hotreload_v1_hotreload_proto_msgTypes = make([]protoimpl.MessageInfo, 10) var file_xyz_block_ftl_hotreload_v1_hotreload_proto_goTypes = []any{ - (*ReloadRequest)(nil), // 0: xyz.block.ftl.hotreload.v1.ReloadRequest - (*ReloadResponse)(nil), // 1: xyz.block.ftl.hotreload.v1.ReloadResponse - (*WatchRequest)(nil), // 2: xyz.block.ftl.hotreload.v1.WatchRequest - (*WatchResponse)(nil), // 3: xyz.block.ftl.hotreload.v1.WatchResponse - (*ReloadNotRequired)(nil), // 4: xyz.block.ftl.hotreload.v1.ReloadNotRequired - (*ReloadSuccess)(nil), // 5: xyz.block.ftl.hotreload.v1.ReloadSuccess - (*ReloadFailed)(nil), // 6: xyz.block.ftl.hotreload.v1.ReloadFailed - (*v1.Module)(nil), // 7: xyz.block.ftl.schema.v1.Module - (*v11.ErrorList)(nil), // 8: xyz.block.ftl.language.v1.ErrorList - (*v12.PingRequest)(nil), // 9: xyz.block.ftl.v1.PingRequest - (*v12.PingResponse)(nil), // 10: xyz.block.ftl.v1.PingResponse + (*ReloadRequest)(nil), // 0: xyz.block.ftl.hotreload.v1.ReloadRequest + (*ReloadResponse)(nil), // 1: xyz.block.ftl.hotreload.v1.ReloadResponse + (*WatchRequest)(nil), // 2: xyz.block.ftl.hotreload.v1.WatchRequest + (*WatchResponse)(nil), // 3: xyz.block.ftl.hotreload.v1.WatchResponse + (*RunnerInfoRequest)(nil), // 4: xyz.block.ftl.hotreload.v1.RunnerInfoRequest + (*Database)(nil), // 5: xyz.block.ftl.hotreload.v1.Database + (*RunnerInfoResponse)(nil), // 6: xyz.block.ftl.hotreload.v1.RunnerInfoResponse + (*ReloadNotRequired)(nil), // 7: xyz.block.ftl.hotreload.v1.ReloadNotRequired + (*ReloadSuccess)(nil), // 8: xyz.block.ftl.hotreload.v1.ReloadSuccess + (*ReloadFailed)(nil), // 9: xyz.block.ftl.hotreload.v1.ReloadFailed + (*v1.Module)(nil), // 10: xyz.block.ftl.schema.v1.Module + (*v11.ErrorList)(nil), // 11: xyz.block.ftl.language.v1.ErrorList + (*v12.PingRequest)(nil), // 12: xyz.block.ftl.v1.PingRequest + (*v12.PingResponse)(nil), // 13: xyz.block.ftl.v1.PingResponse } var file_xyz_block_ftl_hotreload_v1_hotreload_proto_depIdxs = []int32{ - 4, // 0: xyz.block.ftl.hotreload.v1.ReloadResponse.reload_not_required:type_name -> xyz.block.ftl.hotreload.v1.ReloadNotRequired - 5, // 1: xyz.block.ftl.hotreload.v1.ReloadResponse.reload_success:type_name -> xyz.block.ftl.hotreload.v1.ReloadSuccess - 6, // 2: xyz.block.ftl.hotreload.v1.ReloadResponse.reload_failed:type_name -> xyz.block.ftl.hotreload.v1.ReloadFailed - 5, // 3: xyz.block.ftl.hotreload.v1.WatchResponse.reload_success:type_name -> xyz.block.ftl.hotreload.v1.ReloadSuccess - 6, // 4: xyz.block.ftl.hotreload.v1.WatchResponse.reload_failed:type_name -> xyz.block.ftl.hotreload.v1.ReloadFailed - 7, // 5: xyz.block.ftl.hotreload.v1.ReloadSuccess.module:type_name -> xyz.block.ftl.schema.v1.Module - 8, // 6: xyz.block.ftl.hotreload.v1.ReloadSuccess.errors:type_name -> xyz.block.ftl.language.v1.ErrorList - 8, // 7: xyz.block.ftl.hotreload.v1.ReloadFailed.errors:type_name -> xyz.block.ftl.language.v1.ErrorList - 9, // 8: xyz.block.ftl.hotreload.v1.HotReloadService.Ping:input_type -> xyz.block.ftl.v1.PingRequest - 0, // 9: xyz.block.ftl.hotreload.v1.HotReloadService.Reload:input_type -> xyz.block.ftl.hotreload.v1.ReloadRequest - 2, // 10: xyz.block.ftl.hotreload.v1.HotReloadService.Watch:input_type -> xyz.block.ftl.hotreload.v1.WatchRequest - 10, // 11: xyz.block.ftl.hotreload.v1.HotReloadService.Ping:output_type -> xyz.block.ftl.v1.PingResponse - 1, // 12: xyz.block.ftl.hotreload.v1.HotReloadService.Reload:output_type -> xyz.block.ftl.hotreload.v1.ReloadResponse - 3, // 13: xyz.block.ftl.hotreload.v1.HotReloadService.Watch:output_type -> xyz.block.ftl.hotreload.v1.WatchResponse - 11, // [11:14] is the sub-list for method output_type - 8, // [8:11] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name + 7, // 0: xyz.block.ftl.hotreload.v1.ReloadResponse.reload_not_required:type_name -> xyz.block.ftl.hotreload.v1.ReloadNotRequired + 8, // 1: xyz.block.ftl.hotreload.v1.ReloadResponse.reload_success:type_name -> xyz.block.ftl.hotreload.v1.ReloadSuccess + 9, // 2: xyz.block.ftl.hotreload.v1.ReloadResponse.reload_failed:type_name -> xyz.block.ftl.hotreload.v1.ReloadFailed + 8, // 3: xyz.block.ftl.hotreload.v1.WatchResponse.reload_success:type_name -> xyz.block.ftl.hotreload.v1.ReloadSuccess + 9, // 4: xyz.block.ftl.hotreload.v1.WatchResponse.reload_failed:type_name -> xyz.block.ftl.hotreload.v1.ReloadFailed + 5, // 5: xyz.block.ftl.hotreload.v1.RunnerInfoRequest.databases:type_name -> xyz.block.ftl.hotreload.v1.Database + 10, // 6: xyz.block.ftl.hotreload.v1.ReloadSuccess.module:type_name -> xyz.block.ftl.schema.v1.Module + 11, // 7: xyz.block.ftl.hotreload.v1.ReloadSuccess.errors:type_name -> xyz.block.ftl.language.v1.ErrorList + 11, // 8: xyz.block.ftl.hotreload.v1.ReloadFailed.errors:type_name -> xyz.block.ftl.language.v1.ErrorList + 12, // 9: xyz.block.ftl.hotreload.v1.HotReloadService.Ping:input_type -> xyz.block.ftl.v1.PingRequest + 0, // 10: xyz.block.ftl.hotreload.v1.HotReloadService.Reload:input_type -> xyz.block.ftl.hotreload.v1.ReloadRequest + 2, // 11: xyz.block.ftl.hotreload.v1.HotReloadService.Watch:input_type -> xyz.block.ftl.hotreload.v1.WatchRequest + 4, // 12: xyz.block.ftl.hotreload.v1.HotReloadService.RunnerInfo:input_type -> xyz.block.ftl.hotreload.v1.RunnerInfoRequest + 13, // 13: xyz.block.ftl.hotreload.v1.HotReloadService.Ping:output_type -> xyz.block.ftl.v1.PingResponse + 1, // 14: xyz.block.ftl.hotreload.v1.HotReloadService.Reload:output_type -> xyz.block.ftl.hotreload.v1.ReloadResponse + 3, // 15: xyz.block.ftl.hotreload.v1.HotReloadService.Watch:output_type -> xyz.block.ftl.hotreload.v1.WatchResponse + 6, // 16: xyz.block.ftl.hotreload.v1.HotReloadService.RunnerInfo:output_type -> xyz.block.ftl.hotreload.v1.RunnerInfoResponse + 13, // [13:17] is the sub-list for method output_type + 9, // [9:13] 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 } func init() { file_xyz_block_ftl_hotreload_v1_hotreload_proto_init() } @@ -575,7 +750,7 @@ func file_xyz_block_ftl_hotreload_v1_hotreload_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_xyz_block_ftl_hotreload_v1_hotreload_proto_rawDesc, NumEnums: 0, - NumMessages: 7, + NumMessages: 10, NumExtensions: 0, NumServices: 1, }, diff --git a/backend/protos/xyz/block/ftl/hotreload/v1/hotreload.proto b/backend/protos/xyz/block/ftl/hotreload/v1/hotreload.proto index 626d1307e6..122969f642 100644 --- a/backend/protos/xyz/block/ftl/hotreload/v1/hotreload.proto +++ b/backend/protos/xyz/block/ftl/hotreload/v1/hotreload.proto @@ -32,6 +32,19 @@ message WatchResponse { } } +message RunnerInfoRequest { + string address = 1; + string deployment = 2; + repeated Database databases = 3; +} + +message Database { + string name = 1; + string address = 2; +} + +message RunnerInfoResponse { +} message ReloadNotRequired {} @@ -61,4 +74,7 @@ service HotReloadService { // Watch for hot reloads not initiated by an explicit Reload call. rpc Watch(WatchRequest) returns (stream WatchResponse); + + // Invoked by the runner to provide runner information to the plugin. + rpc RunnerInfo(RunnerInfoRequest) returns (RunnerInfoResponse); } diff --git a/backend/protos/xyz/block/ftl/hotreload/v1/hotreloadpbconnect/hotreload.connect.go b/backend/protos/xyz/block/ftl/hotreload/v1/hotreloadpbconnect/hotreload.connect.go index 879f6c2aef..667b1795ad 100644 --- a/backend/protos/xyz/block/ftl/hotreload/v1/hotreloadpbconnect/hotreload.connect.go +++ b/backend/protos/xyz/block/ftl/hotreload/v1/hotreloadpbconnect/hotreload.connect.go @@ -40,6 +40,9 @@ const ( HotReloadServiceReloadProcedure = "/xyz.block.ftl.hotreload.v1.HotReloadService/Reload" // HotReloadServiceWatchProcedure is the fully-qualified name of the HotReloadService's Watch RPC. HotReloadServiceWatchProcedure = "/xyz.block.ftl.hotreload.v1.HotReloadService/Watch" + // HotReloadServiceRunnerInfoProcedure is the fully-qualified name of the HotReloadService's + // RunnerInfo RPC. + HotReloadServiceRunnerInfoProcedure = "/xyz.block.ftl.hotreload.v1.HotReloadService/RunnerInfo" ) // HotReloadServiceClient is a client for the xyz.block.ftl.hotreload.v1.HotReloadService service. @@ -51,6 +54,8 @@ type HotReloadServiceClient interface { Reload(context.Context, *connect.Request[v11.ReloadRequest]) (*connect.Response[v11.ReloadResponse], error) // Watch for hot reloads not initiated by an explicit Reload call. Watch(context.Context, *connect.Request[v11.WatchRequest]) (*connect.ServerStreamForClient[v11.WatchResponse], error) + // Invoked by the runner to provide runner information to the plugin. + RunnerInfo(context.Context, *connect.Request[v11.RunnerInfoRequest]) (*connect.Response[v11.RunnerInfoResponse], error) } // NewHotReloadServiceClient constructs a client for the xyz.block.ftl.hotreload.v1.HotReloadService @@ -79,14 +84,20 @@ func NewHotReloadServiceClient(httpClient connect.HTTPClient, baseURL string, op baseURL+HotReloadServiceWatchProcedure, opts..., ), + runnerInfo: connect.NewClient[v11.RunnerInfoRequest, v11.RunnerInfoResponse]( + httpClient, + baseURL+HotReloadServiceRunnerInfoProcedure, + opts..., + ), } } // hotReloadServiceClient implements HotReloadServiceClient. type hotReloadServiceClient struct { - ping *connect.Client[v1.PingRequest, v1.PingResponse] - reload *connect.Client[v11.ReloadRequest, v11.ReloadResponse] - watch *connect.Client[v11.WatchRequest, v11.WatchResponse] + ping *connect.Client[v1.PingRequest, v1.PingResponse] + reload *connect.Client[v11.ReloadRequest, v11.ReloadResponse] + watch *connect.Client[v11.WatchRequest, v11.WatchResponse] + runnerInfo *connect.Client[v11.RunnerInfoRequest, v11.RunnerInfoResponse] } // Ping calls xyz.block.ftl.hotreload.v1.HotReloadService.Ping. @@ -104,6 +115,11 @@ func (c *hotReloadServiceClient) Watch(ctx context.Context, req *connect.Request return c.watch.CallServerStream(ctx, req) } +// RunnerInfo calls xyz.block.ftl.hotreload.v1.HotReloadService.RunnerInfo. +func (c *hotReloadServiceClient) RunnerInfo(ctx context.Context, req *connect.Request[v11.RunnerInfoRequest]) (*connect.Response[v11.RunnerInfoResponse], error) { + return c.runnerInfo.CallUnary(ctx, req) +} + // HotReloadServiceHandler is an implementation of the xyz.block.ftl.hotreload.v1.HotReloadService // service. type HotReloadServiceHandler interface { @@ -114,6 +130,8 @@ type HotReloadServiceHandler interface { Reload(context.Context, *connect.Request[v11.ReloadRequest]) (*connect.Response[v11.ReloadResponse], error) // Watch for hot reloads not initiated by an explicit Reload call. Watch(context.Context, *connect.Request[v11.WatchRequest], *connect.ServerStream[v11.WatchResponse]) error + // Invoked by the runner to provide runner information to the plugin. + RunnerInfo(context.Context, *connect.Request[v11.RunnerInfoRequest]) (*connect.Response[v11.RunnerInfoResponse], error) } // NewHotReloadServiceHandler builds an HTTP handler from the service implementation. It returns the @@ -138,6 +156,11 @@ func NewHotReloadServiceHandler(svc HotReloadServiceHandler, opts ...connect.Han svc.Watch, opts..., ) + hotReloadServiceRunnerInfoHandler := connect.NewUnaryHandler( + HotReloadServiceRunnerInfoProcedure, + svc.RunnerInfo, + opts..., + ) return "/xyz.block.ftl.hotreload.v1.HotReloadService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case HotReloadServicePingProcedure: @@ -146,6 +169,8 @@ func NewHotReloadServiceHandler(svc HotReloadServiceHandler, opts ...connect.Han hotReloadServiceReloadHandler.ServeHTTP(w, r) case HotReloadServiceWatchProcedure: hotReloadServiceWatchHandler.ServeHTTP(w, r) + case HotReloadServiceRunnerInfoProcedure: + hotReloadServiceRunnerInfoHandler.ServeHTTP(w, r) default: http.NotFound(w, r) } @@ -166,3 +191,7 @@ func (UnimplementedHotReloadServiceHandler) Reload(context.Context, *connect.Req func (UnimplementedHotReloadServiceHandler) Watch(context.Context, *connect.Request[v11.WatchRequest], *connect.ServerStream[v11.WatchResponse]) error { return connect.NewError(connect.CodeUnimplemented, errors.New("xyz.block.ftl.hotreload.v1.HotReloadService.Watch is not implemented")) } + +func (UnimplementedHotReloadServiceHandler) RunnerInfo(context.Context, *connect.Request[v11.RunnerInfoRequest]) (*connect.Response[v11.RunnerInfoResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("xyz.block.ftl.hotreload.v1.HotReloadService.RunnerInfo is not implemented")) +} diff --git a/backend/protos/xyz/block/ftl/language/v1/language.pb.go b/backend/protos/xyz/block/ftl/language/v1/language.pb.go index 745bbf2765..e6ea1d5e23 100644 --- a/backend/protos/xyz/block/ftl/language/v1/language.pb.go +++ b/backend/protos/xyz/block/ftl/language/v1/language.pb.go @@ -1271,10 +1271,10 @@ type BuildSuccess struct { DevEndpoint *string `protobuf:"bytes,7,opt,name=dev_endpoint,json=devEndpoint,proto3,oneof" json:"dev_endpoint,omitempty"` // Dev mode debug port DebugPort *int32 `protobuf:"varint,8,opt,name=debug_port,json=debugPort,proto3,oneof" json:"debug_port,omitempty"` - // Dev mode runner info file, this file is used to allow the runner to communicate provisioner info back to the plugin - DevRunnerInfoFile *string `protobuf:"bytes,9,opt,name=dev_runner_info_file,json=devRunnerInfoFile,proto3,oneof" json:"dev_runner_info_file,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // Dev mode hot reload endpoint, this is used to allow the runner to communicate info back to the running process + DevHotReloadEndpoint *string `protobuf:"bytes,9,opt,name=dev_hot_reload_endpoint,json=devHotReloadEndpoint,proto3,oneof" json:"dev_hot_reload_endpoint,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *BuildSuccess) Reset() { @@ -1363,9 +1363,9 @@ func (x *BuildSuccess) GetDebugPort() int32 { return 0 } -func (x *BuildSuccess) GetDevRunnerInfoFile() string { - if x != nil && x.DevRunnerInfoFile != nil { - return *x.DevRunnerInfoFile +func (x *BuildSuccess) GetDevHotReloadEndpoint() string { + if x != nil && x.DevHotReloadEndpoint != nil { + return *x.DevHotReloadEndpoint } return "" } @@ -2047,7 +2047,7 @@ var file_xyz_block_ftl_language_v1_language_proto_rawDesc = []byte{ 0x41, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, - 0x64, 0x22, 0xcc, 0x03, 0x0a, 0x0c, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x75, 0x63, 0x63, 0x65, + 0x64, 0x22, 0xd5, 0x03, 0x0a, 0x0c, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x73, 0x5f, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, @@ -2069,154 +2069,155 @@ var file_xyz_block_ftl_language_v1_language_proto_rawDesc = []byte{ 0x65, 0x76, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x22, 0x0a, 0x0a, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x09, 0x64, 0x65, 0x62, 0x75, 0x67, 0x50, 0x6f, 0x72, 0x74, 0x88, 0x01, - 0x01, 0x12, 0x34, 0x0a, 0x14, 0x64, 0x65, 0x76, 0x5f, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x5f, - 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x48, - 0x02, 0x52, 0x11, 0x64, 0x65, 0x76, 0x52, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, - 0x46, 0x69, 0x6c, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x64, 0x65, 0x76, 0x5f, - 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x64, 0x65, 0x62, - 0x75, 0x67, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x17, 0x0a, 0x15, 0x5f, 0x64, 0x65, 0x76, 0x5f, - 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x65, - 0x22, 0xd6, 0x01, 0x0a, 0x0c, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, - 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x64, - 0x12, 0x30, 0x0a, 0x14, 0x69, 0x73, 0x5f, 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, - 0x5f, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, - 0x69, 0x73, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x52, 0x65, 0x62, 0x75, 0x69, - 0x6c, 0x64, 0x12, 0x3c, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, - 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, - 0x12, 0x37, 0x0a, 0x17, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x64, - 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x16, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x70, - 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x22, 0x9b, 0x02, 0x0a, 0x0d, 0x42, 0x75, - 0x69, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x14, 0x61, - 0x75, 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x72, - 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, - 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, - 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x12, 0x61, 0x75, 0x74, 0x6f, - 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4e, - 0x0a, 0x0d, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x48, 0x00, - 0x52, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x4e, - 0x0a, 0x0d, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x48, 0x00, - 0x52, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x42, 0x07, - 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0xa8, 0x02, 0x0a, 0x14, 0x47, 0x65, 0x6e, 0x65, - 0x72, 0x61, 0x74, 0x65, 0x53, 0x74, 0x75, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, - 0x69, 0x72, 0x12, 0x37, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, - 0x74, 0x6c, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x64, - 0x75, 0x6c, 0x65, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x4c, 0x0a, 0x0d, 0x6d, - 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, - 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x6d, 0x6f, 0x64, - 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5e, 0x0a, 0x14, 0x6e, 0x61, 0x74, - 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x48, 0x00, 0x52, 0x12, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x88, 0x01, 0x01, 0x42, 0x17, 0x0a, 0x15, 0x5f, 0x6e, 0x61, - 0x74, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x22, 0x17, 0x0a, 0x15, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x53, 0x74, - 0x75, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdb, 0x01, 0x0a, 0x19, - 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x75, 0x62, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4c, 0x0a, 0x0d, 0x6d, 0x6f, 0x64, - 0x75, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x01, 0x12, 0x3a, 0x0a, 0x17, 0x64, 0x65, 0x76, 0x5f, 0x68, 0x6f, 0x74, 0x5f, 0x72, 0x65, 0x6c, + 0x6f, 0x61, 0x64, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x02, 0x52, 0x14, 0x64, 0x65, 0x76, 0x48, 0x6f, 0x74, 0x52, 0x65, 0x6c, 0x6f, + 0x61, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0f, 0x0a, + 0x0d, 0x5f, 0x64, 0x65, 0x76, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x0d, + 0x0a, 0x0b, 0x5f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x1a, 0x0a, + 0x18, 0x5f, 0x64, 0x65, 0x76, 0x5f, 0x68, 0x6f, 0x74, 0x5f, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, + 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0xd6, 0x01, 0x0a, 0x0c, 0x42, 0x75, + 0x69, 0x6c, 0x64, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x73, 0x5f, + 0x61, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x73, 0x41, 0x75, 0x74, 0x6f, 0x6d, + 0x61, 0x74, 0x69, 0x63, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x3c, 0x0a, 0x06, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x78, 0x79, + 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, + 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12, 0x37, 0x0a, 0x17, 0x69, 0x6e, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, + 0x63, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x69, 0x6e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, + 0x65, 0x73, 0x22, 0x9b, 0x02, 0x0a, 0x0d, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x61, 0x0a, 0x14, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x72, 0x65, 0x62, + 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, + 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x75, 0x74, 0x6f, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, + 0x64, 0x48, 0x00, 0x52, 0x12, 0x61, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4e, 0x0a, 0x0d, 0x62, 0x75, 0x69, 0x6c, 0x64, + 0x5f, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, + 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, + 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, + 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x4e, 0x0a, 0x0d, 0x62, 0x75, 0x69, 0x6c, 0x64, + 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, + 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, + 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, + 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, + 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x22, 0xa8, 0x02, 0x0a, 0x14, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x53, 0x74, 0x75, + 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x69, 0x72, 0x12, 0x37, 0x0a, 0x06, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x79, + 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x06, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x12, 0x4c, 0x0a, 0x0d, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x79, + 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, + 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x5e, 0x0a, 0x14, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x64, - 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x6d, 0x6f, 0x64, 0x75, 0x6c, - 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x75, 0x62, 0x73, - 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x75, - 0x62, 0x73, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, - 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, - 0x12, 0x37, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1f, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, - 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x1c, 0x0a, 0x1a, 0x53, 0x79, 0x6e, - 0x63, 0x53, 0x74, 0x75, 0x62, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xb9, 0x08, 0x0a, 0x0f, 0x4c, 0x61, 0x6e, 0x67, - 0x75, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4a, 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, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x87, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x73, - 0x12, 0x36, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, - 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x46, 0x6c, 0x61, 0x67, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, + 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x12, 0x6e, 0x61, 0x74, + 0x69, 0x76, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x88, + 0x01, 0x01, 0x42, 0x17, 0x0a, 0x15, 0x5f, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x17, 0x0a, 0x15, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x53, 0x74, 0x75, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdb, 0x01, 0x0a, 0x19, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x75, + 0x62, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x4c, 0x0a, 0x0d, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x78, 0x79, 0x7a, 0x2e, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, + 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x0c, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x75, 0x62, 0x73, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x75, 0x62, 0x73, 0x52, 0x6f, 0x6f, 0x74, 0x12, + 0x18, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x78, 0x79, 0x7a, 0x2e, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x22, 0x1c, 0x0a, 0x1a, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x75, 0x62, 0x52, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x32, 0xb9, 0x08, 0x0a, 0x0f, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x4a, 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, 0x22, 0x03, 0x90, 0x02, 0x01, + 0x12, 0x87, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x36, 0x2e, 0x78, 0x79, 0x7a, 0x2e, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, + 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x37, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, + 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x46, 0x6c, 0x61, + 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x0c, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x2e, 0x2e, 0x78, 0x79, 0x7a, + 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x78, 0x79, 0x7a, + 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x87, 0x01, 0x0a, 0x14, + 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x73, 0x12, 0x36, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x78, + 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, + 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x44, 0x65, 0x70, 0x65, + 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x6f, - 0x64, 0x75, 0x6c, 0x65, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x6f, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, - 0x65, 0x12, 0x2e, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, - 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2f, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, - 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x87, 0x01, 0x0a, 0x14, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x36, 0x2e, 0x78, 0x79, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, + 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, - 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, - 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x44, 0x65, 0x66, 0x61, - 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x0f, - 0x47, 0x65, 0x74, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x12, - 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, - 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, - 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, - 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x05, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, - 0x27, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, - 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, - 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, + 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x70, 0x65, 0x6e, + 0x64, 0x65, 0x6e, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x5c, 0x0a, 0x05, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x27, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x30, 0x01, 0x12, 0x84, 0x01, 0x0a, 0x13, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x35, 0x2e, 0x78, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x28, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, + 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, + 0x69, 0x6c, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x84, 0x01, + 0x0a, 0x13, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x35, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, - 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x0d, 0x47, - 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x53, 0x74, 0x75, 0x62, 0x73, 0x12, 0x2f, 0x2e, 0x78, - 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, - 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x53, 0x74, 0x75, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, - 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, - 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x53, 0x74, 0x75, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x81, 0x01, 0x0a, 0x12, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x75, 0x62, 0x52, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x34, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x0d, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x53, 0x74, 0x75, 0x62, 0x73, 0x12, 0x2f, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x53, 0x74, 0x75, 0x62, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x75, 0x62, 0x52, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x78, - 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, - 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x75, - 0x62, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x42, 0x4c, 0x50, 0x01, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x62, 0x61, - 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x78, 0x79, 0x7a, - 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x6c, 0x61, 0x6e, 0x67, 0x75, - 0x61, 0x67, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x70, - 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x53, 0x74, 0x75, 0x62, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, 0x01, 0x0a, 0x12, 0x53, 0x79, 0x6e, + 0x63, 0x53, 0x74, 0x75, 0x62, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, + 0x34, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, + 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, + 0x53, 0x74, 0x75, 0x62, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x78, 0x79, 0x7a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x2e, 0x66, 0x74, 0x6c, 0x2e, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x75, 0x62, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x4c, 0x50, 0x01, + 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x2f, 0x66, 0x74, 0x6c, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x78, 0x79, 0x7a, 0x2f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2f, + 0x66, 0x74, 0x6c, 0x2f, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x2f, 0x76, 0x31, 0x3b, + 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/backend/protos/xyz/block/ftl/language/v1/language.proto b/backend/protos/xyz/block/ftl/language/v1/language.proto index 62a49bc068..6d4dc932f4 100644 --- a/backend/protos/xyz/block/ftl/language/v1/language.proto +++ b/backend/protos/xyz/block/ftl/language/v1/language.proto @@ -237,8 +237,8 @@ message BuildSuccess { // Dev mode debug port optional int32 debug_port = 8; - // Dev mode runner info file, this file is used to allow the runner to communicate provisioner info back to the plugin - optional string dev_runner_info_file = 9; + // Dev mode hot reload endpoint, this is used to allow the runner to communicate info back to the running process + optional string dev_hot_reload_endpoint = 9; } // BuildFailure should be sent when a build fails. diff --git a/backend/provisioner/scaling/localscaling/local_scaling.go b/backend/provisioner/scaling/localscaling/local_scaling.go index e393d417ad..80de96b63e 100644 --- a/backend/provisioner/scaling/localscaling/local_scaling.go +++ b/backend/provisioner/scaling/localscaling/local_scaling.go @@ -100,11 +100,11 @@ func (l *localScaling) TerminatePreviousDeployments(ctx context.Context, module } type devModeRunner struct { - uri url.URL + uri string + hotReloadURI string // The deployment key of the deployment that is currently running - deploymentKey optional.Option[key.Deployment] - debugPort int - runnerInfoFile optional.Option[string] + deploymentKey optional.Option[key.Deployment] + debugPort int } func (l *localScaling) Start(ctx context.Context) error { @@ -122,9 +122,9 @@ func (l *localScaling) Start(ctx context.Context) error { // Must be called under lock func (l *localScaling) updateDevModeEndpoint(ctx context.Context, devEndpoints dev.LocalEndpoint) { l.devModeEndpoints[devEndpoints.Module] = &devModeRunner{ - uri: devEndpoints.Endpoint, - debugPort: devEndpoints.DebugPort, - runnerInfoFile: devEndpoints.RunnerInfoFile, + uri: devEndpoints.Endpoint, + debugPort: devEndpoints.DebugPort, + hotReloadURI: devEndpoints.HotReloadEndpoint, } if ide, ok := l.ideSupport.Get(); ok { if devEndpoints.DebugPort != 0 { @@ -255,12 +255,12 @@ func (l *localScaling) startRunner(ctx context.Context, deploymentKey key.Deploy } devEndpoint := l.devModeEndpoints[info.module] - devURI := optional.None[url.URL]() - devRunnerInfoFile := optional.None[string]() + devURI := optional.None[string]() + devHotReloadURI := optional.None[string]() debugPort := 0 if devEndpoint != nil { devURI = optional.Some(devEndpoint.uri) - devRunnerInfoFile = devEndpoint.runnerInfoFile + devHotReloadURI = optional.Some(devEndpoint.hotReloadURI) if devKey, ok := devEndpoint.deploymentKey.Get(); ok && devKey.Equal(deploymentKey) { // Already running, don't start another return nil @@ -297,14 +297,14 @@ func (l *localScaling) startRunner(ctx context.Context, deploymentKey key.Deploy return fmt.Errorf("failed to start runner: %w", err) } config := runner.Config{ - Bind: bindURL, - ControllerEndpoint: controllerEndpoint, - LeaseEndpoint: l.leaseAddress, - Key: key.NewLocalRunnerKey(keySuffix), - Deployment: deploymentKey, - DebugPort: debugPort, - DevEndpoint: devURI, - DevRunnerInfoFile: devRunnerInfoFile, + Bind: bindURL, + ControllerEndpoint: controllerEndpoint, + LeaseEndpoint: l.leaseAddress, + Key: key.NewLocalRunnerKey(keySuffix), + Deployment: deploymentKey, + DebugPort: debugPort, + DevEndpoint: devURI, + DevHotReloadEndpoint: devHotReloadURI, } simpleName := fmt.Sprintf("runner%d", keySuffix) diff --git a/backend/runner/runner.go b/backend/runner/runner.go index aabfb775f9..a974a47b97 100644 --- a/backend/runner/runner.go +++ b/backend/runner/runner.go @@ -29,8 +29,11 @@ import ( "google.golang.org/protobuf/types/known/structpb" mysql "github.com/block/ftl-mysql-auth-proxy" + "github.com/block/ftl/backend/controller/artefacts" ftldeploymentconnect "github.com/block/ftl/backend/protos/xyz/block/ftl/deployment/v1/deploymentpbconnect" + hotreloadpb "github.com/block/ftl/backend/protos/xyz/block/ftl/hotreload/v1" + "github.com/block/ftl/backend/protos/xyz/block/ftl/hotreload/v1/hotreloadpbconnect" ftlleaseconnect "github.com/block/ftl/backend/protos/xyz/block/ftl/lease/v1/leasepbconnect" "github.com/block/ftl/backend/protos/xyz/block/ftl/pubsub/v1/pubsubpbconnect" "github.com/block/ftl/backend/protos/xyz/block/ftl/query/v1/querypbconnect" @@ -57,22 +60,22 @@ import ( ) type Config struct { - Config []string `name:"config" short:"C" help:"Paths to FTL project configuration files." env:"FTL_CONFIG" placeholder:"FILE[,FILE,...]" type:"existingfile"` - Bind *url.URL `help:"Endpoint the Runner should bind to and advertise." default:"http://127.0.0.1:8892" env:"FTL_BIND"` - Key key.Runner `help:"Runner key (auto)."` - ControllerEndpoint *url.URL `name:"ftl-endpoint" help:"Controller endpoint." env:"FTL_ENDPOINT" default:"http://127.0.0.1:8892"` - LeaseEndpoint *url.URL `name:"ftl-lease-endpoint" help:"Lease endpoint endpoint." env:"FTL_LEASE_ENDPOINT" default:"http://127.0.0.1:8895"` - QueryEndpoint *url.URL `name:"ftl-query-endpoint" help:"Query endpoint." env:"FTL_QUERY_ENDPOINT" default:"http://127.0.0.1:8897"` - TimelineEndpoint *url.URL `help:"Timeline endpoint." env:"FTL_TIMELINE_ENDPOINT" default:"http://127.0.0.1:8894"` - TemplateDir string `help:"Template directory to copy into each deployment, if any." type:"existingdir"` - DeploymentDir string `help:"Directory to store deployments in." default:"${deploymentdir}"` - DeploymentKeepHistory int `help:"Number of deployments to keep history for." default:"3"` - HeartbeatPeriod time.Duration `help:"Minimum period between heartbeats." default:"3s"` - HeartbeatJitter time.Duration `help:"Jitter to add to heartbeat period." default:"2s"` - Deployment key.Deployment `help:"The deployment this runner is for." env:"FTL_DEPLOYMENT"` - DebugPort int `help:"The port to use for debugging." env:"FTL_DEBUG_PORT"` - DevEndpoint optional.Option[url.URL] `help:"An existing endpoint to connect to in development mode" hidden:""` - DevRunnerInfoFile optional.Option[string] `help:"The path to a file that we write dev endpoint information to." hidden:""` + Config []string `name:"config" short:"C" help:"Paths to FTL project configuration files." env:"FTL_CONFIG" placeholder:"FILE[,FILE,...]" type:"existingfile"` + Bind *url.URL `help:"Endpoint the Runner should bind to and advertise." default:"http://127.0.0.1:8892" env:"FTL_BIND"` + Key key.Runner `help:"Runner key (auto)."` + ControllerEndpoint *url.URL `name:"ftl-endpoint" help:"Controller endpoint." env:"FTL_ENDPOINT" default:"http://127.0.0.1:8892"` + LeaseEndpoint *url.URL `name:"ftl-lease-endpoint" help:"Lease endpoint endpoint." env:"FTL_LEASE_ENDPOINT" default:"http://127.0.0.1:8895"` + QueryEndpoint *url.URL `name:"ftl-query-endpoint" help:"Query endpoint." env:"FTL_QUERY_ENDPOINT" default:"http://127.0.0.1:8897"` + TimelineEndpoint *url.URL `help:"Timeline endpoint." env:"FTL_TIMELINE_ENDPOINT" default:"http://127.0.0.1:8894"` + TemplateDir string `help:"Template directory to copy into each deployment, if any." type:"existingdir"` + DeploymentDir string `help:"Directory to store deployments in." default:"${deploymentdir}"` + DeploymentKeepHistory int `help:"Number of deployments to keep history for." default:"3"` + HeartbeatPeriod time.Duration `help:"Minimum period between heartbeats." default:"3s"` + HeartbeatJitter time.Duration `help:"Jitter to add to heartbeat period." default:"2s"` + Deployment key.Deployment `help:"The deployment this runner is for." env:"FTL_DEPLOYMENT"` + DebugPort int `help:"The port to use for debugging." env:"FTL_DEBUG_PORT"` + DevEndpoint optional.Option[string] `help:"An existing endpoint to connect to in development mode" hidden:""` + DevHotReloadEndpoint optional.Option[string] `help:"The gRPC enpoint to send runner into to for hot reload." hidden:""` } func Start(ctx context.Context, config Config, storage *artefacts.OCIArtefactService) error { @@ -119,17 +122,17 @@ func Start(ctx context.Context, config Config, storage *artefacts.OCIArtefactSer timelineClient := timeline.NewClient(ctx, config.TimelineEndpoint) svc := &Service{ - key: runnerKey, - config: config, - storage: storage, - controllerClient: controllerClient, - timelineClient: timelineClient, - labels: labels, - deploymentLogQueue: make(chan log.Entry, 10000), - cancelFunc: doneFunc, - devEndpoint: config.DevEndpoint, - devRunnerInfoFile: config.DevRunnerInfoFile, - queryServices: query.NewMultiService(), + key: runnerKey, + config: config, + storage: storage, + controllerClient: controllerClient, + timelineClient: timelineClient, + labels: labels, + deploymentLogQueue: make(chan log.Entry, 10000), + cancelFunc: doneFunc, + devEndpoint: config.DevEndpoint, + devHotReloadEndpoint: config.DevHotReloadEndpoint, + queryServices: query.NewMultiService(), } module, err := svc.getModule(ctx, config.Deployment) @@ -245,10 +248,11 @@ var _ ftlv1connect.VerbServiceHandler = (*Service)(nil) type deployment struct { key key.Deployment // Cancelled when plugin terminates - ctx context.Context - cmd optional.Option[exec.Cmd] - endpoint *url.URL // The endpoint the plugin is listening on. - client ftlv1connect.VerbServiceClient + ctx context.Context + cmd optional.Option[exec.Cmd] + endpoint string // The endpoint the plugin is listening on. + client ftlv1connect.VerbServiceClient + reverseProxy *httputil.ReverseProxy } type Service struct { @@ -262,16 +266,16 @@ type Service struct { controllerClient ftlv1connect.ControllerServiceClient timelineClient *timeline.Client // Failed to register with the Controller - registrationFailure atomic.Value[optional.Option[error]] - labels *structpb.Struct - deploymentLogQueue chan log.Entry - cancelFunc func() - devEndpoint optional.Option[url.URL] - devRunnerInfoFile optional.Option[string] - proxy *proxy.Service - pubSub *pubsub.Service - queryServices *query.MultiService - proxyBindAddress *url.URL + registrationFailure atomic.Value[optional.Option[error]] + labels *structpb.Struct + deploymentLogQueue chan log.Entry + cancelFunc func() + devEndpoint optional.Option[string] + devHotReloadEndpoint optional.Option[string] + proxy *proxy.Service + pubSub *pubsub.Service + queryServices *query.MultiService + proxyBindAddress *url.URL } func (s *Service) Call(ctx context.Context, req *connect.Request[ftlv1.CallRequest]) (*connect.Response[ftlv1.CallResponse], error) { @@ -387,27 +391,38 @@ func (s *Service) deploy(ctx context.Context, key key.Deployment, module *schema var dep *deployment if ep, ok := s.devEndpoint.Get(); ok { - client := rpc.Dial(ftlv1connect.NewVerbServiceClient, ep.String(), log.Error) - dep = &deployment{ - ctx: ctx, - key: key, - cmd: optional.None[exec.Cmd](), - endpoint: &ep, - client: client, - } - if file, ok := s.devRunnerInfoFile.Get(); ok { - fileContents := "proxy.bind.address=" + s.proxyBindAddress.String() - fileContents += fmt.Sprintf("\ndeployment=%s", s.config.Deployment.String()) + if hotRelaodEp, ok := s.devHotReloadEndpoint.Get(); ok { + hotReloadClient := rpc.Dial(hotreloadpbconnect.NewHotReloadServiceClient, hotRelaodEp, log.Error) + err = rpc.Wait(ctx, backoff.Backoff{}, time.Minute, hotReloadClient) + if err != nil { + return fmt.Errorf("failed to ping hot reload endpoint: %w", err) + } + var databases []*hotreloadpb.Database dbAddresses.Range(func(key string, value string) bool { - fileContents += fmt.Sprintf("\ndatabase.%s.url=%s", key, value) + databases = append(databases, &hotreloadpb.Database{ + Name: key, + Address: value, + }) return true }) - err = os.WriteFile(file, []byte(fileContents), 0660) // #nosec + _, err := hotReloadClient.RunnerInfo(ctx, connect.NewRequest(&hotreloadpb.RunnerInfoRequest{ + Deployment: s.config.Deployment.String(), + Address: s.proxyBindAddress.String(), + Databases: databases, + })) if err != nil { - logger.Errorf(err, "could not create FTL dev Config") + return fmt.Errorf("failed to send runner info: %w", err) } } + client := rpc.Dial(ftlv1connect.NewVerbServiceClient, ep, log.Error) err = rpc.Wait(ctx, backoff.Backoff{}, time.Minute, client) + dep = &deployment{ + ctx: ctx, + key: key, + cmd: optional.None[exec.Cmd](), + endpoint: ep, + client: client, + } if err != nil { observability.Deployment.Failure(ctx, optional.Some(key.String())) return fmt.Errorf("failed to ping dev endpoint: %w", err) @@ -510,18 +525,19 @@ func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, "no deployment", http.StatusNotFound) return } - proxy := httputil.NewSingleHostReverseProxy(deployment.endpoint) - proxy.ServeHTTP(w, r) + deployment.reverseProxy.ServeHTTP(w, r) } func (s *Service) makeDeployment(ctx context.Context, key key.Deployment, plugin *plugin.Plugin[ftlv1connect.VerbServiceClient, ftlv1.PingRequest, ftlv1.PingResponse, *ftlv1.PingResponse]) *deployment { + proxy := httputil.NewSingleHostReverseProxy(plugin.Endpoint) return &deployment{ - ctx: ctx, - key: key, - cmd: optional.Ptr(plugin.Cmd), - endpoint: plugin.Endpoint, - client: plugin.Client, + ctx: ctx, + key: key, + cmd: optional.Ptr(plugin.Cmd), + endpoint: plugin.Endpoint.String(), + client: plugin.Client, + reverseProxy: proxy, } } diff --git a/frontend/console/src/protos/xyz/block/ftl/hotreload/v1/hotreload_connect.ts b/frontend/console/src/protos/xyz/block/ftl/hotreload/v1/hotreload_connect.ts index 33142f7b26..06f01b7c0e 100644 --- a/frontend/console/src/protos/xyz/block/ftl/hotreload/v1/hotreload_connect.ts +++ b/frontend/console/src/protos/xyz/block/ftl/hotreload/v1/hotreload_connect.ts @@ -5,7 +5,7 @@ import { PingRequest, PingResponse } from "../../v1/ftl_pb.js"; import { MethodIdempotency, MethodKind } from "@bufbuild/protobuf"; -import { ReloadRequest, ReloadResponse, WatchRequest, WatchResponse } from "./hotreload_pb.js"; +import { ReloadRequest, ReloadResponse, RunnerInfoRequest, RunnerInfoResponse, WatchRequest, WatchResponse } from "./hotreload_pb.js"; /** * HotReloadService is for communication between a language plugin a language runtime that can perform a hot reload @@ -51,6 +51,17 @@ export const HotReloadService = { O: WatchResponse, kind: MethodKind.ServerStreaming, }, + /** + * Invoked by the runner to provide runner information to the plugin. + * + * @generated from rpc xyz.block.ftl.hotreload.v1.HotReloadService.RunnerInfo + */ + runnerInfo: { + name: "RunnerInfo", + I: RunnerInfoRequest, + O: RunnerInfoResponse, + kind: MethodKind.Unary, + }, } } as const; diff --git a/frontend/console/src/protos/xyz/block/ftl/hotreload/v1/hotreload_pb.ts b/frontend/console/src/protos/xyz/block/ftl/hotreload/v1/hotreload_pb.ts index 4414faa340..d3444022d4 100644 --- a/frontend/console/src/protos/xyz/block/ftl/hotreload/v1/hotreload_pb.ts +++ b/frontend/console/src/protos/xyz/block/ftl/hotreload/v1/hotreload_pb.ts @@ -183,6 +183,129 @@ export class WatchResponse extends Message { } } +/** + * @generated from message xyz.block.ftl.hotreload.v1.RunnerInfoRequest + */ +export class RunnerInfoRequest extends Message { + /** + * @generated from field: string address = 1; + */ + address = ""; + + /** + * @generated from field: string deployment = 2; + */ + deployment = ""; + + /** + * @generated from field: repeated xyz.block.ftl.hotreload.v1.Database databases = 3; + */ + databases: Database[] = []; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.hotreload.v1.RunnerInfoRequest"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "address", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "deployment", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 3, name: "databases", kind: "message", T: Database, repeated: true }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): RunnerInfoRequest { + return new RunnerInfoRequest().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): RunnerInfoRequest { + return new RunnerInfoRequest().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): RunnerInfoRequest { + return new RunnerInfoRequest().fromJsonString(jsonString, options); + } + + static equals(a: RunnerInfoRequest | PlainMessage | undefined, b: RunnerInfoRequest | PlainMessage | undefined): boolean { + return proto3.util.equals(RunnerInfoRequest, a, b); + } +} + +/** + * @generated from message xyz.block.ftl.hotreload.v1.Database + */ +export class Database extends Message { + /** + * @generated from field: string name = 1; + */ + name = ""; + + /** + * @generated from field: string address = 2; + */ + address = ""; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.hotreload.v1.Database"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "address", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): Database { + return new Database().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): Database { + return new Database().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): Database { + return new Database().fromJsonString(jsonString, options); + } + + static equals(a: Database | PlainMessage | undefined, b: Database | PlainMessage | undefined): boolean { + return proto3.util.equals(Database, a, b); + } +} + +/** + * @generated from message xyz.block.ftl.hotreload.v1.RunnerInfoResponse + */ +export class RunnerInfoResponse extends Message { + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "xyz.block.ftl.hotreload.v1.RunnerInfoResponse"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): RunnerInfoResponse { + return new RunnerInfoResponse().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): RunnerInfoResponse { + return new RunnerInfoResponse().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): RunnerInfoResponse { + return new RunnerInfoResponse().fromJsonString(jsonString, options); + } + + static equals(a: RunnerInfoResponse | PlainMessage | undefined, b: RunnerInfoResponse | PlainMessage | undefined): boolean { + return proto3.util.equals(RunnerInfoResponse, a, b); + } +} + /** * @generated from message xyz.block.ftl.hotreload.v1.ReloadNotRequired */ diff --git a/frontend/console/src/protos/xyz/block/ftl/language/v1/language_pb.ts b/frontend/console/src/protos/xyz/block/ftl/language/v1/language_pb.ts index 66d2df2701..d9ee407631 100644 --- a/frontend/console/src/protos/xyz/block/ftl/language/v1/language_pb.ts +++ b/frontend/console/src/protos/xyz/block/ftl/language/v1/language_pb.ts @@ -1170,11 +1170,11 @@ export class BuildSuccess extends Message { debugPort?: number; /** - * Dev mode runner info file, this file is used to allow the runner to communicate provisioner info back to the plugin + * Dev mode hot reload endpoint, this is used to allow the runner to communicate info back to the running process * - * @generated from field: optional string dev_runner_info_file = 9; + * @generated from field: optional string dev_hot_reload_endpoint = 9; */ - devRunnerInfoFile?: string; + devHotReloadEndpoint?: string; constructor(data?: PartialMessage) { super(); @@ -1192,7 +1192,7 @@ export class BuildSuccess extends Message { { no: 6, name: "errors", kind: "message", T: ErrorList }, { no: 7, name: "dev_endpoint", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, { no: 8, name: "debug_port", kind: "scalar", T: 5 /* ScalarType.INT32 */, opt: true }, - { no: 9, name: "dev_runner_info_file", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, + { no: 9, name: "dev_hot_reload_endpoint", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true }, ]); static fromBinary(bytes: Uint8Array, options?: Partial): BuildSuccess { diff --git a/internal/buildengine/build.go b/internal/buildengine/build.go index e050a82e26..47ebf44711 100644 --- a/internal/buildengine/build.go +++ b/internal/buildengine/build.go @@ -3,7 +3,6 @@ package buildengine import ( "context" "fmt" - "net/url" "os" "path/filepath" "time" @@ -93,10 +92,7 @@ func handleBuildResult(ctx context.Context, projectConfig projectconfig.Config, } if endpoint, ok := result.DevEndpoint.Get(); ok { if devModeEndpoints != nil { - parsed, err := url.Parse(endpoint) - if err == nil { - devModeEndpoints <- dev.LocalEndpoint{Module: config.Module, Endpoint: *parsed, DebugPort: result.DebugPort, Language: config.Language, RunnerInfoFile: result.DevRunnerInfoFile} - } + devModeEndpoints <- dev.LocalEndpoint{Module: config.Module, Endpoint: endpoint, DebugPort: result.DebugPort, Language: config.Language, HotReloadEndpoint: result.HotReloadEndpoint.Default("")} } } return result.Schema, result.Deploy, nil diff --git a/internal/buildengine/languageplugin/plugin.go b/internal/buildengine/languageplugin/plugin.go index 25801244fe..748ed0a172 100644 --- a/internal/buildengine/languageplugin/plugin.go +++ b/internal/buildengine/languageplugin/plugin.go @@ -41,7 +41,7 @@ type BuildResult struct { DevEndpoint optional.Option[string] // File that the runner can use to pass info into the hot reload endpoint - DevRunnerInfoFile optional.Option[string] + HotReloadEndpoint optional.Option[string] DebugPort int } @@ -581,7 +581,7 @@ func buildResultFromProto(result either.Either[*langpb.BuildResponse_BuildSucces Deploy: buildSuccess.Deploy, StartTime: startTime, DevEndpoint: optional.Ptr(buildSuccess.DevEndpoint), - DevRunnerInfoFile: optional.Ptr(buildSuccess.DevRunnerInfoFile), + HotReloadEndpoint: optional.Ptr(buildSuccess.DevHotReloadEndpoint), DebugPort: port, }, nil case either.Right[*langpb.BuildResponse_BuildSuccess, *langpb.BuildResponse_BuildFailure]: diff --git a/internal/dev/devendpoint.go b/internal/dev/devendpoint.go index ec7f7c2877..6d3906af3b 100644 --- a/internal/dev/devendpoint.go +++ b/internal/dev/devendpoint.go @@ -1,15 +1,9 @@ package dev -import ( - "net/url" - - "github.com/alecthomas/types/optional" -) - type LocalEndpoint struct { - Module string - Endpoint url.URL - DebugPort int - Language string - RunnerInfoFile optional.Option[string] + Module string + Endpoint string + DebugPort int + Language string + HotReloadEndpoint string } diff --git a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/HotReloadHandler.java b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/HotReloadHandler.java index d2e209f25d..c8257e8459 100644 --- a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/HotReloadHandler.java +++ b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/HotReloadHandler.java @@ -5,7 +5,9 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; @@ -17,12 +19,16 @@ import io.grpc.stub.StreamObserver; import io.quarkus.bootstrap.classloading.QuarkusClassLoader; import io.quarkus.deployment.dev.RuntimeUpdatesProcessor; +import xyz.block.ftl.hotreload.RunnerInfo; +import xyz.block.ftl.hotreload.RunnerNotification; import xyz.block.ftl.hotreload.v1.HotReloadServiceGrpc; import xyz.block.ftl.hotreload.v1.ReloadFailed; import xyz.block.ftl.hotreload.v1.ReloadNotRequired; import xyz.block.ftl.hotreload.v1.ReloadRequest; import xyz.block.ftl.hotreload.v1.ReloadResponse; import xyz.block.ftl.hotreload.v1.ReloadSuccess; +import xyz.block.ftl.hotreload.v1.RunnerInfoRequest; +import xyz.block.ftl.hotreload.v1.RunnerInfoResponse; import xyz.block.ftl.hotreload.v1.WatchRequest; import xyz.block.ftl.hotreload.v1.WatchResponse; import xyz.block.ftl.language.v1.Error; @@ -93,18 +99,18 @@ public void reload(ReloadRequest request, StreamObserver respons try { doScan(request.getForce()); } finally { - synchronized (HotReloadHandler.class) { + synchronized (HotReloadHandler.this) { explicitlyReloading = false; - HotReloadHandler.class.notifyAll(); + HotReloadHandler.this.notifyAll(); } } }, "FTL Restart Thread"); - synchronized (HotReloadHandler.class) { + synchronized (HotReloadHandler.this) { explicitlyReloading = true; t.start(); while (explicitlyReloading) { try { - HotReloadHandler.class.wait(); + HotReloadHandler.this.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } @@ -170,6 +176,18 @@ public void watch(WatchRequest request, StreamObserver responseOb watches.add(responseObserver); } + @Override + public void runnerInfo(RunnerInfoRequest request, StreamObserver responseObserver) { + Map databases = new HashMap<>(); + for (var db : request.getDatabasesList()) { + databases.put(db.getName(), db.getAddress()); + } + RunnerNotification + .setRunnerInfo(new RunnerInfo(request.getAddress(), request.getDeployment(), databases)); + responseObserver.onNext(RunnerInfoResponse.newBuilder().build()); + responseObserver.onCompleted(); + } + public static void start() { if (INSTANCE != null) { return; @@ -187,7 +205,7 @@ private void init() { gatherMigrations(); int port = Integer.getInteger("ftl.language.port"); server = ServerBuilder.forPort(port) - .addService(new HotReloadHandler()) + .addService(this) .build(); try { LOG.info("Starting Hot Reload gRPC server on port " + port); diff --git a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/ModuleProcessor.java b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/ModuleProcessor.java index 27eec24f14..c964dd69a5 100644 --- a/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/ModuleProcessor.java +++ b/jvm-runtime/ftl-runtime/common/deployment/src/main/java/xyz/block/ftl/deployment/ModuleProcessor.java @@ -63,8 +63,6 @@ public class ModuleProcessor { private static final String SCHEMA_OUT = "schema.pb"; private static final String ERRORS_OUT = "errors.pb"; - public static final String DEV_MODE_RUNNER_INFO_FILE = "FTL_RUNNER_INFO"; - /** * Persistent schema hash, used to detect runner restarts in dev mode. */ @@ -195,16 +193,7 @@ public void accept(xyz.block.ftl.schema.v1.Module module, ErrorList errorList) { var hash = HashUtil.sha256(schBytes); if (!Objects.equals(hash, schemaHash)) { schemaHash = hash; - String runnerInfo = System.getenv(DEV_MODE_RUNNER_INFO_FILE); - if (runnerInfo != null) { - Path path = Path.of(runnerInfo); - // Delete the runner info file if it already exists - Files.deleteIfExists(path); - // This method tells the runtime not to actually start until we have updated runner details - systemPropertyBuildItemBuildProducer - .produce(new SystemPropertyBuildItem(FTLRecorder.DEV_MODE_RUNNER_INFO_PATH, path.toString())); - recorder.handleDevModeRunnerStart(shutdownContextBuildItem); - } + recorder.handleDevModeRunnerStart(shutdownContextBuildItem); } } else { output = outputTargetBuildItem.getOutputDirectory().resolve("launch"); diff --git a/jvm-runtime/ftl-runtime/common/hotreload/pom.xml b/jvm-runtime/ftl-runtime/common/hotreload/pom.xml new file mode 100644 index 0000000000..bf28b9b7c2 --- /dev/null +++ b/jvm-runtime/ftl-runtime/common/hotreload/pom.xml @@ -0,0 +1,14 @@ + + + 4.0.0 + + + xyz.block.ftl + ftl-jvm-runtime-parent + 1.0-SNAPSHOT + + ftl-jvm-hot-reload + FTL Java Runtime - Hot Reload SPI + + diff --git a/jvm-runtime/ftl-runtime/common/hotreload/src/main/java/xyz/block/ftl/hotreload/RunnerInfo.java b/jvm-runtime/ftl-runtime/common/hotreload/src/main/java/xyz/block/ftl/hotreload/RunnerInfo.java new file mode 100644 index 0000000000..dfaa55b63f --- /dev/null +++ b/jvm-runtime/ftl-runtime/common/hotreload/src/main/java/xyz/block/ftl/hotreload/RunnerInfo.java @@ -0,0 +1,7 @@ +package xyz.block.ftl.hotreload; + +import java.util.Map; + +public record RunnerInfo(String address, String deployment, Map databases) { + +} diff --git a/jvm-runtime/ftl-runtime/common/hotreload/src/main/java/xyz/block/ftl/hotreload/RunnerNotification.java b/jvm-runtime/ftl-runtime/common/hotreload/src/main/java/xyz/block/ftl/hotreload/RunnerNotification.java new file mode 100644 index 0000000000..d5ee059315 --- /dev/null +++ b/jvm-runtime/ftl-runtime/common/hotreload/src/main/java/xyz/block/ftl/hotreload/RunnerNotification.java @@ -0,0 +1,31 @@ +package xyz.block.ftl.hotreload; + +import java.util.function.Consumer; + +public class RunnerNotification { + + private static volatile Consumer callback; + private static volatile RunnerInfo info; + + public static synchronized void setCallback(Consumer callback) { + if (RunnerNotification.callback != null) { + throw new IllegalStateException("Callback already set"); + } + if (info != null) { + callback.accept(info); + info = null; + } else { + RunnerNotification.callback = callback; + } + } + + public static synchronized void setRunnerInfo(RunnerInfo info) { + if (callback != null) { + callback.accept(info); + callback = null; + } else { + RunnerNotification.info = info; + } + } + +} diff --git a/jvm-runtime/ftl-runtime/common/pom.xml b/jvm-runtime/ftl-runtime/common/pom.xml index 3aa2e02a32..74a2a85925 100644 --- a/jvm-runtime/ftl-runtime/common/pom.xml +++ b/jvm-runtime/ftl-runtime/common/pom.xml @@ -18,5 +18,6 @@ runtime bom build-parent + hotreload diff --git a/jvm-runtime/ftl-runtime/common/runtime/pom.xml b/jvm-runtime/ftl-runtime/common/runtime/pom.xml index 14f4eb9f14..133ed0e98e 100644 --- a/jvm-runtime/ftl-runtime/common/runtime/pom.xml +++ b/jvm-runtime/ftl-runtime/common/runtime/pom.xml @@ -12,6 +12,10 @@ FTL Java Runtime - Runtime + + xyz.block.ftl + ftl-jvm-hot-reload + io.quarkus quarkus-arc @@ -100,8 +104,8 @@ extension-descriptor - ${project.groupId}:${project.artifactId}-deployment:${project.version} - + ${project.groupId}:${project.artifactId}-deployment:${project.version} + xyz.block.ftl:ftl-jvm-hot-reload diff --git a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/runtime/DevModeRunnerDetails.java b/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/runtime/DevModeRunnerDetails.java index 36fc9235b4..6a31e86510 100644 --- a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/runtime/DevModeRunnerDetails.java +++ b/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/runtime/DevModeRunnerDetails.java @@ -1,69 +1,32 @@ package xyz.block.ftl.runtime; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.HashMap; import java.util.Map; import java.util.Optional; -import java.util.Properties; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import xyz.block.ftl.deployment.v1.GetDeploymentContextResponse; +import xyz.block.ftl.hotreload.RunnerInfo; +import xyz.block.ftl.hotreload.RunnerNotification; public class DevModeRunnerDetails implements RunnerDetails { - private final Path path; private volatile Map databases; private volatile String proxyAddress; private volatile String deployment; private volatile boolean closed; - private static final Pattern dbNames = Pattern.compile("database\\.([a-zA-Z0-9]+).url"); private volatile boolean loaded = false; - public DevModeRunnerDetails(Path path) { - this.path = path; - startWatchThread(); + public DevModeRunnerDetails() { + RunnerNotification.setCallback(this::setRunnerInfo); } - void startWatchThread() { - Thread watchThread = new Thread(() -> { - while (!closed) { - try { - Thread.sleep(100); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - if (Files.exists(path)) { - Properties p = new Properties(); - try (InputStream stream = Files.newInputStream(path)) { - p.load(stream); - synchronized (this) { - proxyAddress = p.getProperty("proxy.bind.address"); - deployment = p.getProperty("deployment"); - var dbs = new HashMap(); - for (var addr : p.stringPropertyNames()) { - Matcher m = dbNames.matcher(addr); - if (m.matches()) { - dbs.put(m.group(1), p.getProperty(addr)); - } - } - databases = dbs; - loaded = true; - notifyAll(); - return; - } - - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - }); - watchThread.setDaemon(true); - watchThread.start(); + private void setRunnerInfo(RunnerInfo runnerInfo) { + synchronized (this) { + proxyAddress = runnerInfo.address(); + deployment = runnerInfo.deployment(); + databases = runnerInfo.databases(); + loaded = true; + notifyAll(); + } } @Override diff --git a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/runtime/FTLController.java b/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/runtime/FTLController.java index 485272af46..cae787df34 100644 --- a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/runtime/FTLController.java +++ b/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/runtime/FTLController.java @@ -1,6 +1,5 @@ package xyz.block.ftl.runtime; -import java.nio.file.Path; import java.time.Duration; import java.util.List; import java.util.Map; @@ -94,7 +93,7 @@ public void readDevModeRunnerInfo() { runnerConnection = null; } runnerDetails.close(); - runnerDetails = new DevModeRunnerDetails(Path.of(System.getProperty(FTLRecorder.DEV_MODE_RUNNER_INFO_PATH))); + runnerDetails = new DevModeRunnerDetails(); haveRunnerInfo = true; this.notifyAll(); } diff --git a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/runtime/FTLRecorder.java b/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/runtime/FTLRecorder.java index a4db234ff3..07b38fd546 100644 --- a/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/runtime/FTLRecorder.java +++ b/jvm-runtime/ftl-runtime/common/runtime/src/main/java/xyz/block/ftl/runtime/FTLRecorder.java @@ -21,7 +21,6 @@ public class FTLRecorder { public static final String X_FTL_VERB = "X-ftl-verb"; - public static final String DEV_MODE_RUNNER_INFO_PATH = "ftl.dev.runner.info"; public void registerVerb(String module, String verbName, String methodName, List> parameterTypes, Class verbHandlerClass, List paramMappers, diff --git a/jvm-runtime/ftl-runtime/pom.xml b/jvm-runtime/ftl-runtime/pom.xml index c9e2333377..61426032c4 100644 --- a/jvm-runtime/ftl-runtime/pom.xml +++ b/jvm-runtime/ftl-runtime/pom.xml @@ -73,6 +73,11 @@ pom import + + xyz.block.ftl + ftl-jvm-hot-reload + ${project.version} + xyz.block.ftl ftl-jvm-runtime diff --git a/jvm-runtime/plugin/common/jvmcommon.go b/jvm-runtime/plugin/common/jvmcommon.go index b8fe5ba202..fc0c638b8b 100644 --- a/jvm-runtime/plugin/common/jvmcommon.go +++ b/jvm-runtime/plugin/common/jvmcommon.go @@ -250,6 +250,7 @@ func (s *Service) runDevMode(ctx context.Context, req *connect.Request[langpb.Bu err := s.runQuarkusDev(ctx, req, stream, first) first = false if err != nil { + log.FromContext(ctx).Errorf(err, "Dev mode process exited") return err } if !waitForFileChanges(ctx, fileEvents) { @@ -345,10 +346,8 @@ func (s *Service) runQuarkusDev(ctx context.Context, req *connect.Request[langpb } errorFile := filepath.Join(buildCtx.Config.DeployDir, ErrorFile) schemaFile := filepath.Join(buildCtx.Config.DeployDir, SchemaFile) - runnerInfoFile := filepath.Join(buildCtx.Config.Dir, ".ftl-runner-info") os.Remove(errorFile) os.Remove(schemaFile) - os.Remove(runnerInfoFile) errorHash := sha256.SHA256{} schemaHash := sha256.SHA256{} migrationHash := watch.FileHashes{} @@ -369,11 +368,11 @@ func (s *Service) runQuarkusDev(ctx context.Context, req *connect.Request[langpb if err == nil { devModeBuild = fmt.Sprintf("%s -Ddebug=%d", devModeBuild, debugPort.Port) } - protoPort, err := plugin.AllocatePort() + hotReloadPort, err := plugin.AllocatePort() if err != nil { return fmt.Errorf("could not allocate port: %w", err) } - devModeBuild = fmt.Sprintf("%s -Dftl.language.port=%d", devModeBuild, protoPort.Port) + devModeBuild = fmt.Sprintf("%s -Dftl.language.port=%d", devModeBuild, hotReloadPort.Port) if os.Getenv("FTL_SUSPEND") == "true" { devModeBuild += " -Dsuspend " @@ -381,8 +380,7 @@ func (s *Service) runQuarkusDev(ctx context.Context, req *connect.Request[langpb go func() { logger.Infof("Using dev mode build command '%s'", devModeBuild) command := exec.Command(ctx, log.Debug, buildCtx.Config.Dir, "bash", "-c", devModeBuild) - command.Env = append(command.Env, fmt.Sprintf("FTL_BIND=%s", bind)) - command.Env = append(command.Env, fmt.Sprintf("FTL_RUNNER_INFO=%s", runnerInfoFile)) + command.Env = append(command.Env, fmt.Sprintf("FTL_BIND=%s", bind), "MAVEN_OPTS=-Xmx1024m") command.Stdout = os.Stdout command.Stderr = os.Stderr err = command.Run() @@ -396,7 +394,8 @@ func (s *Service) runQuarkusDev(ctx context.Context, req *connect.Request[langpb forceUpdate := false // Wait for the plugin to start. - client := rpc.Dial(hotreloadpbconnect.NewHotReloadServiceClient, fmt.Sprintf("http://localhost:%d", protoPort.Port), log.Trace) + hotReloadEndpoint := fmt.Sprintf("http://localhost:%d", hotReloadPort.Port) + client := rpc.Dial(hotreloadpbconnect.NewHotReloadServiceClient, hotReloadEndpoint, log.Trace) err = rpc.Wait(ctx, backoff.Backoff{}, time.Minute, client) if err != nil { logger.Infof("Dev mode process failed to start") @@ -430,7 +429,7 @@ func (s *Service) runQuarkusDev(ctx context.Context, req *connect.Request[langpb if err != nil { return fmt.Errorf("failed to invoke hot reload for build context update %w", err) } - resp := s.toBuildResponse(result.Msg, &bc.buildCtx, false, devModeEndpoint, debugPort32, runnerInfoFile) + resp := s.toBuildResponse(result.Msg, &bc.buildCtx, false, devModeEndpoint, debugPort32, hotReloadEndpoint) if resp != nil { err = stream.Send(resp) } @@ -512,13 +511,13 @@ func (s *Service) runQuarkusDev(ctx context.Context, req *connect.Request[langpb err = stream.Send(&langpb.BuildResponse{ Event: &langpb.BuildResponse_BuildSuccess{ BuildSuccess: &langpb.BuildSuccess{ - ContextId: buildCtx.ID, - IsAutomaticRebuild: auto, - Module: moduleProto, - DevEndpoint: ptr(devModeEndpoint), - DevRunnerInfoFile: &runnerInfoFile, - DebugPort: &debugPort32, - Deploy: []string{SchemaFile}, + ContextId: buildCtx.ID, + IsAutomaticRebuild: auto, + Module: moduleProto, + DevEndpoint: ptr(devModeEndpoint), + DevHotReloadEndpoint: ptr(hotReloadEndpoint), + DebugPort: &debugPort32, + Deploy: []string{SchemaFile}, }, }, }) @@ -970,19 +969,19 @@ func (s *Service) writeGenericSchemaFiles(ctx context.Context, v *schema.Schema, return nil } -func (s *Service) toBuildResponse(result *hotreloadpb.ReloadResponse, bc *buildContext, auto bool, devEndpoint string, debugPort int32, devRunnerInfoFile string) (ret *langpb.BuildResponse) { +func (s *Service) toBuildResponse(result *hotreloadpb.ReloadResponse, bc *buildContext, auto bool, devEndpoint string, debugPort int32, hotReloadAddress string) (ret *langpb.BuildResponse) { ret = &langpb.BuildResponse{} switch e := result.Event.(type) { case *hotreloadpb.ReloadResponse_ReloadSuccess: ret.Event = &langpb.BuildResponse_BuildSuccess{ BuildSuccess: &langpb.BuildSuccess{ - ContextId: bc.ID, - IsAutomaticRebuild: auto, - Module: e.ReloadSuccess.Module, - Errors: e.ReloadSuccess.Errors, - DevEndpoint: &devEndpoint, - DebugPort: &debugPort, - DevRunnerInfoFile: &devRunnerInfoFile, + ContextId: bc.ID, + IsAutomaticRebuild: auto, + Module: e.ReloadSuccess.Module, + Errors: e.ReloadSuccess.Errors, + DevEndpoint: &devEndpoint, + DebugPort: &debugPort, + DevHotReloadEndpoint: &hotReloadAddress, }, } diff --git a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/hotreload/v1/hotreload_pb2.py b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/hotreload/v1/hotreload_pb2.py index 6f1e1a3430..5220f45a7d 100644 --- a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/hotreload/v1/hotreload_pb2.py +++ b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/hotreload/v1/hotreload_pb2.py @@ -27,7 +27,7 @@ from xyz.block.ftl.v1 import ftl_pb2 as xyz_dot_block_dot_ftl_dot_v1_dot_ftl__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n*xyz/block/ftl/hotreload/v1/hotreload.proto\x12\x1axyz.block.ftl.hotreload.v1\x1a(xyz/block/ftl/language/v1/language.proto\x1a$xyz/block/ftl/schema/v1/schema.proto\x1a\x1axyz/block/ftl/v1/ftl.proto\"%\n\rReloadRequest\x12\x14\n\x05\x66orce\x18\x01 \x01(\x08R\x05\x66orce\"\x9f\x02\n\x0eReloadResponse\x12_\n\x13reload_not_required\x18\x01 \x01(\x0b\x32-.xyz.block.ftl.hotreload.v1.ReloadNotRequiredH\x00R\x11reloadNotRequired\x12R\n\x0ereload_success\x18\x02 \x01(\x0b\x32).xyz.block.ftl.hotreload.v1.ReloadSuccessH\x00R\rreloadSuccess\x12O\n\rreload_failed\x18\x03 \x01(\x0b\x32(.xyz.block.ftl.hotreload.v1.ReloadFailedH\x00R\x0creloadFailedB\x07\n\x05\x65vent\"\x0e\n\x0cWatchRequest\"\xbd\x01\n\rWatchResponse\x12R\n\x0ereload_success\x18\x01 \x01(\x0b\x32).xyz.block.ftl.hotreload.v1.ReloadSuccessH\x00R\rreloadSuccess\x12O\n\rreload_failed\x18\x02 \x01(\x0b\x32(.xyz.block.ftl.hotreload.v1.ReloadFailedH\x00R\x0creloadFailedB\x07\n\x05\x65vent\"\x13\n\x11ReloadNotRequired\"\x86\x01\n\rReloadSuccess\x12\x37\n\x06module\x18\x01 \x01(\x0b\x32\x1f.xyz.block.ftl.schema.v1.ModuleR\x06module\x12<\n\x06\x65rrors\x18\x02 \x01(\x0b\x32$.xyz.block.ftl.language.v1.ErrorListR\x06\x65rrors\"L\n\x0cReloadFailed\x12<\n\x06\x65rrors\x18\x01 \x01(\x0b\x32$.xyz.block.ftl.language.v1.ErrorListR\x06\x65rrors2\x9f\x02\n\x10HotReloadService\x12J\n\x04Ping\x12\x1d.xyz.block.ftl.v1.PingRequest\x1a\x1e.xyz.block.ftl.v1.PingResponse\"\x03\x90\x02\x01\x12_\n\x06Reload\x12).xyz.block.ftl.hotreload.v1.ReloadRequest\x1a*.xyz.block.ftl.hotreload.v1.ReloadResponse\x12^\n\x05Watch\x12(.xyz.block.ftl.hotreload.v1.WatchRequest\x1a).xyz.block.ftl.hotreload.v1.WatchResponse0\x01\x42NP\x01ZJgithub.com/block/ftl/backend/protos/xyz/block/ftl/hotreload/v1;hotreloadpbb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n*xyz/block/ftl/hotreload/v1/hotreload.proto\x12\x1axyz.block.ftl.hotreload.v1\x1a(xyz/block/ftl/language/v1/language.proto\x1a$xyz/block/ftl/schema/v1/schema.proto\x1a\x1axyz/block/ftl/v1/ftl.proto\"%\n\rReloadRequest\x12\x14\n\x05\x66orce\x18\x01 \x01(\x08R\x05\x66orce\"\x9f\x02\n\x0eReloadResponse\x12_\n\x13reload_not_required\x18\x01 \x01(\x0b\x32-.xyz.block.ftl.hotreload.v1.ReloadNotRequiredH\x00R\x11reloadNotRequired\x12R\n\x0ereload_success\x18\x02 \x01(\x0b\x32).xyz.block.ftl.hotreload.v1.ReloadSuccessH\x00R\rreloadSuccess\x12O\n\rreload_failed\x18\x03 \x01(\x0b\x32(.xyz.block.ftl.hotreload.v1.ReloadFailedH\x00R\x0creloadFailedB\x07\n\x05\x65vent\"\x0e\n\x0cWatchRequest\"\xbd\x01\n\rWatchResponse\x12R\n\x0ereload_success\x18\x01 \x01(\x0b\x32).xyz.block.ftl.hotreload.v1.ReloadSuccessH\x00R\rreloadSuccess\x12O\n\rreload_failed\x18\x02 \x01(\x0b\x32(.xyz.block.ftl.hotreload.v1.ReloadFailedH\x00R\x0creloadFailedB\x07\n\x05\x65vent\"\x91\x01\n\x11RunnerInfoRequest\x12\x18\n\x07\x61\x64\x64ress\x18\x01 \x01(\tR\x07\x61\x64\x64ress\x12\x1e\n\ndeployment\x18\x02 \x01(\tR\ndeployment\x12\x42\n\tdatabases\x18\x03 \x03(\x0b\x32$.xyz.block.ftl.hotreload.v1.DatabaseR\tdatabases\"8\n\x08\x44\x61tabase\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n\x07\x61\x64\x64ress\x18\x02 \x01(\tR\x07\x61\x64\x64ress\"\x14\n\x12RunnerInfoResponse\"\x13\n\x11ReloadNotRequired\"\x86\x01\n\rReloadSuccess\x12\x37\n\x06module\x18\x01 \x01(\x0b\x32\x1f.xyz.block.ftl.schema.v1.ModuleR\x06module\x12<\n\x06\x65rrors\x18\x02 \x01(\x0b\x32$.xyz.block.ftl.language.v1.ErrorListR\x06\x65rrors\"L\n\x0cReloadFailed\x12<\n\x06\x65rrors\x18\x01 \x01(\x0b\x32$.xyz.block.ftl.language.v1.ErrorListR\x06\x65rrors2\x8c\x03\n\x10HotReloadService\x12J\n\x04Ping\x12\x1d.xyz.block.ftl.v1.PingRequest\x1a\x1e.xyz.block.ftl.v1.PingResponse\"\x03\x90\x02\x01\x12_\n\x06Reload\x12).xyz.block.ftl.hotreload.v1.ReloadRequest\x1a*.xyz.block.ftl.hotreload.v1.ReloadResponse\x12^\n\x05Watch\x12(.xyz.block.ftl.hotreload.v1.WatchRequest\x1a).xyz.block.ftl.hotreload.v1.WatchResponse0\x01\x12k\n\nRunnerInfo\x12-.xyz.block.ftl.hotreload.v1.RunnerInfoRequest\x1a..xyz.block.ftl.hotreload.v1.RunnerInfoResponseBNP\x01ZJgithub.com/block/ftl/backend/protos/xyz/block/ftl/hotreload/v1;hotreloadpbb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -45,12 +45,18 @@ _globals['_WATCHREQUEST']._serialized_end=525 _globals['_WATCHRESPONSE']._serialized_start=528 _globals['_WATCHRESPONSE']._serialized_end=717 - _globals['_RELOADNOTREQUIRED']._serialized_start=719 - _globals['_RELOADNOTREQUIRED']._serialized_end=738 - _globals['_RELOADSUCCESS']._serialized_start=741 - _globals['_RELOADSUCCESS']._serialized_end=875 - _globals['_RELOADFAILED']._serialized_start=877 - _globals['_RELOADFAILED']._serialized_end=953 - _globals['_HOTRELOADSERVICE']._serialized_start=956 - _globals['_HOTRELOADSERVICE']._serialized_end=1243 + _globals['_RUNNERINFOREQUEST']._serialized_start=720 + _globals['_RUNNERINFOREQUEST']._serialized_end=865 + _globals['_DATABASE']._serialized_start=867 + _globals['_DATABASE']._serialized_end=923 + _globals['_RUNNERINFORESPONSE']._serialized_start=925 + _globals['_RUNNERINFORESPONSE']._serialized_end=945 + _globals['_RELOADNOTREQUIRED']._serialized_start=947 + _globals['_RELOADNOTREQUIRED']._serialized_end=966 + _globals['_RELOADSUCCESS']._serialized_start=969 + _globals['_RELOADSUCCESS']._serialized_end=1103 + _globals['_RELOADFAILED']._serialized_start=1105 + _globals['_RELOADFAILED']._serialized_end=1181 + _globals['_HOTRELOADSERVICE']._serialized_start=1184 + _globals['_HOTRELOADSERVICE']._serialized_end=1580 # @@protoc_insertion_point(module_scope) diff --git a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/hotreload/v1/hotreload_pb2.pyi b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/hotreload/v1/hotreload_pb2.pyi index 0f389ae504..85a63be648 100644 --- a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/hotreload/v1/hotreload_pb2.pyi +++ b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/hotreload/v1/hotreload_pb2.pyi @@ -1,9 +1,10 @@ from xyz.block.ftl.language.v1 import language_pb2 as _language_pb2 from xyz.block.ftl.schema.v1 import schema_pb2 as _schema_pb2 from xyz.block.ftl.v1 import ftl_pb2 as _ftl_pb2 +from google.protobuf.internal import containers as _containers from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message -from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union +from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union DESCRIPTOR: _descriptor.FileDescriptor @@ -35,6 +36,28 @@ class WatchResponse(_message.Message): reload_failed: ReloadFailed def __init__(self, reload_success: _Optional[_Union[ReloadSuccess, _Mapping]] = ..., reload_failed: _Optional[_Union[ReloadFailed, _Mapping]] = ...) -> None: ... +class RunnerInfoRequest(_message.Message): + __slots__ = ("address", "deployment", "databases") + ADDRESS_FIELD_NUMBER: _ClassVar[int] + DEPLOYMENT_FIELD_NUMBER: _ClassVar[int] + DATABASES_FIELD_NUMBER: _ClassVar[int] + address: str + deployment: str + databases: _containers.RepeatedCompositeFieldContainer[Database] + def __init__(self, address: _Optional[str] = ..., deployment: _Optional[str] = ..., databases: _Optional[_Iterable[_Union[Database, _Mapping]]] = ...) -> None: ... + +class Database(_message.Message): + __slots__ = ("name", "address") + NAME_FIELD_NUMBER: _ClassVar[int] + ADDRESS_FIELD_NUMBER: _ClassVar[int] + name: str + address: str + def __init__(self, name: _Optional[str] = ..., address: _Optional[str] = ...) -> None: ... + +class RunnerInfoResponse(_message.Message): + __slots__ = () + def __init__(self) -> None: ... + class ReloadNotRequired(_message.Message): __slots__ = () def __init__(self) -> None: ... diff --git a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/language/v1/language_pb2.py b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/language/v1/language_pb2.py index 78895592e7..57c2328990 100644 --- a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/language/v1/language_pb2.py +++ b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/language/v1/language_pb2.py @@ -27,7 +27,7 @@ from xyz.block.ftl.v1 import ftl_pb2 as xyz_dot_block_dot_ftl_dot_v1_dot_ftl__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n(xyz/block/ftl/language/v1/language.proto\x12\x19xyz.block.ftl.language.v1\x1a\x1cgoogle/protobuf/struct.proto\x1a$xyz/block/ftl/schema/v1/schema.proto\x1a\x1axyz/block/ftl/v1/ftl.proto\"\x99\x03\n\x0cModuleConfig\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x10\n\x03\x64ir\x18\x02 \x01(\tR\x03\x64ir\x12\x1a\n\x08language\x18\x03 \x01(\tR\x08language\x12\x1d\n\ndeploy_dir\x18\x04 \x01(\tR\tdeployDir\x12\x19\n\x05\x62uild\x18\x05 \x01(\tH\x00R\x05\x62uild\x88\x01\x01\x12)\n\x0e\x64\x65v_mode_build\x18\x06 \x01(\tH\x01R\x0c\x64\x65vModeBuild\x88\x01\x01\x12\x1d\n\nbuild_lock\x18\x07 \x01(\tR\tbuildLock\x12\x14\n\x05watch\x18\t \x03(\tR\x05watch\x12@\n\x0flanguage_config\x18\n \x01(\x0b\x32\x17.google.protobuf.StructR\x0elanguageConfig\x12*\n\x11sql_migration_dir\x18\x0b \x01(\tR\x0fsqlMigrationDir\x12\"\n\rsql_query_dir\x18\x0c \x01(\tR\x0bsqlQueryDirB\x08\n\x06_buildB\x11\n\x0f_dev_mode_build\"d\n\rProjectConfig\x12\x10\n\x03\x64ir\x18\x01 \x01(\tR\x03\x64ir\x12\x12\n\x04name\x18\x02 \x01(\tR\x04name\x12\x15\n\x06no_git\x18\x03 \x01(\x08R\x05noGit\x12\x16\n\x06hermit\x18\x04 \x01(\x08R\x06hermit\"9\n\x1bGetCreateModuleFlagsRequest\x12\x1a\n\x08language\x18\x01 \x01(\tR\x08language\"\xcf\x02\n\x1cGetCreateModuleFlagsResponse\x12R\n\x05\x66lags\x18\x01 \x03(\x0b\x32<.xyz.block.ftl.language.v1.GetCreateModuleFlagsResponse.FlagR\x05\x66lags\x1a\xda\x01\n\x04\x46lag\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n\x04help\x18\x02 \x01(\tR\x04help\x12\x19\n\x05\x65nvar\x18\x03 \x01(\tH\x00R\x05\x65nvar\x88\x01\x01\x12\x19\n\x05short\x18\x04 \x01(\tH\x01R\x05short\x88\x01\x01\x12%\n\x0bplaceholder\x18\x05 \x01(\tH\x02R\x0bplaceholder\x88\x01\x01\x12\x1d\n\x07\x64\x65\x66\x61ult\x18\x06 \x01(\tH\x03R\x07\x64\x65\x66\x61ult\x88\x01\x01\x42\x08\n\x06_envarB\x08\n\x06_shortB\x0e\n\x0c_placeholderB\n\n\x08_default\"\xbb\x01\n\x13\x43reateModuleRequest\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x10\n\x03\x64ir\x18\x02 \x01(\tR\x03\x64ir\x12O\n\x0eproject_config\x18\x03 \x01(\x0b\x32(.xyz.block.ftl.language.v1.ProjectConfigR\rprojectConfig\x12-\n\x05\x66lags\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructR\x05\x66lags\"\x16\n\x14\x43reateModuleResponse\"/\n\x1bModuleConfigDefaultsRequest\x12\x10\n\x03\x64ir\x18\x01 \x01(\tR\x03\x64ir\"\xfb\x02\n\x1cModuleConfigDefaultsResponse\x12\x1d\n\ndeploy_dir\x18\x01 \x01(\tR\tdeployDir\x12\x19\n\x05\x62uild\x18\x02 \x01(\tH\x00R\x05\x62uild\x88\x01\x01\x12)\n\x0e\x64\x65v_mode_build\x18\x03 \x01(\tH\x01R\x0c\x64\x65vModeBuild\x88\x01\x01\x12\"\n\nbuild_lock\x18\x04 \x01(\tH\x02R\tbuildLock\x88\x01\x01\x12\x14\n\x05watch\x18\x06 \x03(\tR\x05watch\x12@\n\x0flanguage_config\x18\x07 \x01(\x0b\x32\x17.google.protobuf.StructR\x0elanguageConfig\x12*\n\x11sql_migration_dir\x18\x08 \x01(\tR\x0fsqlMigrationDir\x12\"\n\rsql_query_dir\x18\t \x01(\tR\x0bsqlQueryDirB\x08\n\x06_buildB\x11\n\x0f_dev_mode_buildB\r\n\x0b_build_lock\"f\n\x16GetDependenciesRequest\x12L\n\rmodule_config\x18\x01 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.ModuleConfigR\x0cmoduleConfig\"3\n\x17GetDependenciesResponse\x12\x18\n\x07modules\x18\x01 \x03(\tR\x07modules\"\xe6\x01\n\x0c\x42uildContext\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12L\n\rmodule_config\x18\x02 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.ModuleConfigR\x0cmoduleConfig\x12\x37\n\x06schema\x18\x03 \x01(\x0b\x32\x1f.xyz.block.ftl.schema.v1.SchemaR\x06schema\x12\"\n\x0c\x64\x65pendencies\x18\x04 \x03(\tR\x0c\x64\x65pendencies\x12\x1b\n\tbuild_env\x18\x05 \x03(\tR\x08\x62uildEnv\"j\n\x1a\x42uildContextUpdatedRequest\x12L\n\rbuild_context\x18\x01 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.BuildContextR\x0c\x62uildContext\"\x1d\n\x1b\x42uildContextUpdatedResponse\"\xa4\x03\n\x05\x45rror\x12\x10\n\x03msg\x18\x01 \x01(\tR\x03msg\x12\x41\n\x05level\x18\x04 \x01(\x0e\x32+.xyz.block.ftl.language.v1.Error.ErrorLevelR\x05level\x12:\n\x03pos\x18\x05 \x01(\x0b\x32#.xyz.block.ftl.language.v1.PositionH\x00R\x03pos\x88\x01\x01\x12>\n\x04type\x18\x06 \x01(\x0e\x32*.xyz.block.ftl.language.v1.Error.ErrorTypeR\x04type\"l\n\nErrorLevel\x12\x1b\n\x17\x45RROR_LEVEL_UNSPECIFIED\x10\x00\x12\x14\n\x10\x45RROR_LEVEL_INFO\x10\x01\x12\x14\n\x10\x45RROR_LEVEL_WARN\x10\x02\x12\x15\n\x11\x45RROR_LEVEL_ERROR\x10\x03\"T\n\tErrorType\x12\x1a\n\x16\x45RROR_TYPE_UNSPECIFIED\x10\x00\x12\x12\n\x0e\x45RROR_TYPE_FTL\x10\x01\x12\x17\n\x13\x45RROR_TYPE_COMPILER\x10\x02\x42\x06\n\x04_pos\"|\n\x08Position\x12\x1a\n\x08\x66ilename\x18\x01 \x01(\tR\x08\x66ilename\x12\x12\n\x04line\x18\x02 \x01(\x03R\x04line\x12!\n\x0cstart_column\x18\x03 \x01(\x03R\x0bstartColumn\x12\x1d\n\nend_column\x18\x04 \x01(\x03R\tendColumn\"E\n\tErrorList\x12\x38\n\x06\x65rrors\x18\x01 \x03(\x0b\x32 .xyz.block.ftl.language.v1.ErrorR\x06\x65rrors\"\xd3\x01\n\x0c\x42uildRequest\x12!\n\x0cproject_root\x18\x01 \x01(\tR\x0bprojectRoot\x12\x1d\n\nstubs_root\x18\x02 \x01(\tR\tstubsRoot\x12\x33\n\x15rebuild_automatically\x18\x03 \x01(\x08R\x14rebuildAutomatically\x12L\n\rbuild_context\x18\x04 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.BuildContextR\x0c\x62uildContext\"3\n\x12\x41utoRebuildStarted\x12\x1d\n\ncontext_id\x18\x01 \x01(\tR\tcontextId\"\xcc\x03\n\x0c\x42uildSuccess\x12\x1d\n\ncontext_id\x18\x01 \x01(\tR\tcontextId\x12\x30\n\x14is_automatic_rebuild\x18\x02 \x01(\x08R\x12isAutomaticRebuild\x12\x37\n\x06module\x18\x03 \x01(\x0b\x32\x1f.xyz.block.ftl.schema.v1.ModuleR\x06module\x12\x16\n\x06\x64\x65ploy\x18\x04 \x03(\tR\x06\x64\x65ploy\x12!\n\x0c\x64ocker_image\x18\x05 \x01(\tR\x0b\x64ockerImage\x12<\n\x06\x65rrors\x18\x06 \x01(\x0b\x32$.xyz.block.ftl.language.v1.ErrorListR\x06\x65rrors\x12&\n\x0c\x64\x65v_endpoint\x18\x07 \x01(\tH\x00R\x0b\x64\x65vEndpoint\x88\x01\x01\x12\"\n\ndebug_port\x18\x08 \x01(\x05H\x01R\tdebugPort\x88\x01\x01\x12\x34\n\x14\x64\x65v_runner_info_file\x18\t \x01(\tH\x02R\x11\x64\x65vRunnerInfoFile\x88\x01\x01\x42\x0f\n\r_dev_endpointB\r\n\x0b_debug_portB\x17\n\x15_dev_runner_info_file\"\xd6\x01\n\x0c\x42uildFailure\x12\x1d\n\ncontext_id\x18\x01 \x01(\tR\tcontextId\x12\x30\n\x14is_automatic_rebuild\x18\x02 \x01(\x08R\x12isAutomaticRebuild\x12<\n\x06\x65rrors\x18\x03 \x01(\x0b\x32$.xyz.block.ftl.language.v1.ErrorListR\x06\x65rrors\x12\x37\n\x17invalidate_dependencies\x18\x04 \x01(\x08R\x16invalidateDependencies\"\x9b\x02\n\rBuildResponse\x12\x61\n\x14\x61uto_rebuild_started\x18\x02 \x01(\x0b\x32-.xyz.block.ftl.language.v1.AutoRebuildStartedH\x00R\x12\x61utoRebuildStarted\x12N\n\rbuild_success\x18\x03 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.BuildSuccessH\x00R\x0c\x62uildSuccess\x12N\n\rbuild_failure\x18\x04 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.BuildFailureH\x00R\x0c\x62uildFailureB\x07\n\x05\x65vent\"\xa8\x02\n\x14GenerateStubsRequest\x12\x10\n\x03\x64ir\x18\x01 \x01(\tR\x03\x64ir\x12\x37\n\x06module\x18\x02 \x01(\x0b\x32\x1f.xyz.block.ftl.schema.v1.ModuleR\x06module\x12L\n\rmodule_config\x18\x03 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.ModuleConfigR\x0cmoduleConfig\x12^\n\x14native_module_config\x18\x04 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.ModuleConfigH\x00R\x12nativeModuleConfig\x88\x01\x01\x42\x17\n\x15_native_module_config\"\x17\n\x15GenerateStubsResponse\"\xdb\x01\n\x19SyncStubReferencesRequest\x12L\n\rmodule_config\x18\x01 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.ModuleConfigR\x0cmoduleConfig\x12\x1d\n\nstubs_root\x18\x02 \x01(\tR\tstubsRoot\x12\x18\n\x07modules\x18\x03 \x03(\tR\x07modules\x12\x37\n\x06schema\x18\x04 \x01(\x0b\x32\x1f.xyz.block.ftl.schema.v1.SchemaR\x06schema\"\x1c\n\x1aSyncStubReferencesResponse2\xb9\x08\n\x0fLanguageService\x12J\n\x04Ping\x12\x1d.xyz.block.ftl.v1.PingRequest\x1a\x1e.xyz.block.ftl.v1.PingResponse\"\x03\x90\x02\x01\x12\x87\x01\n\x14GetCreateModuleFlags\x12\x36.xyz.block.ftl.language.v1.GetCreateModuleFlagsRequest\x1a\x37.xyz.block.ftl.language.v1.GetCreateModuleFlagsResponse\x12o\n\x0c\x43reateModule\x12..xyz.block.ftl.language.v1.CreateModuleRequest\x1a/.xyz.block.ftl.language.v1.CreateModuleResponse\x12\x87\x01\n\x14ModuleConfigDefaults\x12\x36.xyz.block.ftl.language.v1.ModuleConfigDefaultsRequest\x1a\x37.xyz.block.ftl.language.v1.ModuleConfigDefaultsResponse\x12x\n\x0fGetDependencies\x12\x31.xyz.block.ftl.language.v1.GetDependenciesRequest\x1a\x32.xyz.block.ftl.language.v1.GetDependenciesResponse\x12\\\n\x05\x42uild\x12\'.xyz.block.ftl.language.v1.BuildRequest\x1a(.xyz.block.ftl.language.v1.BuildResponse0\x01\x12\x84\x01\n\x13\x42uildContextUpdated\x12\x35.xyz.block.ftl.language.v1.BuildContextUpdatedRequest\x1a\x36.xyz.block.ftl.language.v1.BuildContextUpdatedResponse\x12r\n\rGenerateStubs\x12/.xyz.block.ftl.language.v1.GenerateStubsRequest\x1a\x30.xyz.block.ftl.language.v1.GenerateStubsResponse\x12\x81\x01\n\x12SyncStubReferences\x12\x34.xyz.block.ftl.language.v1.SyncStubReferencesRequest\x1a\x35.xyz.block.ftl.language.v1.SyncStubReferencesResponseBLP\x01ZHgithub.com/block/ftl/backend/protos/xyz/block/ftl/language/v1;languagepbb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n(xyz/block/ftl/language/v1/language.proto\x12\x19xyz.block.ftl.language.v1\x1a\x1cgoogle/protobuf/struct.proto\x1a$xyz/block/ftl/schema/v1/schema.proto\x1a\x1axyz/block/ftl/v1/ftl.proto\"\x99\x03\n\x0cModuleConfig\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x10\n\x03\x64ir\x18\x02 \x01(\tR\x03\x64ir\x12\x1a\n\x08language\x18\x03 \x01(\tR\x08language\x12\x1d\n\ndeploy_dir\x18\x04 \x01(\tR\tdeployDir\x12\x19\n\x05\x62uild\x18\x05 \x01(\tH\x00R\x05\x62uild\x88\x01\x01\x12)\n\x0e\x64\x65v_mode_build\x18\x06 \x01(\tH\x01R\x0c\x64\x65vModeBuild\x88\x01\x01\x12\x1d\n\nbuild_lock\x18\x07 \x01(\tR\tbuildLock\x12\x14\n\x05watch\x18\t \x03(\tR\x05watch\x12@\n\x0flanguage_config\x18\n \x01(\x0b\x32\x17.google.protobuf.StructR\x0elanguageConfig\x12*\n\x11sql_migration_dir\x18\x0b \x01(\tR\x0fsqlMigrationDir\x12\"\n\rsql_query_dir\x18\x0c \x01(\tR\x0bsqlQueryDirB\x08\n\x06_buildB\x11\n\x0f_dev_mode_build\"d\n\rProjectConfig\x12\x10\n\x03\x64ir\x18\x01 \x01(\tR\x03\x64ir\x12\x12\n\x04name\x18\x02 \x01(\tR\x04name\x12\x15\n\x06no_git\x18\x03 \x01(\x08R\x05noGit\x12\x16\n\x06hermit\x18\x04 \x01(\x08R\x06hermit\"9\n\x1bGetCreateModuleFlagsRequest\x12\x1a\n\x08language\x18\x01 \x01(\tR\x08language\"\xcf\x02\n\x1cGetCreateModuleFlagsResponse\x12R\n\x05\x66lags\x18\x01 \x03(\x0b\x32<.xyz.block.ftl.language.v1.GetCreateModuleFlagsResponse.FlagR\x05\x66lags\x1a\xda\x01\n\x04\x46lag\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n\x04help\x18\x02 \x01(\tR\x04help\x12\x19\n\x05\x65nvar\x18\x03 \x01(\tH\x00R\x05\x65nvar\x88\x01\x01\x12\x19\n\x05short\x18\x04 \x01(\tH\x01R\x05short\x88\x01\x01\x12%\n\x0bplaceholder\x18\x05 \x01(\tH\x02R\x0bplaceholder\x88\x01\x01\x12\x1d\n\x07\x64\x65\x66\x61ult\x18\x06 \x01(\tH\x03R\x07\x64\x65\x66\x61ult\x88\x01\x01\x42\x08\n\x06_envarB\x08\n\x06_shortB\x0e\n\x0c_placeholderB\n\n\x08_default\"\xbb\x01\n\x13\x43reateModuleRequest\x12\x12\n\x04name\x18\x01 \x01(\tR\x04name\x12\x10\n\x03\x64ir\x18\x02 \x01(\tR\x03\x64ir\x12O\n\x0eproject_config\x18\x03 \x01(\x0b\x32(.xyz.block.ftl.language.v1.ProjectConfigR\rprojectConfig\x12-\n\x05\x66lags\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructR\x05\x66lags\"\x16\n\x14\x43reateModuleResponse\"/\n\x1bModuleConfigDefaultsRequest\x12\x10\n\x03\x64ir\x18\x01 \x01(\tR\x03\x64ir\"\xfb\x02\n\x1cModuleConfigDefaultsResponse\x12\x1d\n\ndeploy_dir\x18\x01 \x01(\tR\tdeployDir\x12\x19\n\x05\x62uild\x18\x02 \x01(\tH\x00R\x05\x62uild\x88\x01\x01\x12)\n\x0e\x64\x65v_mode_build\x18\x03 \x01(\tH\x01R\x0c\x64\x65vModeBuild\x88\x01\x01\x12\"\n\nbuild_lock\x18\x04 \x01(\tH\x02R\tbuildLock\x88\x01\x01\x12\x14\n\x05watch\x18\x06 \x03(\tR\x05watch\x12@\n\x0flanguage_config\x18\x07 \x01(\x0b\x32\x17.google.protobuf.StructR\x0elanguageConfig\x12*\n\x11sql_migration_dir\x18\x08 \x01(\tR\x0fsqlMigrationDir\x12\"\n\rsql_query_dir\x18\t \x01(\tR\x0bsqlQueryDirB\x08\n\x06_buildB\x11\n\x0f_dev_mode_buildB\r\n\x0b_build_lock\"f\n\x16GetDependenciesRequest\x12L\n\rmodule_config\x18\x01 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.ModuleConfigR\x0cmoduleConfig\"3\n\x17GetDependenciesResponse\x12\x18\n\x07modules\x18\x01 \x03(\tR\x07modules\"\xe6\x01\n\x0c\x42uildContext\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12L\n\rmodule_config\x18\x02 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.ModuleConfigR\x0cmoduleConfig\x12\x37\n\x06schema\x18\x03 \x01(\x0b\x32\x1f.xyz.block.ftl.schema.v1.SchemaR\x06schema\x12\"\n\x0c\x64\x65pendencies\x18\x04 \x03(\tR\x0c\x64\x65pendencies\x12\x1b\n\tbuild_env\x18\x05 \x03(\tR\x08\x62uildEnv\"j\n\x1a\x42uildContextUpdatedRequest\x12L\n\rbuild_context\x18\x01 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.BuildContextR\x0c\x62uildContext\"\x1d\n\x1b\x42uildContextUpdatedResponse\"\xa4\x03\n\x05\x45rror\x12\x10\n\x03msg\x18\x01 \x01(\tR\x03msg\x12\x41\n\x05level\x18\x04 \x01(\x0e\x32+.xyz.block.ftl.language.v1.Error.ErrorLevelR\x05level\x12:\n\x03pos\x18\x05 \x01(\x0b\x32#.xyz.block.ftl.language.v1.PositionH\x00R\x03pos\x88\x01\x01\x12>\n\x04type\x18\x06 \x01(\x0e\x32*.xyz.block.ftl.language.v1.Error.ErrorTypeR\x04type\"l\n\nErrorLevel\x12\x1b\n\x17\x45RROR_LEVEL_UNSPECIFIED\x10\x00\x12\x14\n\x10\x45RROR_LEVEL_INFO\x10\x01\x12\x14\n\x10\x45RROR_LEVEL_WARN\x10\x02\x12\x15\n\x11\x45RROR_LEVEL_ERROR\x10\x03\"T\n\tErrorType\x12\x1a\n\x16\x45RROR_TYPE_UNSPECIFIED\x10\x00\x12\x12\n\x0e\x45RROR_TYPE_FTL\x10\x01\x12\x17\n\x13\x45RROR_TYPE_COMPILER\x10\x02\x42\x06\n\x04_pos\"|\n\x08Position\x12\x1a\n\x08\x66ilename\x18\x01 \x01(\tR\x08\x66ilename\x12\x12\n\x04line\x18\x02 \x01(\x03R\x04line\x12!\n\x0cstart_column\x18\x03 \x01(\x03R\x0bstartColumn\x12\x1d\n\nend_column\x18\x04 \x01(\x03R\tendColumn\"E\n\tErrorList\x12\x38\n\x06\x65rrors\x18\x01 \x03(\x0b\x32 .xyz.block.ftl.language.v1.ErrorR\x06\x65rrors\"\xd3\x01\n\x0c\x42uildRequest\x12!\n\x0cproject_root\x18\x01 \x01(\tR\x0bprojectRoot\x12\x1d\n\nstubs_root\x18\x02 \x01(\tR\tstubsRoot\x12\x33\n\x15rebuild_automatically\x18\x03 \x01(\x08R\x14rebuildAutomatically\x12L\n\rbuild_context\x18\x04 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.BuildContextR\x0c\x62uildContext\"3\n\x12\x41utoRebuildStarted\x12\x1d\n\ncontext_id\x18\x01 \x01(\tR\tcontextId\"\xd5\x03\n\x0c\x42uildSuccess\x12\x1d\n\ncontext_id\x18\x01 \x01(\tR\tcontextId\x12\x30\n\x14is_automatic_rebuild\x18\x02 \x01(\x08R\x12isAutomaticRebuild\x12\x37\n\x06module\x18\x03 \x01(\x0b\x32\x1f.xyz.block.ftl.schema.v1.ModuleR\x06module\x12\x16\n\x06\x64\x65ploy\x18\x04 \x03(\tR\x06\x64\x65ploy\x12!\n\x0c\x64ocker_image\x18\x05 \x01(\tR\x0b\x64ockerImage\x12<\n\x06\x65rrors\x18\x06 \x01(\x0b\x32$.xyz.block.ftl.language.v1.ErrorListR\x06\x65rrors\x12&\n\x0c\x64\x65v_endpoint\x18\x07 \x01(\tH\x00R\x0b\x64\x65vEndpoint\x88\x01\x01\x12\"\n\ndebug_port\x18\x08 \x01(\x05H\x01R\tdebugPort\x88\x01\x01\x12:\n\x17\x64\x65v_hot_reload_endpoint\x18\t \x01(\tH\x02R\x14\x64\x65vHotReloadEndpoint\x88\x01\x01\x42\x0f\n\r_dev_endpointB\r\n\x0b_debug_portB\x1a\n\x18_dev_hot_reload_endpoint\"\xd6\x01\n\x0c\x42uildFailure\x12\x1d\n\ncontext_id\x18\x01 \x01(\tR\tcontextId\x12\x30\n\x14is_automatic_rebuild\x18\x02 \x01(\x08R\x12isAutomaticRebuild\x12<\n\x06\x65rrors\x18\x03 \x01(\x0b\x32$.xyz.block.ftl.language.v1.ErrorListR\x06\x65rrors\x12\x37\n\x17invalidate_dependencies\x18\x04 \x01(\x08R\x16invalidateDependencies\"\x9b\x02\n\rBuildResponse\x12\x61\n\x14\x61uto_rebuild_started\x18\x02 \x01(\x0b\x32-.xyz.block.ftl.language.v1.AutoRebuildStartedH\x00R\x12\x61utoRebuildStarted\x12N\n\rbuild_success\x18\x03 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.BuildSuccessH\x00R\x0c\x62uildSuccess\x12N\n\rbuild_failure\x18\x04 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.BuildFailureH\x00R\x0c\x62uildFailureB\x07\n\x05\x65vent\"\xa8\x02\n\x14GenerateStubsRequest\x12\x10\n\x03\x64ir\x18\x01 \x01(\tR\x03\x64ir\x12\x37\n\x06module\x18\x02 \x01(\x0b\x32\x1f.xyz.block.ftl.schema.v1.ModuleR\x06module\x12L\n\rmodule_config\x18\x03 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.ModuleConfigR\x0cmoduleConfig\x12^\n\x14native_module_config\x18\x04 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.ModuleConfigH\x00R\x12nativeModuleConfig\x88\x01\x01\x42\x17\n\x15_native_module_config\"\x17\n\x15GenerateStubsResponse\"\xdb\x01\n\x19SyncStubReferencesRequest\x12L\n\rmodule_config\x18\x01 \x01(\x0b\x32\'.xyz.block.ftl.language.v1.ModuleConfigR\x0cmoduleConfig\x12\x1d\n\nstubs_root\x18\x02 \x01(\tR\tstubsRoot\x12\x18\n\x07modules\x18\x03 \x03(\tR\x07modules\x12\x37\n\x06schema\x18\x04 \x01(\x0b\x32\x1f.xyz.block.ftl.schema.v1.SchemaR\x06schema\"\x1c\n\x1aSyncStubReferencesResponse2\xb9\x08\n\x0fLanguageService\x12J\n\x04Ping\x12\x1d.xyz.block.ftl.v1.PingRequest\x1a\x1e.xyz.block.ftl.v1.PingResponse\"\x03\x90\x02\x01\x12\x87\x01\n\x14GetCreateModuleFlags\x12\x36.xyz.block.ftl.language.v1.GetCreateModuleFlagsRequest\x1a\x37.xyz.block.ftl.language.v1.GetCreateModuleFlagsResponse\x12o\n\x0c\x43reateModule\x12..xyz.block.ftl.language.v1.CreateModuleRequest\x1a/.xyz.block.ftl.language.v1.CreateModuleResponse\x12\x87\x01\n\x14ModuleConfigDefaults\x12\x36.xyz.block.ftl.language.v1.ModuleConfigDefaultsRequest\x1a\x37.xyz.block.ftl.language.v1.ModuleConfigDefaultsResponse\x12x\n\x0fGetDependencies\x12\x31.xyz.block.ftl.language.v1.GetDependenciesRequest\x1a\x32.xyz.block.ftl.language.v1.GetDependenciesResponse\x12\\\n\x05\x42uild\x12\'.xyz.block.ftl.language.v1.BuildRequest\x1a(.xyz.block.ftl.language.v1.BuildResponse0\x01\x12\x84\x01\n\x13\x42uildContextUpdated\x12\x35.xyz.block.ftl.language.v1.BuildContextUpdatedRequest\x1a\x36.xyz.block.ftl.language.v1.BuildContextUpdatedResponse\x12r\n\rGenerateStubs\x12/.xyz.block.ftl.language.v1.GenerateStubsRequest\x1a\x30.xyz.block.ftl.language.v1.GenerateStubsResponse\x12\x81\x01\n\x12SyncStubReferences\x12\x34.xyz.block.ftl.language.v1.SyncStubReferencesRequest\x1a\x35.xyz.block.ftl.language.v1.SyncStubReferencesResponseBLP\x01ZHgithub.com/block/ftl/backend/protos/xyz/block/ftl/language/v1;languagepbb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -80,19 +80,19 @@ _globals['_AUTOREBUILDSTARTED']._serialized_start=3086 _globals['_AUTOREBUILDSTARTED']._serialized_end=3137 _globals['_BUILDSUCCESS']._serialized_start=3140 - _globals['_BUILDSUCCESS']._serialized_end=3600 - _globals['_BUILDFAILURE']._serialized_start=3603 - _globals['_BUILDFAILURE']._serialized_end=3817 - _globals['_BUILDRESPONSE']._serialized_start=3820 - _globals['_BUILDRESPONSE']._serialized_end=4103 - _globals['_GENERATESTUBSREQUEST']._serialized_start=4106 - _globals['_GENERATESTUBSREQUEST']._serialized_end=4402 - _globals['_GENERATESTUBSRESPONSE']._serialized_start=4404 - _globals['_GENERATESTUBSRESPONSE']._serialized_end=4427 - _globals['_SYNCSTUBREFERENCESREQUEST']._serialized_start=4430 - _globals['_SYNCSTUBREFERENCESREQUEST']._serialized_end=4649 - _globals['_SYNCSTUBREFERENCESRESPONSE']._serialized_start=4651 - _globals['_SYNCSTUBREFERENCESRESPONSE']._serialized_end=4679 - _globals['_LANGUAGESERVICE']._serialized_start=4682 - _globals['_LANGUAGESERVICE']._serialized_end=5763 + _globals['_BUILDSUCCESS']._serialized_end=3609 + _globals['_BUILDFAILURE']._serialized_start=3612 + _globals['_BUILDFAILURE']._serialized_end=3826 + _globals['_BUILDRESPONSE']._serialized_start=3829 + _globals['_BUILDRESPONSE']._serialized_end=4112 + _globals['_GENERATESTUBSREQUEST']._serialized_start=4115 + _globals['_GENERATESTUBSREQUEST']._serialized_end=4411 + _globals['_GENERATESTUBSRESPONSE']._serialized_start=4413 + _globals['_GENERATESTUBSRESPONSE']._serialized_end=4436 + _globals['_SYNCSTUBREFERENCESREQUEST']._serialized_start=4439 + _globals['_SYNCSTUBREFERENCESREQUEST']._serialized_end=4658 + _globals['_SYNCSTUBREFERENCESRESPONSE']._serialized_start=4660 + _globals['_SYNCSTUBREFERENCESRESPONSE']._serialized_end=4688 + _globals['_LANGUAGESERVICE']._serialized_start=4691 + _globals['_LANGUAGESERVICE']._serialized_end=5772 # @@protoc_insertion_point(module_scope) diff --git a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/language/v1/language_pb2.pyi b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/language/v1/language_pb2.pyi index 107171c3fb..513afae05e 100644 --- a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/language/v1/language_pb2.pyi +++ b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/language/v1/language_pb2.pyi @@ -219,7 +219,7 @@ class AutoRebuildStarted(_message.Message): def __init__(self, context_id: _Optional[str] = ...) -> None: ... class BuildSuccess(_message.Message): - __slots__ = ("context_id", "is_automatic_rebuild", "module", "deploy", "docker_image", "errors", "dev_endpoint", "debug_port", "dev_runner_info_file") + __slots__ = ("context_id", "is_automatic_rebuild", "module", "deploy", "docker_image", "errors", "dev_endpoint", "debug_port", "dev_hot_reload_endpoint") CONTEXT_ID_FIELD_NUMBER: _ClassVar[int] IS_AUTOMATIC_REBUILD_FIELD_NUMBER: _ClassVar[int] MODULE_FIELD_NUMBER: _ClassVar[int] @@ -228,7 +228,7 @@ class BuildSuccess(_message.Message): ERRORS_FIELD_NUMBER: _ClassVar[int] DEV_ENDPOINT_FIELD_NUMBER: _ClassVar[int] DEBUG_PORT_FIELD_NUMBER: _ClassVar[int] - DEV_RUNNER_INFO_FILE_FIELD_NUMBER: _ClassVar[int] + DEV_HOT_RELOAD_ENDPOINT_FIELD_NUMBER: _ClassVar[int] context_id: str is_automatic_rebuild: bool module: _schema_pb2.Module @@ -237,8 +237,8 @@ class BuildSuccess(_message.Message): errors: ErrorList dev_endpoint: str debug_port: int - dev_runner_info_file: str - def __init__(self, context_id: _Optional[str] = ..., is_automatic_rebuild: bool = ..., module: _Optional[_Union[_schema_pb2.Module, _Mapping]] = ..., deploy: _Optional[_Iterable[str]] = ..., docker_image: _Optional[str] = ..., errors: _Optional[_Union[ErrorList, _Mapping]] = ..., dev_endpoint: _Optional[str] = ..., debug_port: _Optional[int] = ..., dev_runner_info_file: _Optional[str] = ...) -> None: ... + dev_hot_reload_endpoint: str + def __init__(self, context_id: _Optional[str] = ..., is_automatic_rebuild: bool = ..., module: _Optional[_Union[_schema_pb2.Module, _Mapping]] = ..., deploy: _Optional[_Iterable[str]] = ..., docker_image: _Optional[str] = ..., errors: _Optional[_Union[ErrorList, _Mapping]] = ..., dev_endpoint: _Optional[str] = ..., debug_port: _Optional[int] = ..., dev_hot_reload_endpoint: _Optional[str] = ...) -> None: ... class BuildFailure(_message.Message): __slots__ = ("context_id", "is_automatic_rebuild", "errors", "invalidate_dependencies")