Repository: SeldonIO/seldon-core (language: python)

Issue:
WIP controller <-> scheduler coordination on server status updates
Work in progress for better state sharing between controller and scheduler,
taking into account possible failures on both ends.


Discussion / hints:
This PR will not be merged. It is used just to share in-progress code, and will be closed when the equivalent functionality has been implemented through other PRs.

Fix patch:
diff --git a/apis/go/mlops/scheduler/scheduler.pb.go b/apis/go/mlops/scheduler/scheduler.pb.go
index f6582e7000..a71317d2d3 100644
--- a/apis/go/mlops/scheduler/scheduler.pb.go
+++ b/apis/go/mlops/scheduler/scheduler.pb.go
@@ -1921,7 +1921,8 @@ type ServerNotifyRequest struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Servers []*ServerNotify `protobuf:"bytes,1,rep,name=servers,proto3" json:"servers,omitempty"`
+	Servers     []*ServerNotify `protobuf:"bytes,1,rep,name=servers,proto3" json:"servers,omitempty"`
+	IsFirstSync bool            `protobuf:"varint,2,opt,name=isFirstSync,proto3" json:"isFirstSync,omitempty"`
 }
 
 func (x *ServerNotifyRequest) Reset() {
@@ -1963,6 +1964,13 @@ func (x *ServerNotifyRequest) GetServers() []*ServerNotify {
 	return nil
 }
 
+func (x *ServerNotifyRequest) GetIsFirstSync() bool {
+	if x != nil {
+		return x.IsFirstSync
+	}
+	return false
+}
+
 type ServerNotify struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -4001,440 +4009,442 @@ var file_mlops_scheduler_scheduler_proto_rawDesc = []byte{
 	0x6c, 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69,
 	0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x6c, 0x6c, 0x56, 0x65,
 	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c,
-	0x22, 0x55, 0x0a, 0x13, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79,
+	0x22, 0x77, 0x0a, 0x13, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79,
 	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3e, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65,
 	0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f,
 	0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65,
 	0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x07,
-	0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x22, 0xce, 0x01, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76,
-	0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x10,
-	0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64,
-	0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72,
-	0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64,
-	0x12, 0x53, 0x0a, 0x0e, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65,
-	0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f,
-	0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65,
-	0x72, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61,
-	0x48, 0x00, 0x52, 0x0e, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65,
-	0x74, 0x61, 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e,
-	0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x22, 0x16, 0x0a, 0x14, 0x53, 0x65, 0x72, 0x76,
-	0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x22, 0x43, 0x0a, 0x19, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72,
-	0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a,
-	0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65,
-	0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x5c, 0x0a, 0x16, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x78,
-	0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
-	0x42, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f,
-	0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x70,
-	0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d,
-	0x65, 0x6e, 0x74, 0x22, 0xee, 0x03, 0x0a, 0x0a, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65,
-	0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c,
-	0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75,
-	0x6c, 0x74, 0x88, 0x01, 0x01, 0x12, 0x4b, 0x0a, 0x0a, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61,
-	0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64,
-	0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c,
-	0x65, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x6e,
-	0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x0a, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74,
-	0x65, 0x73, 0x12, 0x45, 0x0a, 0x06, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70,
-	0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x65,
-	0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x01, 0x52, 0x06,
-	0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x12, 0x45, 0x0a, 0x06, 0x63, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x65, 0x6c, 0x64,
-	0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c,
-	0x65, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e,
-	0x66, 0x69, 0x67, 0x48, 0x02, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x88, 0x01, 0x01,
-	0x12, 0x53, 0x0a, 0x0e, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65,
-	0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f,
-	0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65,
-	0x72, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61,
-	0x48, 0x03, 0x52, 0x0e, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65,
-	0x74, 0x61, 0x88, 0x01, 0x01, 0x12, 0x48, 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
-	0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x73, 0x65,
-	0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64,
-	0x75, 0x6c, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70,
-	0x65, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x42,
-	0x0a, 0x0a, 0x08, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x5f,
-	0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
-	0x67, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73,
-	0x4d, 0x65, 0x74, 0x61, 0x22, 0x3a, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65,
-	0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x74, 0x69, 0x63,
-	0x6b, 0x79, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
-	0x52, 0x0e, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x79, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73,
-	0x22, 0x41, 0x0a, 0x13, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x61,
-	0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x77,
-	0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x77, 0x65, 0x69,
-	0x67, 0x68, 0x74, 0x22, 0x40, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e,
-	0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70,
-	0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x70, 0x65,
-	0x72, 0x63, 0x65, 0x6e, 0x74, 0x22, 0x19, 0x0a, 0x17, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x78,
-	0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x22, 0x2b, 0x0a, 0x15, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65,
-	0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
-	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x18, 0x0a,
-	0x16, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x47, 0x0a, 0x1d, 0x45, 0x78, 0x70, 0x65, 0x72,
-	0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
-	0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x73,
-	0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65,
-	0x22, 0xbc, 0x02, 0x0a, 0x18, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53,
-	0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a,
-	0x0e, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e,
-	0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x28, 0x0a,
-	0x0f, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x61, 0x64, 0x79,
-	0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74,
-	0x65, 0x73, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x69, 0x72, 0x72, 0x6f,
-	0x72, 0x52, 0x65, 0x61, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6d, 0x69,
-	0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, 0x2c, 0x0a, 0x11, 0x73, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x44, 0x65, 0x73, 0x63,
-	0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x0e, 0x6b, 0x75, 0x62, 0x65, 0x72,
-	0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x26, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73,
-	0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65,
-	0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x48, 0x00, 0x52, 0x0e, 0x6b, 0x75, 0x62, 0x65, 0x72,
-	0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, 0x0f,
-	0x5f, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x22,
-	0x53, 0x0a, 0x13, 0x4c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x08, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69,
-	0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f,
-	0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65,
-	0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x08, 0x70, 0x69, 0x70, 0x65,
-	0x6c, 0x69, 0x6e, 0x65, 0x22, 0x63, 0x0a, 0x17, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65,
-	0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x69, 0x73, 0x46, 0x69, 0x72,
+	0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73,
+	0x46, 0x69, 0x72, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x22, 0xce, 0x01, 0x0a, 0x0c, 0x53, 0x65,
+	0x72, 0x76, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
+	0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a,
+	0x0a, 0x10, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63,
+	0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74,
+	0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x68,
+	0x61, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72,
+	0x65, 0x64, 0x12, 0x53, 0x0a, 0x0e, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73,
+	0x4d, 0x65, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x73, 0x65, 0x6c,
+	0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75,
+	0x6c, 0x65, 0x72, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65,
+	0x74, 0x61, 0x48, 0x00, 0x52, 0x0e, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73,
+	0x4d, 0x65, 0x74, 0x61, 0x88, 0x01, 0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x6b, 0x75, 0x62, 0x65,
+	0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x22, 0x16, 0x0a, 0x14, 0x53, 0x65,
+	0x72, 0x76, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0x43, 0x0a, 0x19, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x75, 0x62, 0x73,
+	0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
 	0x26, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d,
 	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
-	0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01,
-	0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x8a, 0x03, 0x0a, 0x08, 0x50, 0x69,
-	0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69,
-	0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07,
-	0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76,
-	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18,
-	0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d,
-	0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50,
-	0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x52, 0x05, 0x73, 0x74, 0x65,
-	0x70, 0x73, 0x12, 0x43, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x26, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70,
-	0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65,
-	0x6c, 0x69, 0x6e, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x48, 0x00, 0x52, 0x06, 0x6f, 0x75,
-	0x74, 0x70, 0x75, 0x74, 0x88, 0x01, 0x01, 0x12, 0x53, 0x0a, 0x0e, 0x6b, 0x75, 0x62, 0x65, 0x72,
-	0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x26, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73,
-	0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65,
-	0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x48, 0x01, 0x52, 0x0e, 0x6b, 0x75, 0x62, 0x65, 0x72,
-	0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x88, 0x01, 0x01, 0x12, 0x40, 0x0a, 0x05,
-	0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x65,
+	0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x5c, 0x0a, 0x16, 0x53, 0x74, 0x61, 0x72, 0x74,
+	0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x42, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d,
+	0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x45,
+	0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x65, 0x72,
+	0x69, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0xee, 0x03, 0x0a, 0x0a, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69,
+	0x6d, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61,
+	0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x64, 0x65, 0x66,
+	0x61, 0x75, 0x6c, 0x74, 0x88, 0x01, 0x01, 0x12, 0x4b, 0x0a, 0x0a, 0x63, 0x61, 0x6e, 0x64, 0x69,
+	0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x73, 0x65,
 	0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64,
-	0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x70,
-	0x75, 0x74, 0x48, 0x02, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x88, 0x01, 0x01, 0x42, 0x09,
-	0x0a, 0x07, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x6b, 0x75,
-	0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x08, 0x0a, 0x06,
-	0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x22, 0x9d, 0x04, 0x0a, 0x0c, 0x50, 0x69, 0x70, 0x65, 0x6c,
-	0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x69,
-	0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x69, 0x6e, 0x70,
-	0x75, 0x74, 0x73, 0x12, 0x27, 0x0a, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f,
-	0x77, 0x4d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x0c, 0x6a, 0x6f, 0x69,
-	0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x51, 0x0a, 0x09,
-	0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
-	0x33, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73,
-	0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e,
-	0x65, 0x53, 0x74, 0x65, 0x70, 0x2e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45,
-	0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x12,
-	0x4b, 0x0a, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x18, 0x05, 0x20,
-	0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f,
-	0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70,
-	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70,
-	0x52, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x1a, 0x0a, 0x08,
-	0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08,
-	0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x12, 0x4f, 0x0a, 0x0c, 0x74, 0x72, 0x69, 0x67,
-	0x67, 0x65, 0x72, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b,
-	0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63,
-	0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65,
-	0x53, 0x74, 0x65, 0x70, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x52, 0x0c, 0x74, 0x72, 0x69,
-	0x67, 0x67, 0x65, 0x72, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x33, 0x0a, 0x05, 0x62, 0x61, 0x74,
-	0x63, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f,
-	0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65,
-	0x72, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x3c,
-	0x0a, 0x0e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79,
-	0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
-	0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x27, 0x0a, 0x06,
-	0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4e, 0x4e, 0x45, 0x52, 0x10,
-	0x00, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x55, 0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03,
-	0x41, 0x4e, 0x59, 0x10, 0x02, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69,
-	0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22, 0x57, 0x0a, 0x05, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12,
-	0x17, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52,
-	0x04, 0x73, 0x69, 0x7a, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x77, 0x69, 0x6e, 0x64,
-	0x6f, 0x77, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, 0x52, 0x08, 0x77, 0x69,
-	0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x73, 0x69,
-	0x7a, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22,
-	0xf4, 0x03, 0x0a, 0x0d, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x70, 0x75,
-	0x74, 0x12, 0x26, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x70,
-	0x75, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x72,
-	0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x65, 0x78, 0x74,
-	0x65, 0x72, 0x6e, 0x61, 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20,
-	0x03, 0x28, 0x09, 0x52, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x54, 0x72, 0x69,
-	0x67, 0x67, 0x65, 0x72, 0x73, 0x12, 0x27, 0x0a, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e,
-	0x64, 0x6f, 0x77, 0x4d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x0c, 0x6a,
-	0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x48,
-	0x0a, 0x08, 0x6a, 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e,
-	0x32, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e,
-	0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69,
-	0x6e, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x52, 0x08,
-	0x6a, 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x50, 0x0a, 0x0c, 0x74, 0x72, 0x69, 0x67,
-	0x67, 0x65, 0x72, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c,
-	0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63,
-	0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65,
-	0x49, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x52, 0x0c, 0x74, 0x72,
-	0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x52, 0x0a, 0x09, 0x74, 0x65,
-	0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e,
+	0x75, 0x6c, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x43,
+	0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x52, 0x0a, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64,
+	0x61, 0x74, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x06, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c,
+	0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x45, 0x78,
+	0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x01,
+	0x52, 0x06, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x12, 0x45, 0x0a, 0x06, 0x63,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x65,
+	0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64,
+	0x75, 0x6c, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x02, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x88,
+	0x01, 0x01, 0x12, 0x53, 0x0a, 0x0e, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73,
+	0x4d, 0x65, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x73, 0x65, 0x6c,
+	0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75,
+	0x6c, 0x65, 0x72, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65,
+	0x74, 0x61, 0x48, 0x03, 0x52, 0x0e, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73,
+	0x4d, 0x65, 0x74, 0x61, 0x88, 0x01, 0x01, 0x12, 0x48, 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75,
+	0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e,
+	0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68,
+	0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54,
+	0x79, 0x70, 0x65, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70,
+	0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x42, 0x09, 0x0a,
+	0x07, 0x5f, 0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x63, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74,
+	0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x22, 0x3a, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69,
+	0x6d, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x74,
+	0x69, 0x63, 0x6b, 0x79, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x08, 0x52, 0x0e, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x79, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f,
+	0x6e, 0x73, 0x22, 0x41, 0x0a, 0x13, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74,
+	0x43, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a,
+	0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x77,
+	0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x40, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d,
+	0x65, 0x6e, 0x74, 0x4d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a,
+	0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07,
+	0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x22, 0x19, 0x0a, 0x17, 0x53, 0x74, 0x61, 0x72, 0x74,
+	0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0x2b, 0x0a, 0x15, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69,
+	0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22,
+	0x18, 0x0a, 0x16, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e,
+	0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x47, 0x0a, 0x1d, 0x45, 0x78, 0x70,
+	0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
+	0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x75,
+	0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61,
+	0x6d, 0x65, 0x22, 0xbc, 0x02, 0x0a, 0x18, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e,
+	0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+	0x26, 0x0a, 0x0e, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d,
+	0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12,
+	0x28, 0x0a, 0x0f, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x61,
+	0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64,
+	0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x69, 0x72,
+	0x72, 0x6f, 0x72, 0x52, 0x65, 0x61, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b,
+	0x6d, 0x69, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, 0x2c, 0x0a, 0x11, 0x73,
+	0x74, 0x61, 0x74, 0x75, 0x73, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x44, 0x65,
+	0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x0e, 0x6b, 0x75, 0x62,
+	0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x26, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73,
+	0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72,
+	0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x48, 0x00, 0x52, 0x0e, 0x6b, 0x75, 0x62,
+	0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x88, 0x01, 0x01, 0x42, 0x11,
+	0x0a, 0x0f, 0x5f, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74,
+	0x61, 0x22, 0x53, 0x0a, 0x13, 0x4c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e,
+	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x08, 0x70, 0x69, 0x70, 0x65,
+	0x6c, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x65, 0x6c,
+	0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75,
+	0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x08, 0x70, 0x69,
+	0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x63, 0x0a, 0x17, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69,
+	0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e,
+	0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63,
+	0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88,
+	0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x8a, 0x03, 0x0a, 0x08,
+	0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03,
+	0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x18,
+	0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52,
+	0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70,
+	0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e,
+	0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72,
+	0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x52, 0x05, 0x73,
+	0x74, 0x65, 0x70, 0x73, 0x12, 0x43, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x05,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c,
+	0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69,
+	0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x48, 0x00, 0x52, 0x06,
+	0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x88, 0x01, 0x01, 0x12, 0x53, 0x0a, 0x0e, 0x6b, 0x75, 0x62,
+	0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x26, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73,
+	0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4b, 0x75, 0x62, 0x65, 0x72,
+	0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x48, 0x01, 0x52, 0x0e, 0x6b, 0x75, 0x62,
+	0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x88, 0x01, 0x01, 0x12, 0x40,
+	0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e,
 	0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68,
 	0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x49,
-	0x6e, 0x70, 0x75, 0x74, 0x2e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e,
-	0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x1a, 0x3c,
-	0x0a, 0x0e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79,
-	0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
-	0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x27, 0x0a, 0x06,
-	0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4e, 0x4e, 0x45, 0x52, 0x10,
-	0x00, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x55, 0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03,
-	0x41, 0x4e, 0x59, 0x10, 0x02, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69,
-	0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22, 0xd3, 0x02, 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c,
-	0x69, 0x6e, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x65,
-	0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x12,
-	0x22, 0x0a, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f,
-	0x77, 0x4d, 0x73, 0x12, 0x4b, 0x0a, 0x09, 0x73, 0x74, 0x65, 0x70, 0x73, 0x4a, 0x6f, 0x69, 0x6e,
-	0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e,
-	0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e,
-	0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x4a,
-	0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x52, 0x09, 0x73, 0x74, 0x65, 0x70, 0x73, 0x4a, 0x6f, 0x69, 0x6e,
-	0x12, 0x53, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x18, 0x04, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f,
-	0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70,
-	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x54, 0x65, 0x6e, 0x73,
-	0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x73,
-	0x6f, 0x72, 0x4d, 0x61, 0x70, 0x1a, 0x3c, 0x0a, 0x0e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d,
-	0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c,
-	0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
-	0x02, 0x38, 0x01, 0x22, 0x27, 0x0a, 0x06, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x12, 0x09, 0x0a,
-	0x05, 0x49, 0x4e, 0x4e, 0x45, 0x52, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x55, 0x54, 0x45,
-	0x52, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x59, 0x10, 0x02, 0x22, 0x16, 0x0a, 0x14,
-	0x4c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x0a, 0x15, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x69,
-	0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a,
-	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
-	0x65, 0x22, 0x18, 0x0a, 0x16, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c,
-	0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x83, 0x01, 0x0a, 0x15,
-	0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69,
-	0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73,
-	0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a,
-	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e,
-	0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x56, 0x65, 0x72,
-	0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x6c, 0x6c,
-	0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d,
-	0x65, 0x22, 0x45, 0x0a, 0x1b, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x75, 0x62,
-	0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x12, 0x26, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61,
-	0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72,
-	0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x83, 0x01, 0x0a, 0x16, 0x50, 0x69, 0x70,
-	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4e,
-	0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x69, 0x70, 0x65, 0x6c,
-	0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x45, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69,
-	0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x64,
-	0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c,
-	0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53,
-	0x74, 0x61, 0x74, 0x65, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x95,
-	0x01, 0x0a, 0x11, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x57, 0x69, 0x74, 0x68, 0x53,
-	0x74, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x08, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e,
-	0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e,
-	0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x08, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69,
-	0x6e, 0x65, 0x12, 0x42, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73,
+	0x6e, 0x70, 0x75, 0x74, 0x48, 0x02, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x88, 0x01, 0x01,
+	0x42, 0x09, 0x0a, 0x07, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x42, 0x11, 0x0a, 0x0f, 0x5f,
+	0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x42, 0x08,
+	0x0a, 0x06, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x22, 0x9d, 0x04, 0x0a, 0x0c, 0x50, 0x69, 0x70,
+	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a,
+	0x06, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x69,
+	0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x27, 0x0a, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e,
+	0x64, 0x6f, 0x77, 0x4d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x0c, 0x6a,
+	0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x51,
+	0x0a, 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x18, 0x04, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73,
 	0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c,
-	0x69, 0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52,
-	0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xe4, 0x03, 0x0a, 0x14, 0x50, 0x69, 0x70, 0x65, 0x6c,
-	0x69, 0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12,
-	0x28, 0x0a, 0x0f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69,
-	0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69,
-	0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x06, 0x73, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3b, 0x2e, 0x73, 0x65, 0x6c, 0x64,
-	0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c,
-	0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69,
-	0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65,
-	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16,
-	0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
-	0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x4c, 0x0a, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x68,
-	0x61, 0x6e, 0x67, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
-	0x13, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73,
-	0x74, 0x61, 0x6d, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x52, 0x65,
-	0x61, 0x64, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x6c,
-	0x73, 0x52, 0x65, 0x61, 0x64, 0x79, 0x22, 0xc4, 0x01, 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c,
-	0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x0a, 0x15, 0x50, 0x69, 0x70,
-	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x6e, 0x6b, 0x6e, 0x6f,
-	0x77, 0x6e, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65,
-	0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x69, 0x70, 0x65,
-	0x6c, 0x69, 0x6e, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x10, 0x02, 0x12, 0x11,
-	0x0a, 0x0d, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x61, 0x64, 0x79, 0x10,
-	0x03, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x46, 0x61, 0x69,
-	0x6c, 0x65, 0x64, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e,
-	0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x10, 0x05, 0x12, 0x17, 0x0a, 0x13,
-	0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74,
-	0x69, 0x6e, 0x67, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e,
-	0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x10, 0x07, 0x22, 0x40, 0x0a,
-	0x16, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x2e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61,
+	0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61,
+	0x70, 0x12, 0x4b, 0x0a, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x18,
+	0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d,
+	0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50,
+	0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x2e, 0x4a, 0x6f, 0x69, 0x6e,
+	0x4f, 0x70, 0x52, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x1a,
+	0x0a, 0x08, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09,
+	0x52, 0x08, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x12, 0x4f, 0x0a, 0x0c, 0x74, 0x72,
+	0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e,
+	0x32, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e,
+	0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69,
+	0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x52, 0x0c, 0x74,
+	0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x33, 0x0a, 0x05, 0x62,
+	0x61, 0x74, 0x63, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x73, 0x65, 0x6c,
+	0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75,
+	0x6c, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68,
+	0x1a, 0x3c, 0x0a, 0x0e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74,
+	0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x27,
+	0x0a, 0x06, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4e, 0x4e, 0x45,
+	0x52, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x55, 0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x07,
+	0x0a, 0x03, 0x41, 0x4e, 0x59, 0x10, 0x02, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6a, 0x6f, 0x69, 0x6e,
+	0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22, 0x57, 0x0a, 0x05, 0x42, 0x61, 0x74, 0x63,
+	0x68, 0x12, 0x17, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48,
+	0x00, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x77, 0x69,
+	0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, 0x52, 0x08,
+	0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f,
+	0x73, 0x69, 0x7a, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d,
+	0x73, 0x22, 0xf4, 0x03, 0x0a, 0x0d, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x49, 0x6e,
+	0x70, 0x75, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49,
+	0x6e, 0x70, 0x75, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x78, 0x74,
+	0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x65,
+	0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x18,
+	0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x54,
+	0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x12, 0x27, 0x0a, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57,
+	0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52,
+	0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x88, 0x01, 0x01,
+	0x12, 0x48, 0x0a, 0x08, 0x6a, 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01,
+	0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70,
+	0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65,
+	0x6c, 0x69, 0x6e, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70,
+	0x52, 0x08, 0x6a, 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x50, 0x0a, 0x0c, 0x74, 0x72,
+	0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e,
+	0x32, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e,
+	0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69,
+	0x6e, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x52, 0x0c,
+	0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x73, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x52, 0x0a, 0x09,
+	0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x34, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73,
+	0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e,
+	0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70,
+	0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70,
+	0x1a, 0x3c, 0x0a, 0x0e, 0x54, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74,
+	0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x27,
+	0x0a, 0x06, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4e, 0x4e, 0x45,
+	0x52, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x55, 0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x07,
+	0x0a, 0x03, 0x41, 0x4e, 0x59, 0x10, 0x02, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x6a, 0x6f, 0x69, 0x6e,
+	0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d, 0x73, 0x22, 0xd3, 0x02, 0x0a, 0x0e, 0x50, 0x69, 0x70,
+	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73,
+	0x74, 0x65, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70,
+	0x73, 0x12, 0x22, 0x0a, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x4d,
+	0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6a, 0x6f, 0x69, 0x6e, 0x57, 0x69, 0x6e,
+	0x64, 0x6f, 0x77, 0x4d, 0x73, 0x12, 0x4b, 0x0a, 0x09, 0x73, 0x74, 0x65, 0x70, 0x73, 0x4a, 0x6f,
+	0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f,
+	0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65,
+	0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74,
+	0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x52, 0x09, 0x73, 0x74, 0x65, 0x70, 0x73, 0x4a, 0x6f,
+	0x69, 0x6e, 0x12, 0x53, 0x0a, 0x09, 0x74, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x18,
+	0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d,
+	0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50,
+	0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x54, 0x65,
+	0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x65,
+	0x6e, 0x73, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x1a, 0x3c, 0x0a, 0x0e, 0x54, 0x65, 0x6e, 0x73, 0x6f,
+	0x72, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76,
+	0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
+	0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x27, 0x0a, 0x06, 0x4a, 0x6f, 0x69, 0x6e, 0x4f, 0x70, 0x12,
+	0x09, 0x0a, 0x05, 0x49, 0x4e, 0x4e, 0x45, 0x52, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x55,
+	0x54, 0x45, 0x52, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4e, 0x59, 0x10, 0x02, 0x22, 0x16,
+	0x0a, 0x14, 0x4c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x0a, 0x15, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64,
+	0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
+	0x61, 0x6d, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70,
+	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x83, 0x01,
+	0x0a, 0x15, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
 	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63,
 	0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22,
-	0x49, 0x0a, 0x17, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74,
-	0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x61, 0x70,
-	0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
-	0x69, 0x6f, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2a, 0x27, 0x0a, 0x0c, 0x52, 0x65,
-	0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x4d, 0x4f,
-	0x44, 0x45, 0x4c, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x49, 0x50, 0x45, 0x4c, 0x49, 0x4e,
-	0x45, 0x10, 0x01, 0x32, 0xd9, 0x0e, 0x0a, 0x09, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65,
-	0x72, 0x12, 0x6b, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66,
-	0x79, 0x12, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73,
-	0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65,
-	0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c,
+	0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12,
+	0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52,
+	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x56,
+	0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61,
+	0x6c, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e,
+	0x61, 0x6d, 0x65, 0x22, 0x45, 0x0a, 0x1b, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53,
+	0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72,
+	0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73,
+	0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x83, 0x01, 0x0a, 0x16, 0x50,
+	0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e,
+	0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x69, 0x70,
+	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x45, 0x0a, 0x08, 0x76, 0x65, 0x72,
+	0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x73, 0x65,
+	0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64,
+	0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x57, 0x69, 0x74,
+	0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73,
+	0x22, 0x95, 0x01, 0x0a, 0x11, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x57, 0x69, 0x74,
+	0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x3c, 0x0a, 0x08, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69,
+	0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f,
+	0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65,
+	0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x08, 0x70, 0x69, 0x70, 0x65,
+	0x6c, 0x69, 0x6e, 0x65, 0x12, 0x42, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f,
+	0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70,
+	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74,
+	0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xe4, 0x03, 0x0a, 0x14, 0x50, 0x69, 0x70,
+	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74,
+	0x65, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x56, 0x65, 0x72,
+	0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x70, 0x69, 0x70, 0x65,
+	0x6c, 0x69, 0x6e, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x53, 0x0a, 0x06, 0x73,
+	0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3b, 0x2e, 0x73, 0x65,
+	0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64,
+	0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x56, 0x65, 0x72,
+	0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69,
+	0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x4c, 0x0a, 0x13, 0x6c, 0x61, 0x73, 0x74,
+	0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18,
+	0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
+	0x70, 0x52, 0x13, 0x6c, 0x61, 0x73, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x69, 0x6d,
+	0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73,
+	0x52, 0x65, 0x61, 0x64, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x6d, 0x6f, 0x64,
+	0x65, 0x6c, 0x73, 0x52, 0x65, 0x61, 0x64, 0x79, 0x22, 0xc4, 0x01, 0x0a, 0x0e, 0x50, 0x69, 0x70,
+	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x0a, 0x15, 0x50,
+	0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x6e, 0x6b,
+	0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69,
+	0x6e, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x69,
+	0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x10, 0x02,
+	0x12, 0x11, 0x0a, 0x0d, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x61, 0x64,
+	0x79, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x46,
+	0x61, 0x69, 0x6c, 0x65, 0x64, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x50, 0x69, 0x70, 0x65, 0x6c,
+	0x69, 0x6e, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x10, 0x05, 0x12, 0x17,
+	0x0a, 0x13, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e,
+	0x61, 0x74, 0x69, 0x6e, 0x67, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x69, 0x70, 0x65, 0x6c,
+	0x69, 0x6e, 0x65, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x64, 0x10, 0x07, 0x22,
+	0x40, 0x0a, 0x16, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74,
+	0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x75, 0x62,
+	0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x0e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x72, 0x4e, 0x61, 0x6d,
+	0x65, 0x22, 0x49, 0x0a, 0x17, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74,
+	0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x12,
+	0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69,
+	0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2a, 0x27, 0x0a, 0x0c,
+	0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05,
+	0x4d, 0x4f, 0x44, 0x45, 0x4c, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x49, 0x50, 0x45, 0x4c,
+	0x49, 0x4e, 0x45, 0x10, 0x01, 0x32, 0xd9, 0x0e, 0x0a, 0x09, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75,
+	0x6c, 0x65, 0x72, 0x12, 0x6b, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x6f, 0x74,
+	0x69, 0x66, 0x79, 0x12, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f,
+	0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72,
+	0x76, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x1a, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e,
+	0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
+	0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
+	0x12, 0x62, 0x0a, 0x09, 0x4c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x28, 0x2e,
+	0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68,
+	0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e,
+	0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72,
+	0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0x00, 0x12, 0x68, 0x0a, 0x0b, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4d, 0x6f,
+	0x64, 0x65, 0x6c, 0x12, 0x2a, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f,
+	0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x6e, 0x6c,
+	0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73,
+	0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4d,
+	0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6b,
+	0x0a, 0x0c, 0x4c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x2b,
 	0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63,
-	0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4e, 0x6f,
-	0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x62,
-	0x0a, 0x09, 0x4c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x28, 0x2e, 0x73, 0x65,
+	0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65,
+	0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x65,
 	0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64,
-	0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d,
-	0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c,
-	0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x22, 0x00, 0x12, 0x68, 0x0a, 0x0b, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64, 0x65,
-	0x6c, 0x12, 0x2a, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73,
-	0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x61,
-	0x64, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e,
+	0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e,
+	0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x71, 0x0a, 0x0e, 0x55,
+	0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x2d, 0x2e,
 	0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68,
-	0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x64,
-	0x65, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6b, 0x0a, 0x0c,
-	0x4c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x2b, 0x2e, 0x73,
+	0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70,
+	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73,
 	0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65,
-	0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69,
-	0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64,
-	0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c,
-	0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x71, 0x0a, 0x0e, 0x55, 0x6e, 0x6c,
-	0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x2d, 0x2e, 0x73, 0x65,
-	0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64,
-	0x75, 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c,
-	0x69, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x65, 0x6c,
-	0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75,
-	0x6c, 0x65, 0x72, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69,
-	0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x74, 0x0a, 0x0f,
-	0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x12,
-	0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73,
-	0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x78,
-	0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
-	0x2f, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73,
-	0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x78,
-	0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x22, 0x00, 0x12, 0x71, 0x0a, 0x0e, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69,
-	0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2d, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c,
-	0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x74,
-	0x6f, 0x70, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f,
-	0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x6f,
-	0x70, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53,
-	0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d,
+	0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x69, 0x70, 0x65,
+	0x6c, 0x69, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x74,
+	0x0a, 0x0f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e,
+	0x74, 0x12, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73,
+	0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74,
+	0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x1a, 0x2f, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73,
+	0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74,
+	0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0x00, 0x12, 0x71, 0x0a, 0x0e, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x78, 0x70, 0x65,
+	0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2d, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e,
+	0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e,
+	0x53, 0x74, 0x6f, 0x70, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d,
 	0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53,
-	0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70,
-	0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76,
-	0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x22, 0x00, 0x30, 0x01, 0x12, 0x6a, 0x0a, 0x0b, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x12, 0x2a, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f,
-	0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64,
-	0x65, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
-	0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73,
-	0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x74,
-	0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01,
-	0x12, 0x73, 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74,
-	0x75, 0x73, 0x12, 0x2d, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70,
-	0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65,
-	0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73,
-	0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c,
-	0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x79, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d,
-	0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2f, 0x2e, 0x73, 0x65, 0x6c, 0x64,
-	0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c,
-	0x65, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x73, 0x65, 0x6c,
-	0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75,
-	0x6c, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74,
-	0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01,
-	0x12, 0x74, 0x0a, 0x0f, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x12, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f,
-	0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x63, 0x68,
-	0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f,
-	0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x63, 0x68,
-	0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7c, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72,
-	0x69, 0x62, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
-	0x31, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73,
-	0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53,
-	0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70,
-	0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76,
-	0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x22, 0x00, 0x30, 0x01, 0x12, 0x79, 0x0a, 0x14, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62,
-	0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x30, 0x2e, 0x73,
+	0x74, 0x6f, 0x70, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65,
+	0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e,
+	0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72,
+	0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c,
+	0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65,
+	0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x6a, 0x0a, 0x0b, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53,
+	0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2a, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d,
+	0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4d,
+	0x6f, 0x64, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x1a, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73,
+	0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c,
+	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
+	0x30, 0x01, 0x12, 0x73, 0x0a, 0x0e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74,
+	0x61, 0x74, 0x75, 0x73, 0x12, 0x2d, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c,
+	0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69,
+	0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f,
+	0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70,
+	0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x79, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x65, 0x72,
+	0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2f, 0x2e, 0x73, 0x65,
+	0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64,
+	0x75, 0x6c, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53,
+	0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x73,
 	0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65,
-	0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x75, 0x62, 0x73, 0x63,
-	0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b,
+	0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74,
+	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
+	0x30, 0x01, 0x12, 0x74, 0x0a, 0x0f, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53,
+	0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2e, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d,
+	0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53,
+	0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d,
+	0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53,
+	0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7c, 0x0a, 0x15, 0x53, 0x75, 0x62, 0x73,
+	0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75,
+	0x73, 0x12, 0x31, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73,
+	0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65,
+	0x72, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c,
+	0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65,
+	0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x79, 0x0a, 0x14, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72,
+	0x69, 0x62, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x30,
 	0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63,
-	0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12,
-	0x88, 0x01, 0x0a, 0x19, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x45, 0x78, 0x70,
-	0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x35, 0x2e,
-	0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68,
-	0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e,
-	0x74, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c,
-	0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x45, 0x78,
-	0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x82, 0x01, 0x0a, 0x17, 0x53,
-	0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65,
-	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e,
+	0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x75, 0x62,
+	0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x1a, 0x2b, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e,
+	0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53,
+	0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30,
+	0x01, 0x12, 0x88, 0x01, 0x0a, 0x19, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x45,
+	0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12,
+	0x35, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73,
+	0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d,
+	0x65, 0x6e, 0x74, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e,
 	0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e,
-	0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70,
-	0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x65,
-	0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64,
-	0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x42,
-	0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x65,
-	0x6c, 0x64, 0x6f, 0x6e, 0x69, 0x6f, 0x2f, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2d, 0x63, 0x6f,
-	0x72, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x32, 0x2f, 0x6d, 0x6c,
-	0x6f, 0x70, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x62, 0x06, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x45, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x82, 0x01, 0x0a,
+	0x17, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69,
+	0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x64, 0x6f,
+	0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65,
+	0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72,
+	0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e,
+	0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2e, 0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2e, 0x73, 0x63, 0x68,
+	0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53,
+	0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30,
+	0x01, 0x42, 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+	0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x69, 0x6f, 0x2f, 0x73, 0x65, 0x6c, 0x64, 0x6f, 0x6e, 0x2d,
+	0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x32, 0x2f,
+	0x6d, 0x6c, 0x6f, 0x70, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x62,
+	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
diff --git a/apis/mlops/scheduler/scheduler.proto b/apis/mlops/scheduler/scheduler.proto
index 2fe2028c13..d8d6463b5a 100644
--- a/apis/mlops/scheduler/scheduler.proto
+++ b/apis/mlops/scheduler/scheduler.proto
@@ -186,6 +186,7 @@ message ModelStatusRequest {
 
 message ServerNotifyRequest {
   repeated ServerNotify servers = 1;
+  bool isFirstSync = 2;
 }
 
 message ServerNotify {
diff --git a/k8s/helm-charts/seldon-core-v2-setup/templates/seldon-v2-components.yaml b/k8s/helm-charts/seldon-core-v2-setup/templates/seldon-v2-components.yaml
index 7fdfb7fdbe..41a3e3e976 100644
--- a/k8s/helm-charts/seldon-core-v2-setup/templates/seldon-v2-components.yaml
+++ b/k8s/helm-charts/seldon-core-v2-setup/templates/seldon-v2-components.yaml
@@ -903,6 +903,7 @@ spec:
         - --db-path=/mnt/scheduler/db
         - --allow-plaintxt=$(ALLOW_PLAINTXT)
         - --kafka-config-path=/mnt/kafka/kafka.json
+        - --scheduler-ready-timeout-seconds=$(SCHEDULER_READY_TIMEOUT_SECONDS)
         command:
         - /bin/scheduler
         env:
@@ -949,6 +950,8 @@ spec:
           value: '{{ .Values.security.envoy.ssl.downstream.server.caPath }}'
         - name: ENVOY_DOWNSTREAM_CLIENT_TLS_CA_LOCATION
           value: '{{ .Values.security.envoy.ssl.downstream.server.clientCaPath }}'
+        - name: SCHEDULER_READY_TIMEOUT_SECONDS
+          value: '{{ .Values.scheduler.schedulerReadyTimeoutSeconds }}'
         - name: ALLOW_PLAINTXT
           value: "true"
         - name: POD_NAMESPACE
diff --git a/k8s/helm-charts/seldon-core-v2-setup/values.yaml b/k8s/helm-charts/seldon-core-v2-setup/values.yaml
index 0e861042d5..2c36eb2953 100644
--- a/k8s/helm-charts/seldon-core-v2-setup/values.yaml
+++ b/k8s/helm-charts/seldon-core-v2-setup/values.yaml
@@ -213,6 +213,7 @@ scheduler:
     runAsUser: 1000
     runAsGroup: 1000
     runAsNonRoot: true
+  schedulerReadyTimeoutSeconds: 600
 
 serverConfig:
   terminationGracePeriodSeconds: 120
diff --git a/k8s/helm-charts/seldon-core-v2-setup/values.yaml.template b/k8s/helm-charts/seldon-core-v2-setup/values.yaml.template
index 655c3cb4f0..08ffa41915 100644
--- a/k8s/helm-charts/seldon-core-v2-setup/values.yaml.template
+++ b/k8s/helm-charts/seldon-core-v2-setup/values.yaml.template
@@ -213,6 +213,7 @@ scheduler:
     runAsUser: 1000
     runAsGroup: 1000
     runAsNonRoot: true
+  schedulerReadyTimeoutSeconds: 600
 
 serverConfig:
   terminationGracePeriodSeconds: 120
diff --git a/k8s/kustomize/helm-components-sc/patch_scheduler.yaml b/k8s/kustomize/helm-components-sc/patch_scheduler.yaml
index 0d7aa42bd6..3aeb6c0266 100644
--- a/k8s/kustomize/helm-components-sc/patch_scheduler.yaml
+++ b/k8s/kustomize/helm-components-sc/patch_scheduler.yaml
@@ -59,6 +59,8 @@ spec:
             value: '{{ .Values.security.envoy.ssl.downstream.server.caPath }}'
           - name: ENVOY_DOWNSTREAM_CLIENT_TLS_CA_LOCATION
             value: '{{ .Values.security.envoy.ssl.downstream.server.clientCaPath }}'
+          - name: SCHEDULER_READY_TIMEOUT_SECONDS
+            value: '{{ .Values.scheduler.schedulerReadyTimeoutSeconds }}'
     volumeClaimTemplates:
     - name: scheduler-state
       spec:
diff --git a/k8s/yaml/components.yaml b/k8s/yaml/components.yaml
index 14d4755a81..0161f446e4 100644
--- a/k8s/yaml/components.yaml
+++ b/k8s/yaml/components.yaml
@@ -547,6 +547,7 @@ spec:
         - --db-path=/mnt/scheduler/db
         - --allow-plaintxt=$(ALLOW_PLAINTXT)
         - --kafka-config-path=/mnt/kafka/kafka.json
+        - --scheduler-ready-timeout-seconds=$(SCHEDULER_READY_TIMEOUT_SECONDS)
         command:
         - /bin/scheduler
         env:
@@ -590,6 +591,8 @@ spec:
           value: '/tmp/certs/dds/ca.crt'
         - name: ENVOY_DOWNSTREAM_CLIENT_TLS_CA_LOCATION
           value: '/tmp/certs/ddc/ca.crt'
+        - name: SCHEDULER_READY_TIMEOUT_SECONDS
+          value: '600'
         - name: ALLOW_PLAINTXT
           value: "true"
         - name: POD_NAMESPACE
diff --git a/operator/config/seldonconfigs/default.yaml b/operator/config/seldonconfigs/default.yaml
index c135bd7bf1..73b5cfb24d 100644
--- a/operator/config/seldonconfigs/default.yaml
+++ b/operator/config/seldonconfigs/default.yaml
@@ -214,11 +214,14 @@ spec:
         - --db-path=/mnt/scheduler/db
         - --allow-plaintxt=$(ALLOW_PLAINTXT)
         - --kafka-config-path=/mnt/kafka/kafka.json
+        - --scheduler-ready-timeout-seconds=$(SCHEDULER_READY_TIMEOUT_SECONDS)
         command:
         - /bin/scheduler
         env:
         - name: ALLOW_PLAINTXT
           value: "true"
+        - name: SCHEDULER_READY_TIMEOUT_SECONDS
+          value: 600
         - name: POD_NAMESPACE
           valueFrom:
             fieldRef:
diff --git a/operator/controllers/mlops/server_controller.go b/operator/controllers/mlops/server_controller.go
index ba8d1db4ea..e7b3d95741 100644
--- a/operator/controllers/mlops/server_controller.go
+++ b/operator/controllers/mlops/server_controller.go
@@ -90,7 +90,7 @@ func (r *ServerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
 		return reconcile.Result{}, nil
 	}
 
-	err := r.Scheduler.ServerNotify(ctx, nil, []v1alpha1.Server{*server})
+	err := r.Scheduler.ServerNotify(ctx, nil, []v1alpha1.Server{*server}, false)
 	if err != nil {
 		r.updateStatusFromError(ctx, logger, server, err)
 		return reconcile.Result{}, err
diff --git a/operator/scheduler/server.go b/operator/scheduler/server.go
index 5416099a96..fa3144719f 100644
--- a/operator/scheduler/server.go
+++ b/operator/scheduler/server.go
@@ -23,7 +23,7 @@ import (
 	"github.com/seldonio/seldon-core/operator/v2/apis/mlops/v1alpha1"
 )
 
-func (s *SchedulerClient) ServerNotify(ctx context.Context, grpcClient scheduler.SchedulerClient, servers []v1alpha1.Server) error {
+func (s *SchedulerClient) ServerNotify(ctx context.Context, grpcClient scheduler.SchedulerClient, servers []v1alpha1.Server, isFirstSync bool) error {
 	logger := s.logger.WithName("NotifyServer")
 	if len(servers) == 0 {
 		return nil
@@ -61,7 +61,8 @@ func (s *SchedulerClient) ServerNotify(ctx context.Context, grpcClient scheduler
 		})
 	}
 	request := &scheduler.ServerNotifyRequest{
-		Servers: requests,
+		Servers:     requests,
+		IsFirstSync: isFirstSync,
 	}
 	_, err := grpcClient.ServerNotify(
 		ctx,
diff --git a/operator/scheduler/utils.go b/operator/scheduler/utils.go
index da4fd5289b..000c8be4f5 100644
--- a/operator/scheduler/utils.go
+++ b/operator/scheduler/utils.go
@@ -129,7 +129,7 @@ func handleRegisteredServers(
 		return
 	}
 
-	if err := s.ServerNotify(ctx, grpcClient, serverList.Items); err != nil {
+	if err := s.ServerNotify(ctx, grpcClient, serverList.Items, true); err != nil {
 		s.logger.Error(err, "Failed to notify servers", "servers", serverList.Items)
 	}
 }
diff --git a/scheduler/all-host-network.yaml b/scheduler/all-host-network.yaml
index 7c0d833054..7d30466355 100644
--- a/scheduler/all-host-network.yaml
+++ b/scheduler/all-host-network.yaml
@@ -167,6 +167,8 @@ services:
       - --disable-autoscaling
       - "--kafka-config-path"
       - "/mnt/config/kafka-host.json"
+      - "--scheduler-ready-timeout-seconds"
+      - ${SCHEDULER_READY_TIMEOUT_SECONDS}
     volumes:
       - type: bind
         source: ./config
diff --git a/scheduler/all-internal.yaml b/scheduler/all-internal.yaml
index b9516fa37c..31d1d2b7f6 100644
--- a/scheduler/all-internal.yaml
+++ b/scheduler/all-internal.yaml
@@ -206,6 +206,8 @@ services:
       - --disable-autoscaling
       - "--kafka-config-path"
       - "/mnt/config/kafka-internal.json"
+      - "--scheduler-ready-timeout-seconds"
+      - ${SCHEDULER_READY_TIMEOUT_SECONDS}
     volumes:
       - type: bind
         source: ./config
diff --git a/scheduler/cmd/scheduler/main.go b/scheduler/cmd/scheduler/main.go
index c91e4f4a1f..1163376186 100644
--- a/scheduler/cmd/scheduler/main.go
+++ b/scheduler/cmd/scheduler/main.go
@@ -35,28 +35,34 @@ import (
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/store"
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/store/experiment"
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/store/pipeline"
+	"github.com/seldonio/seldon-core/scheduler/v2/pkg/synchroniser"
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/tracing"
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/util"
 )
 
 var (
-	envoyPort               uint
-	agentPort               uint
-	agentMtlsPort           uint
-	schedulerPort           uint
-	schedulerMtlsPort       uint
-	chainerPort             uint
-	namespace               string
-	pipelineGatewayHost     string
-	pipelineGatewayHttpPort int
-	pipelineGatewayGrpcPort int
-	logLevel                string
-	tracingConfigPath       string
-	dbPath                  string
-	nodeID                  string
-	allowPlaintxt           bool //scheduler server
-	autoscalingDisabled     bool
-	kafkaConfigPath         string
+	envoyPort                    uint
+	agentPort                    uint
+	agentMtlsPort                uint
+	schedulerPort                uint
+	schedulerMtlsPort            uint
+	chainerPort                  uint
+	namespace                    string
+	pipelineGatewayHost          string
+	pipelineGatewayHttpPort      int
+	pipelineGatewayGrpcPort      int
+	logLevel                     string
+	tracingConfigPath            string
+	dbPath                       string
+	nodeID                       string
+	allowPlaintxt                bool //scheduler server
+	autoscalingDisabled          bool
+	kafkaConfigPath              string
+	schedulerReadyTimeoutSeconds uint
+)
+
+const (
+	xDSWaitTimeout = time.Duration(10 * time.Second)
 )
 
 func init() {
@@ -98,12 +104,17 @@ func init() {
 
 	// Whether to enable autoscaling, default is true
 	flag.BoolVar(&autoscalingDisabled, "disable-autoscaling", false, "Disable autoscaling feature")
+
+	// Kafka config path
 	flag.StringVar(
 		&kafkaConfigPath,
 		"kafka-config-path",
 		"/mnt/config/kafka.json",
 		"Path to kafka configuration file",
 	)
+
+	// Timeout for scheduler to be ready
+	flag.UintVar(&schedulerReadyTimeoutSeconds, "scheduler-ready-timeout-seconds", 300, "Timeout for scheduler to be ready")
 }
 
 func getNamespace() string {
@@ -137,6 +148,8 @@ func main() {
 	logger.Infof("Setting log level to %s", logLevel)
 	logger.SetLevel(logIntLevel)
 
+	logger.Debugf("Scheduler ready timeout is set to %d seconds", schedulerReadyTimeoutSeconds)
+
 	done := make(chan bool, 1)
 
 	namespace = getNamespace()
@@ -149,16 +162,8 @@ func main() {
 	defer eventHub.Close()
 	go makeSignalHandler(logger, done)
 
-	// Start xDS server
 	// Create a cache
 	xdsCache := cache.NewSnapshotCache(false, cache.IDHash{}, logger)
-	ctx := context.Background()
-	srv := envoyServerControlPlaneV3.NewServer(ctx, xdsCache, nil)
-	xdsServer := envoyServer.NewXDSServer(srv, logger)
-	err = xdsServer.StartXDSServer(envoyPort)
-	if err != nil {
-		log.WithError(err).Fatalf("Failed to start envoy xDS server")
-	}
 
 	tracer, err := tracing.NewTraceProvider("seldon-scheduler", &tracingConfigPath, logger)
 	if err != nil {
@@ -167,6 +172,7 @@ func main() {
 		defer tracer.Stop()
 	}
 
+	// Create stores
 	ss := store.NewMemoryStore(logger, store.NewLocalSchedulerStore(), eventHub)
 	ps := pipeline.NewPipelineStore(logger, eventHub, ss)
 	es := experiment.NewExperimentServer(logger, eventHub, ss, ps)
@@ -178,19 +184,13 @@ func main() {
 		GrpcPort: pipelineGatewayGrpcPort,
 	}
 
+	// Create envoy incremental processor
 	_, err = processor.NewIncrementalProcessor(xdsCache, nodeID, logger, ss, es, ps, eventHub, &pipelineGatewayDetails, cleaner)
 	if err != nil {
 		log.WithError(err).Fatalf("Failed to create incremental processor")
 	}
 
-	sched := scheduler.NewSimpleScheduler(
-		logger,
-		ss,
-		scheduler.DefaultSchedulerConfig(ss),
-	)
-	logger.Infof("Autoscaling service is set to %t", !autoscalingDisabled)
-	as := agent.NewAgentServer(logger, ss, sched, eventHub, !autoscalingDisabled)
-
+	// scheduler <-> dataflow grpc
 	dataFlowLoadBalancer := util.NewRingLoadBalancer(1)
 	kafkaConfigMap, err := config.NewKafkaConfig(kafkaConfigPath)
 	if err != nil {
@@ -223,17 +223,57 @@ func main() {
 		log.Warn("Not running with scheduler local DB")
 	}
 
-	s := schedulerServer.NewSchedulerServer(logger, ss, es, ps, sched, eventHub)
+	// Setup synchroniser
+	var sync synchroniser.Synchroniser
+
+	if namespace == "" {
+		// running outside k8s
+		sync = synchroniser.NewSimpleSynchroniser(time.Duration(schedulerReadyTimeoutSeconds) * time.Second)
+	} else {
+		sync = synchroniser.NewServerBasedSynchroniser(eventHub, logger, time.Duration(schedulerReadyTimeoutSeconds)*time.Second)
+	}
+
+	// scheduler scheduling models service
+	sched := scheduler.NewSimpleScheduler(
+		logger,
+		ss,
+		scheduler.DefaultSchedulerConfig(ss),
+		sync,
+	)
+
+	// scheduler <-> controller grpc
+	s := schedulerServer.NewSchedulerServer(logger, ss, es, ps, sched, eventHub, sync)
 	err = s.StartGrpcServers(allowPlaintxt, schedulerPort, schedulerMtlsPort)
 	if err != nil {
 		log.WithError(err).Fatalf("Failed to start server gRPC servers")
 	}
 
+	// scheduler <-> agent  grpc
+	logger.Infof("Autoscaling service is set to %t", !autoscalingDisabled)
+	as := agent.NewAgentServer(logger, ss, sched, eventHub, !autoscalingDisabled)
 	err = as.StartGrpcServer(allowPlaintxt, agentPort, agentMtlsPort)
 	if err != nil {
 		log.WithError(err).Fatalf("Failed to start agent gRPC server")
 	}
 
+	// wait for model servers to be ready
+	sync.WaitReady()
+
+	// extra wait to allow routes state to get created
+	time.Sleep(xDSWaitTimeout)
+
+	// Start envoy xDS server, this is done after the scheduler is ready
+	// so that the xDS server can start sending valid updates to envoy.
+	ctx := context.Background()
+	srv := envoyServerControlPlaneV3.NewServer(ctx, xdsCache, nil)
+	xdsServer := envoyServer.NewXDSServer(srv, logger)
+	err = xdsServer.StartXDSServer(envoyPort)
+	if err != nil {
+		log.WithError(err).Fatalf("Failed to start envoy xDS server")
+	}
+
+	log.Info("Scheduler is ready")
+
 	// Wait for completion
 	<-done
 
diff --git a/scheduler/env.all b/scheduler/env.all
index 08b5dbfbaa..57cb872a21 100644
--- a/scheduler/env.all
+++ b/scheduler/env.all
@@ -62,3 +62,5 @@ HODOMETER_RECEIVER_LOG_LEVEL=info
 KAFKA_MESSAGE_MAX_BYTES=1000000000
 
 OTEL_EXPORTER_OTLP_PROTOCOL=grpc
+
+SCHEDULER_READY_TIMEOUT_SECONDS=30
diff --git a/scheduler/pkg/agent/server.go b/scheduler/pkg/agent/server.go
index f4b14e8f21..3db874a858 100644
--- a/scheduler/pkg/agent/server.go
+++ b/scheduler/pkg/agent/server.go
@@ -390,7 +390,12 @@ func (s *Server) Subscribe(request *pb.AgentSubscribeRequest, stream pb.AgentSer
 	}
 	s.mutex.Unlock()
 
-	err := s.syncMessage(request)
+	s.logger.Debugf("Add Server Replica %+v with config %+v", request, request.ReplicaConfig)
+	err := s.store.AddServerReplica(request)
+	if err != nil {
+		return err
+	}
+	err = s.scheduleModelsFromRequest(request)
 	if err != nil {
 		return err
 	}
@@ -421,13 +426,7 @@ func (s *Server) StopAgentStreams() {
 	}
 }
 
-func (s *Server) syncMessage(request *pb.AgentSubscribeRequest) error {
-	s.logger.Debugf("Add Server Replica %+v with config %+v", request, request.ReplicaConfig)
-	err := s.store.AddServerReplica(request)
-	if err != nil {
-		return err
-	}
-
+func (s *Server) scheduleModelsFromRequest(request *pb.AgentSubscribeRequest) error {
 	// we have to reschedule models that are loaded on the incoming agent
 	// this is because we can have a network glitch that causes the communication between the agent and the scheduler
 	// to drop and the scheduler loading the models on other servers.
@@ -439,7 +438,7 @@ func (s *Server) syncMessage(request *pb.AgentSubscribeRequest) error {
 		}
 	}
 
-	_, err = s.scheduler.ScheduleFailedModels()
+	_, err := s.scheduler.ScheduleFailedModels()
 	if err != nil {
 		return err
 	}
diff --git a/scheduler/pkg/coordinator/hub.go b/scheduler/pkg/coordinator/hub.go
index d03b3daf78..450959f552 100644
--- a/scheduler/pkg/coordinator/hub.go
+++ b/scheduler/pkg/coordinator/hub.go
@@ -20,6 +20,7 @@ import (
 
 const (
 	topicModelEvents      = "model.event"
+	topicServerEvents     = "server.event"
 	topicExperimentEvents = "experiment.event"
 	topicPipelineEvents   = "pipeline.event"
 )
@@ -39,6 +40,7 @@ type EventHub struct {
 	bus                            *busV3.Bus
 	logger                         log.FieldLogger
 	modelEventHandlerChannels      []chan ModelEventMsg
+	serverEventHandlerChannels     []chan ServerEventMsg
 	experimentEventHandlerChannels []chan ExperimentEventMsg
 	pipelineEventHandlerChannels   []chan PipelineEventMsg
 	lock                           sync.RWMutex
@@ -59,7 +61,7 @@ func NewEventHub(l log.FieldLogger) (*EventHub, error) {
 		bus:    bus,
 	}
 
-	hub.bus.RegisterTopics(topicModelEvents, topicExperimentEvents, topicPipelineEvents)
+	hub.bus.RegisterTopics(topicModelEvents, topicServerEvents, topicExperimentEvents, topicPipelineEvents)
 
 	return &hub, nil
 }
@@ -74,6 +76,10 @@ func (h *EventHub) Close() {
 		close(c)
 	}
 
+	for _, c := range h.serverEventHandlerChannels {
+		close(c)
+	}
+
 	for _, c := range h.experimentEventHandlerChannels {
 		close(c)
 	}
diff --git a/scheduler/pkg/coordinator/model.go b/scheduler/pkg/coordinator/model.go
index 14c8737362..a0ebb4463f 100644
--- a/scheduler/pkg/coordinator/model.go
+++ b/scheduler/pkg/coordinator/model.go
@@ -32,14 +32,13 @@ func (h *EventHub) RegisterModelEventHandler(
 		}
 	}()
 
-	handler := h.newModelEventHandler(logger, events, handle)
+	handler := h.newModelEventHandler(logger, events)
 	h.bus.RegisterHandler(name, handler)
 }
 
 func (h *EventHub) newModelEventHandler(
 	logger log.FieldLogger,
 	events chan ModelEventMsg,
-	handle func(event ModelEventMsg),
 ) busV3.Handler {
 	handleModelEventMessage := func(_ context.Context, e busV3.Event) {
 		l := logger.WithField("func", "handleModelEventMessage")
diff --git a/scheduler/pkg/coordinator/server.go b/scheduler/pkg/coordinator/server.go
new file mode 100644
index 0000000000..ac37807dd2
--- /dev/null
+++ b/scheduler/pkg/coordinator/server.go
@@ -0,0 +1,99 @@
+/*
+Copyright (c) 2024 Seldon Technologies Ltd.
+
+Use of this software is governed by
+(1) the license included in the LICENSE file or
+(2) if the license included in the LICENSE file is the Business Source License 1.1,
+the Change License after the Change Date as each is defined in accordance with the LICENSE file.
+*/
+
+package coordinator
+
+import (
+	"context"
+	"reflect"
+
+	busV3 "github.com/mustafaturan/bus/v3"
+	log "github.com/sirupsen/logrus"
+)
+
+func (h *EventHub) RegisterServerEventHandler(
+	name string,
+	queueSize int,
+	logger log.FieldLogger,
+	handle func(event ServerEventMsg),
+) {
+	events := make(chan ServerEventMsg, queueSize)
+	h.addServerEventHandlerChannel(events)
+
+	go func() {
+		for e := range events {
+			handle(e)
+		}
+	}()
+
+	handler := h.newServerEventHandler(logger, events)
+	h.bus.RegisterHandler(name, handler)
+}
+
+func (h *EventHub) newServerEventHandler(
+	logger log.FieldLogger,
+	events chan ServerEventMsg,
+) busV3.Handler {
+	handleServerEventMessage := func(_ context.Context, e busV3.Event) {
+		l := logger.WithField("func", "handleServerEventMessage")
+		l.Debugf("Received event on %s from %s (ID: %s, TxID: %s)", e.Topic, e.Source, e.ID, e.TxID)
+
+		me, ok := e.Data.(ServerEventMsg)
+		if !ok {
+			l.Warnf(
+				"Event (ID %s, TxID %s) on topic %s from %s is not a ServerEventMsg: %s",
+				e.ID,
+				e.TxID,
+				e.Topic,
+				e.Source,
+				reflect.TypeOf(e.Data).String(),
+			)
+			return
+		}
+
+		h.lock.RLock()
+		if h.closed {
+			return
+		}
+		// Propagate the busV3.Event source to the ServerEventMsg
+		// This is useful for logging, but also in case we want to distinguish
+		// the action to take based on where the event came from.
+		me.Source = e.Source
+		events <- me
+		h.lock.RUnlock()
+	}
+
+	return busV3.Handler{
+		Matcher: topicServerEvents,
+		Handle:  handleServerEventMessage,
+	}
+}
+
+func (h *EventHub) addServerEventHandlerChannel(c chan ServerEventMsg) {
+	h.lock.Lock()
+	defer h.lock.Unlock()
+
+	h.serverEventHandlerChannels = append(h.serverEventHandlerChannels, c)
+}
+
+func (h *EventHub) PublishServerEvent(source string, event ServerEventMsg) {
+	err := h.bus.EmitWithOpts(
+		context.Background(),
+		topicServerEvents,
+		event,
+		busV3.WithSource(source),
+	)
+	if err != nil {
+		h.logger.WithError(err).Errorf(
+			"unable to publish server event message from %s to %s",
+			source,
+			topicServerEvents,
+		)
+	}
+}
diff --git a/scheduler/pkg/coordinator/types.go b/scheduler/pkg/coordinator/types.go
index bb7e8c3a09..ca8a43a2d9 100644
--- a/scheduler/pkg/coordinator/types.go
+++ b/scheduler/pkg/coordinator/types.go
@@ -11,6 +11,13 @@ package coordinator
 
 import "fmt"
 
+type ServerEventUpdateContext int
+
+const (
+	SERVER_STATUS_UPDATE ServerEventUpdateContext = iota
+	SERVER_REPLICA_CONNECTED
+)
+
 type ModelEventMsg struct {
 	ModelName    string
 	ModelVersion uint32
@@ -20,6 +27,17 @@ func (m ModelEventMsg) String() string {
 	return fmt.Sprintf("%s:%d", m.ModelName, m.ModelVersion)
 }
 
+type ServerEventMsg struct {
+	ServerName    string
+	ServerIdx     uint32
+	Source        string
+	UpdateContext ServerEventUpdateContext
+}
+
+func (m ServerEventMsg) String() string {
+	return fmt.Sprintf("%s:%d", m.ServerName, m.ServerIdx)
+}
+
 type ExperimentEventMsg struct {
 	ExperimentName    string
 	UpdatedExperiment bool
diff --git a/scheduler/pkg/scheduler/scheduler.go b/scheduler/pkg/scheduler/scheduler.go
index d7edf93631..c43465547a 100644
--- a/scheduler/pkg/scheduler/scheduler.go
+++ b/scheduler/pkg/scheduler/scheduler.go
@@ -21,12 +21,14 @@ import (
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/scheduler/filters"
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/scheduler/sorters"
 	store "github.com/seldonio/seldon-core/scheduler/v2/pkg/store"
+	"github.com/seldonio/seldon-core/scheduler/v2/pkg/synchroniser"
 )
 
 type SimpleScheduler struct {
 	muSortAndUpdate sync.Mutex
 	store           store.ModelStore
 	logger          log.FieldLogger
+	synchroniser    synchroniser.Synchroniser
 	SchedulerConfig
 }
 
@@ -48,20 +50,24 @@ func DefaultSchedulerConfig(store store.ModelStore) SchedulerConfig {
 
 func NewSimpleScheduler(logger log.FieldLogger,
 	store store.ModelStore,
-	schedulerConfig SchedulerConfig) *SimpleScheduler {
+	schedulerConfig SchedulerConfig,
+	synchroniser synchroniser.Synchroniser) *SimpleScheduler {
 	s := &SimpleScheduler{
 		store:           store,
 		logger:          logger.WithField("Name", "SimpleScheduler"),
 		SchedulerConfig: schedulerConfig,
+		synchroniser:    synchroniser,
 	}
 	return s
 }
 
 func (s *SimpleScheduler) Schedule(modelKey string) error {
+	s.synchroniser.WaitReady()
 	return s.scheduleToServer(modelKey)
 }
 
 func (s *SimpleScheduler) ScheduleFailedModels() ([]string, error) {
+	s.synchroniser.WaitReady()
 	failedModels, err := s.getFailedModels()
 	if err != nil {
 		return nil, err
diff --git a/scheduler/pkg/server/server.go b/scheduler/pkg/server/server.go
index a882b8b300..64e436be91 100644
--- a/scheduler/pkg/server/server.go
+++ b/scheduler/pkg/server/server.go
@@ -31,6 +31,7 @@ import (
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/store"
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/store/experiment"
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/store/pipeline"
+	"github.com/seldonio/seldon-core/scheduler/v2/pkg/synchroniser"
 )
 
 const (
@@ -61,6 +62,7 @@ type SchedulerServer struct {
 	pipelineEventStream   PipelineEventStream
 	certificateStore      *seldontls.CertificateStore
 	timeout               time.Duration
+	synchroniser          synchroniser.Synchroniser
 }
 
 type ModelEventStream struct {
@@ -173,6 +175,7 @@ func NewSchedulerServer(
 	pipelineHandler pipeline.PipelineHandler,
 	scheduler scheduler2.Scheduler,
 	eventHub *coordinator.EventHub,
+	synchroniser synchroniser.Synchroniser,
 ) *SchedulerServer {
 	s := &SchedulerServer{
 		logger:           logger.WithField("source", "SchedulerServer"),
@@ -195,7 +198,8 @@ func NewSchedulerServer(
 		experimentEventStream: ExperimentEventStream{
 			streams: make(map[pb.Scheduler_SubscribeExperimentStatusServer]*ExperimentSubscription),
 		},
-		timeout: sendTimeout,
+		timeout:      sendTimeout,
+		synchroniser: synchroniser,
 	}
 
 	eventHub.RegisterModelEventHandler(
@@ -216,7 +220,6 @@ func NewSchedulerServer(
 		s.logger,
 		s.handleExperimentEvents,
 	)
-
 	eventHub.RegisterPipelineEventHandler(
 		pipelineEventHandlerName,
 		pendingEventsQueueSize,
@@ -229,6 +232,8 @@ func NewSchedulerServer(
 
 func (s *SchedulerServer) ServerNotify(ctx context.Context, req *pb.ServerNotifyRequest) (*pb.ServerNotifyResponse, error) {
 	logger := s.logger.WithField("func", "ServerNotify")
+	// numExpectedReplicas is only used when we are doing the first sync
+	numExpectedReplicas := uint(0)
 	for _, server := range req.GetServers() {
 		logger.Infof("Server notification %s expectedReplicas %d shared %v", server.GetName(), server.GetExpectedReplicas(), server.GetShared())
 		err := s.modelStore.ServerNotify(server)
@@ -238,6 +243,11 @@ func (s *SchedulerServer) ServerNotify(ctx context.Context, req *pb.ServerNotify
 		if server.ExpectedReplicas == 0 {
 			go s.rescheduleModels(server.GetName())
 		}
+		numExpectedReplicas += uint(server.ExpectedReplicas)
+	}
+	if req.IsFirstSync {
+		s.synchroniser.Signals(numExpectedReplicas)
+		logger.Infof("Signalling synchroniser with %d expected server agents to connect", numExpectedReplicas)
 	}
 	return &pb.ServerNotifyResponse{}, nil
 }
diff --git a/scheduler/pkg/store/memory.go b/scheduler/pkg/store/memory.go
index baae186431..e2a3b6e611 100644
--- a/scheduler/pkg/store/memory.go
+++ b/scheduler/pkg/store/memory.go
@@ -566,7 +566,7 @@ func (m *MemoryStore) updateReservedMemory(
 }
 
 func (m *MemoryStore) AddServerReplica(request *agent.AgentSubscribeRequest) error {
-	evts, err := m.addServerReplicaImpl(request)
+	evts, serverEvt, err := m.addServerReplicaImpl(request)
 	if err != nil {
 		return err
 	}
@@ -577,11 +577,15 @@ func (m *MemoryStore) AddServerReplica(request *agent.AgentSubscribeRequest) err
 				evt,
 			)
 		}
+		m.eventHub.PublishServerEvent(
+			serverUpdateEventSource,
+			serverEvt,
+		)
 	}
 	return nil
 }
 
-func (m *MemoryStore) addServerReplicaImpl(request *agent.AgentSubscribeRequest) ([]coordinator.ModelEventMsg, error) {
+func (m *MemoryStore) addServerReplicaImpl(request *agent.AgentSubscribeRequest) ([]coordinator.ModelEventMsg, coordinator.ServerEventMsg, error) {
 	m.mu.Lock()
 	defer m.mu.Unlock()
 
@@ -615,7 +619,13 @@ func (m *MemoryStore) addServerReplicaImpl(request *agent.AgentSubscribeRequest)
 		})
 	}
 
-	return evts, nil
+	serverEvt := coordinator.ServerEventMsg{
+		ServerName:    request.ServerName,
+		ServerIdx:     uint32(request.ReplicaIdx),
+		UpdateContext: coordinator.SERVER_REPLICA_CONNECTED,
+	}
+
+	return evts, serverEvt, nil
 }
 
 func (m *MemoryStore) RemoveServerReplica(serverName string, replicaIdx int) ([]string, error) {
diff --git a/scheduler/pkg/store/memory_status.go b/scheduler/pkg/store/memory_status.go
index bda7371554..9a2dfc14de 100644
--- a/scheduler/pkg/store/memory_status.go
+++ b/scheduler/pkg/store/memory_status.go
@@ -18,6 +18,7 @@ import (
 const (
 	modelFailureEventSource = "memory.status.scheduling.failed"
 	modelUpdateEventSource  = "memory.status.model.update"
+	serverUpdateEventSource = "memory.status.server.update"
 )
 
 type modelVersionStateStatistics struct {
diff --git a/scheduler/pkg/synchroniser/servers_sync.go b/scheduler/pkg/synchroniser/servers_sync.go
new file mode 100644
index 0000000000..e17164c65f
--- /dev/null
+++ b/scheduler/pkg/synchroniser/servers_sync.go
@@ -0,0 +1,149 @@
+/*
+Copyright (c) 2024 Seldon Technologies Ltd.
+
+Use of this software is governed by
+(1) the license included in the LICENSE file or
+(2) if the license included in the LICENSE file is the Business Source License 1.1,
+the Change License after the Change Date as each is defined in accordance with the LICENSE file.
+*/
+
+// This file includes the ServerBasedSynchroniser struct and its methods.
+// The ServerBasedSynchroniser struct is responsible for synchronising the starting up of the different components of the "scheduler".
+// It ensures that the time between the scheduler starting and the different model servers connecting does not affect the data plane (inferences).
+// In general terms, the synchroniser waits for all servers to connect before proceeding with processing events, especially those that are related to the servers connecting (i.e model scheduling).
+// Otherwise if we dont wait for all servers to connect, we may get 404s when the scheduler tries to schedule models on servers that have not connected yet.
+// The main trick is that the "controller" will send a number of expected servers to connect based on its etcd state, then the synchroniser will wait for all servers to connect before proceeding.
+// The synchroniser will also wait for a timeout to be reached before proceeding if not all servers connect in time.
+// the synchroniser subsribes to the server event handler and listens for SERVER_REPLICA_CONNECTED events, which are triggered when agents connect to the scheduler.
+// The struct implements the Synchroniser interface, which includes the IsReady, WaitReady, and Signals methods.
+// The struct also includes the handleServerEvents and doneFn methods.
+
+// The ServerBasedSynchroniser struct is defined as follows:
+// - It has the following fields:
+//   - isReady: an atomic boolean value that indicates whether the synchroniser is ready.
+//   - numEvents: an unsigned integer value that represents the number of events seen so far (connected servers).
+//   - maxEvents: an unsigned integer value that represents the maximum number of events (expected servers).
+//   - signalWg: a sync.WaitGroup value that is used to wait for the signal before processing events (controller to connect).
+//   - eventHub: a pointer to the EventHub struct that is used to handle events.
+//   - logger: a log.FieldLogger value that is used for logging.
+//   - connectedServers: a map of strings to empty structs that stores the names of connected servers.
+//   - connectedServersMu: a sync.Mutex value that is used to protect access to the connectedServers map.
+//   - timeout: a time.Duration value that represents the timeout duration.
+//   - doneWg: a sync.WaitGroup value that is used to wait for the timeout to be reached or all servers to connect.
+//   - triggered: an atomic boolean value that indicates whether the synchroniser has been triggered.
+
+package synchroniser
+
+import (
+	"fmt"
+	"sync"
+	"sync/atomic"
+	"time"
+
+	log "github.com/sirupsen/logrus"
+
+	"github.com/seldonio/seldon-core/scheduler/v2/pkg/coordinator"
+)
+
+const (
+	pendingSyncsQueueSize  int = 1000
+	serverEventHandlerName     = "incremental.processor.servers"
+)
+
+type ServerBasedSynchroniser struct {
+	isReady            atomic.Bool
+	numEvents          uint64
+	maxEvents          uint64
+	signalWg           sync.WaitGroup
+	eventHub           *coordinator.EventHub
+	logger             log.FieldLogger
+	connectedServers   map[string]struct{}
+	connectedServersMu sync.Mutex
+	timeout            time.Duration
+	doneWg             sync.WaitGroup
+	triggered          atomic.Bool
+}
+
+func NewServerBasedSynchroniser(eventHub *coordinator.EventHub, logger log.FieldLogger, timeout time.Duration) *ServerBasedSynchroniser {
+	s := &ServerBasedSynchroniser{
+		isReady:            atomic.Bool{},
+		numEvents:          0,
+		maxEvents:          0,
+		eventHub:           eventHub,
+		logger:             logger.WithField("source", "ServerBasedSynchroniser"),
+		connectedServers:   make(map[string]struct{}),
+		connectedServersMu: sync.Mutex{},
+		timeout:            timeout,
+		triggered:          atomic.Bool{},
+	}
+	s.isReady.Store(false)
+	s.triggered.Store(false)
+	s.signalWg.Add(1) // wait fist for signal before processing events
+	s.doneWg.Add(1)   // we wait for the timeout to be reached or all servers to connect
+
+	time.AfterFunc(s.timeout, s.doneFn)
+
+	eventHub.RegisterServerEventHandler(
+		serverEventHandlerName,
+		pendingSyncsQueueSize,
+		logger,
+		s.handleServerEvents,
+	)
+
+	return s
+}
+
+func (s *ServerBasedSynchroniser) IsReady() bool {
+	return s.isReady.Load()
+}
+
+func (s *ServerBasedSynchroniser) WaitReady() {
+	if !s.isReady.Load() {
+		s.doneWg.Wait()
+	}
+}
+
+func (s *ServerBasedSynchroniser) Signals(numSignals uint) {
+	if !s.isReady.Load() {
+		swapped := s.triggered.CompareAndSwap(false, true) // make sure we run only once
+		if swapped {
+			atomic.AddUint64(&s.maxEvents, uint64(numSignals))
+			s.signalWg.Done()
+		}
+	}
+}
+
+func (s *ServerBasedSynchroniser) doneFn() {
+	if s.isReady.CompareAndSwap(false, true) {
+		s.doneWg.Done()
+		s.logger.Debugf("Synchroniser is ready")
+	}
+}
+
+func (s *ServerBasedSynchroniser) handleServerEvents(event coordinator.ServerEventMsg) {
+	logger := s.logger.WithField("func", "handleServerEvents")
+	logger.Debugf("Received sync for server %s", event.String())
+
+	// we do not want to block the event handler while waiting for the signal to be fired as it may cause a deadlock with
+	// other events handlers.
+	// we also do not care about order of events, so we can safely spawn a go routine to handle the signal
+	if event.UpdateContext == coordinator.SERVER_REPLICA_CONNECTED && !s.isReady.Load() {
+		go func() {
+			s.signalWg.Wait()
+
+			s.connectedServersMu.Lock()
+			defer s.connectedServersMu.Unlock()
+
+			serverNameWithIdx := fmt.Sprintf("%s-%d", event.ServerName, event.ServerIdx)
+
+			if _, ok := s.connectedServers[serverNameWithIdx]; !ok {
+				s.connectedServers[serverNameWithIdx] = struct{}{}
+				if len(s.connectedServers) == int(s.maxEvents) {
+					s.doneFn()
+					s.logger.Infof("All (num: %d) servers connected", s.maxEvents)
+				}
+			}
+
+		}()
+	}
+}
diff --git a/scheduler/pkg/synchroniser/sync.go b/scheduler/pkg/synchroniser/sync.go
new file mode 100644
index 0000000000..acc3ec25a3
--- /dev/null
+++ b/scheduler/pkg/synchroniser/sync.go
@@ -0,0 +1,68 @@
+/*
+Copyright (c) 2024 Seldon Technologies Ltd.
+
+Use of this software is governed by
+(1) the license included in the LICENSE file or
+(2) if the license included in the LICENSE file is the Business Source License 1.1,
+the Change License after the Change Date as each is defined in accordance with the LICENSE file.
+*/
+
+// This package is responsible to synchronise starting up the different components of the "scheduler".
+// In particular, it is responsible for making sure that the time between the scheduler starts and while
+// the different model servers connect that the data plane (inferences) is not affected.
+package synchroniser
+
+import (
+	"sync"
+	"sync/atomic"
+	"time"
+)
+
+type Synchroniser interface {
+	IsReady() bool
+	WaitReady()
+	Signals(uint)
+}
+
+type SimpleSynchroniser struct {
+	isReady   atomic.Bool
+	wg        sync.WaitGroup
+	timeout   time.Duration
+	triggered atomic.Bool
+}
+
+func NewSimpleSynchroniser(timeout time.Duration) *SimpleSynchroniser {
+	s := &SimpleSynchroniser{
+		isReady: atomic.Bool{},
+		wg:      sync.WaitGroup{},
+		timeout: timeout,
+	}
+	s.isReady.Store(false)
+	s.triggered.Store(false)
+	return s
+}
+
+func (s *SimpleSynchroniser) IsReady() bool {
+	return s.isReady.Load()
+}
+
+func (s *SimpleSynchroniser) Signals(numSignals uint) {
+	if !s.IsReady() {
+		swapped := s.triggered.CompareAndSwap(false, true) // make sure we run only once
+		if swapped {
+			s.wg.Add(int(numSignals))
+			time.AfterFunc(s.timeout, s.done)
+		}
+	}
+}
+
+func (s *SimpleSynchroniser) WaitReady() {
+	if !s.IsReady() {
+		s.wg.Wait()
+	}
+}
+
+func (s *SimpleSynchroniser) done() {
+	s.isReady.Store(true)
+	s.wg.Done()
+}


Test patch:
diff --git a/operator/scheduler/server_test.go b/operator/scheduler/server_test.go
index 69d8e72149..20ab372744 100644
--- a/operator/scheduler/server_test.go
+++ b/operator/scheduler/server_test.go
@@ -161,7 +161,7 @@ func TestServerNotify(t *testing.T) {
 				requests_servers: []*scheduler.ServerNotify{},
 			}
 			controller := newMockControllerClient()
-			err := controller.ServerNotify(context.Background(), &grpcClient, test.servers)
+			err := controller.ServerNotify(context.Background(), &grpcClient, test.servers, false)
 			g.Expect(err).To(BeNil())
 
 			if len(test.servers) != 0 {
diff --git a/scheduler/pkg/coordinator/events_test.go b/scheduler/pkg/coordinator/events_test.go
new file mode 100644
index 0000000000..88ece44a17
--- /dev/null
+++ b/scheduler/pkg/coordinator/events_test.go
@@ -0,0 +1,637 @@
+/*
+Copyright (c) 2024 Seldon Technologies Ltd.
+
+Use of this software is governed by
+(1) the license included in the LICENSE file or
+(2) if the license included in the LICENSE file is the Business Source License 1.1,
+the Change License after the Change Date as each is defined in accordance with the LICENSE file.
+*/
+
+package coordinator
+
+import (
+	"fmt"
+	"sync/atomic"
+	"testing"
+	"time"
+
+	log "github.com/sirupsen/logrus"
+	"github.com/stretchr/testify/require"
+)
+
+type eventHubTestOp int
+
+const (
+	modelEventHub eventHubTestOp = iota
+	serverEventHub
+	pipelineEventHub
+	experimentEventHub
+)
+
+func TestRegisterHandler(t *testing.T) {
+	type test struct {
+		name        string
+		numHandlers int
+		op          eventHubTestOp
+	}
+
+	tests := []test{
+		// models
+		{
+			name:        "0 handlers do not block publishing - models",
+			numHandlers: 0,
+			op:          modelEventHub,
+		},
+		{
+			name:        "1 handler receives events - models",
+			numHandlers: 1,
+			op:          modelEventHub,
+		},
+		{
+			name:        "n handlers all receive all events - models",
+			numHandlers: 20,
+			op:          modelEventHub,
+		},
+
+		// servers
+		{
+			name:        "0 handlers do not block publishing - servers",
+			numHandlers: 0,
+			op:          serverEventHub,
+		},
+		{
+			name:        "1 handler receives events - servers",
+			numHandlers: 1,
+			op:          serverEventHub,
+		},
+		{
+			name:        "n handlers all receive all events - servers",
+			numHandlers: 20,
+			op:          serverEventHub,
+		},
+
+		// pipelines
+		{
+			name:        "0 handlers do not block publishing - pipelines",
+			numHandlers: 0,
+			op:          pipelineEventHub,
+		},
+		{
+			name:        "1 handler receives events - pipelines",
+			numHandlers: 1,
+			op:          pipelineEventHub,
+		},
+		{
+			name:        "n handlers all receive all events - pipelines",
+			numHandlers: 20,
+			op:          pipelineEventHub,
+		},
+
+		// experiments
+		{
+			name:        "0 handlers do not block publishing - experiments",
+			numHandlers: 0,
+			op:          experimentEventHub,
+		},
+		{
+			name:        "1 handler receives events - experiments",
+			numHandlers: 1,
+			op:          experimentEventHub,
+		},
+		{
+			name:        "n handlers all receive all events - experiments",
+			numHandlers: 20,
+			op:          experimentEventHub,
+		},
+	}
+
+	queueSize := 100
+	numEvents := 10
+	eventSource := "test.publisher"
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			l := log.New()
+			h, err := NewEventHub(l)
+			require.Nil(t, err)
+
+			var counter int64
+
+			for i := 0; i < tt.numHandlers; i++ {
+				if tt.op == modelEventHub {
+					h.RegisterModelEventHandler(
+						fmt.Sprintf("handler-%d", i),
+						queueSize,
+						l,
+						func(event ModelEventMsg) { atomic.AddInt64(&counter, 1) },
+					)
+				} else if tt.op == serverEventHub {
+					h.RegisterServerEventHandler(
+						fmt.Sprintf("handler-%d", i),
+						queueSize,
+						l,
+						func(event ServerEventMsg) { atomic.AddInt64(&counter, 1) },
+					)
+				} else if tt.op == pipelineEventHub {
+					h.RegisterPipelineEventHandler(
+						fmt.Sprintf("handler-%d", i),
+						queueSize,
+						l,
+						func(event PipelineEventMsg) { atomic.AddInt64(&counter, 1) },
+					)
+				} else if tt.op == experimentEventHub {
+					h.RegisterExperimentEventHandler(
+						fmt.Sprintf("handler-%d", i),
+						queueSize,
+						l,
+						func(event ExperimentEventMsg) { atomic.AddInt64(&counter, 1) },
+					)
+				}
+			}
+
+			for i := 0; i < numEvents; i++ {
+				if tt.op == modelEventHub {
+					h.PublishModelEvent(
+						eventSource,
+						ModelEventMsg{},
+					)
+				} else if tt.op == serverEventHub {
+					h.PublishServerEvent(
+						eventSource,
+						ServerEventMsg{},
+					)
+				} else if tt.op == pipelineEventHub {
+					h.PublishPipelineEvent(
+						eventSource,
+						PipelineEventMsg{},
+					)
+				} else if tt.op == experimentEventHub {
+					h.PublishExperimentEvent(
+						eventSource,
+						ExperimentEventMsg{},
+					)
+				}
+			}
+
+			// Handlers are async, so need a little while to run
+			time.Sleep(5 * time.Millisecond)
+
+			require.Equal(t, tt.numHandlers, len(h.bus.HandlerKeys()))
+			require.Equal(t, numEvents*tt.numHandlers, int(counter))
+		})
+	}
+}
+
+func TestPublishModelEvent(t *testing.T) {
+	type test struct {
+		name            string
+		numPublishers   int
+		numEventsBefore int
+		numEventsAfter  int
+		op              eventHubTestOp
+	}
+
+	tests := []test{
+		// models
+		{
+			name:            "Events published before handler registration are ignored - models",
+			numPublishers:   1,
+			numEventsBefore: 10,
+			numEventsAfter:  0,
+			op:              modelEventHub,
+		},
+		{
+			name:            "Events published after handler registration are received - models",
+			numPublishers:   1,
+			numEventsBefore: 0,
+			numEventsAfter:  10,
+			op:              modelEventHub,
+		},
+		{
+			name:            "Only events published after handler registration are received - models",
+			numPublishers:   1,
+			numEventsBefore: 10,
+			numEventsAfter:  10,
+			op:              modelEventHub,
+		},
+		{
+			name:            "Multiple producers can publish to the same topic - models",
+			numPublishers:   10,
+			numEventsBefore: 10,
+			numEventsAfter:  10,
+			op:              modelEventHub,
+		},
+
+		// servers
+		{
+			name:            "Events published before handler registration are ignored - servers",
+			numPublishers:   1,
+			numEventsBefore: 10,
+			numEventsAfter:  0,
+			op:              serverEventHub,
+		},
+		{
+			name:            "Events published after handler registration are received - servers",
+			numPublishers:   1,
+			numEventsBefore: 0,
+			numEventsAfter:  10,
+			op:              serverEventHub,
+		},
+		{
+			name:            "Only events published after handler registration are received - servers",
+			numPublishers:   1,
+			numEventsBefore: 10,
+			numEventsAfter:  10,
+			op:              serverEventHub,
+		},
+		{
+			name:            "Multiple producers can publish to the same topic - servers",
+			numPublishers:   10,
+			numEventsBefore: 10,
+			numEventsAfter:  10,
+			op:              serverEventHub,
+		},
+
+		// pipelines
+		{
+			name:            "Events published before handler registration are ignored - pipelines",
+			numPublishers:   1,
+			numEventsBefore: 10,
+			numEventsAfter:  0,
+			op:              pipelineEventHub,
+		},
+		{
+			name:            "Events published after handler registration are received - pipelines",
+			numPublishers:   1,
+			numEventsBefore: 0,
+			numEventsAfter:  10,
+			op:              pipelineEventHub,
+		},
+		{
+			name:            "Only events published after handler registration are received - pipelines",
+			numPublishers:   1,
+			numEventsBefore: 10,
+			numEventsAfter:  10,
+			op:              pipelineEventHub,
+		},
+		{
+			name:            "Multiple producers can publish to the same topic - pipelines",
+			numPublishers:   10,
+			numEventsBefore: 10,
+			numEventsAfter:  10,
+			op:              pipelineEventHub,
+		},
+
+		// experiments
+		{
+			name:            "Events published before handler registration are ignored - experiments",
+			numPublishers:   1,
+			numEventsBefore: 10,
+			numEventsAfter:  0,
+			op:              experimentEventHub,
+		},
+		{
+			name:            "Events published after handler registration are received - experiments",
+			numPublishers:   1,
+			numEventsBefore: 0,
+			numEventsAfter:  10,
+			op:              experimentEventHub,
+		},
+		{
+			name:            "Only events published after handler registration are received - experiments",
+			numPublishers:   1,
+			numEventsBefore: 10,
+			numEventsAfter:  10,
+			op:              experimentEventHub,
+		},
+		{
+			name:            "Multiple producers can publish to the same topic - experiments",
+			numPublishers:   10,
+			numEventsBefore: 10,
+			numEventsAfter:  10,
+			op:              experimentEventHub,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			l := log.New()
+			h, err := NewEventHub(l)
+			require.Nil(t, err)
+
+			for b := 0; b < tt.numEventsBefore; b++ {
+				for p := 0; p < tt.numPublishers; p++ {
+					if tt.op == modelEventHub {
+						h.PublishModelEvent(
+							fmt.Sprintf("publisher-%d", p),
+							ModelEventMsg{},
+						)
+					} else if tt.op == serverEventHub {
+						h.PublishServerEvent(
+							fmt.Sprintf("publisher-%d", p),
+							ServerEventMsg{},
+						)
+					} else if tt.op == pipelineEventHub {
+						h.PublishPipelineEvent(
+							fmt.Sprintf("publisher-%d", p),
+							PipelineEventMsg{},
+						)
+					} else if tt.op == experimentEventHub {
+						h.PublishExperimentEvent(
+							fmt.Sprintf("publisher-%d", p),
+							ExperimentEventMsg{},
+						)
+					}
+				}
+			}
+
+			var counter int64
+			queueSize := tt.numPublishers * (tt.numEventsBefore + tt.numEventsAfter)
+			if tt.op == modelEventHub {
+				h.RegisterModelEventHandler(
+					"test.handler",
+					queueSize,
+					l,
+					func(event ModelEventMsg) { atomic.AddInt64(&counter, 1) },
+				)
+			} else if tt.op == serverEventHub {
+				h.RegisterServerEventHandler(
+					"test.handler",
+					queueSize,
+					l,
+					func(event ServerEventMsg) { atomic.AddInt64(&counter, 1) },
+				)
+			} else if tt.op == pipelineEventHub {
+				h.RegisterPipelineEventHandler(
+					"test.handler",
+					queueSize,
+					l,
+					func(event PipelineEventMsg) { atomic.AddInt64(&counter, 1) },
+				)
+			} else if tt.op == experimentEventHub {
+				h.RegisterExperimentEventHandler(
+					"test.handler",
+					queueSize,
+					l,
+					func(event ExperimentEventMsg) { atomic.AddInt64(&counter, 1) },
+				)
+			}
+
+			for a := 0; a < tt.numEventsAfter; a++ {
+				for p := 0; p < tt.numPublishers; p++ {
+					if tt.op == modelEventHub {
+						h.PublishModelEvent(
+							fmt.Sprintf("publisher-%d", p),
+							ModelEventMsg{},
+						)
+					} else if tt.op == serverEventHub {
+						h.PublishServerEvent(
+							fmt.Sprintf("publisher-%d", p),
+							ServerEventMsg{},
+						)
+					} else if tt.op == pipelineEventHub {
+						h.PublishPipelineEvent(
+							fmt.Sprintf("publisher-%d", p),
+							PipelineEventMsg{},
+						)
+					} else if tt.op == experimentEventHub {
+						h.PublishExperimentEvent(
+							fmt.Sprintf("publisher-%d", p),
+							ExperimentEventMsg{},
+						)
+					}
+				}
+			}
+
+			// Handlers are async, so need a little while to run
+			time.Sleep(5 * time.Millisecond)
+
+			require.Equal(t, tt.numPublishers*tt.numEventsAfter, int(counter))
+		})
+	}
+}
+
+func TestClose(t *testing.T) {
+	type test struct {
+		name            string
+		numEventsBefore int
+		numEventsAfter  int
+		registerBefore  bool
+		expectedCount   int
+		op              eventHubTestOp
+	}
+
+	tests := []test{
+		// models
+		{
+			name:            "Immediate close is allowed - models",
+			numEventsBefore: 0,
+			numEventsAfter:  10,
+			registerBefore:  true,
+			expectedCount:   0,
+			op:              modelEventHub,
+		},
+		{
+			name:            "No events should be received after calling Close - models",
+			numEventsBefore: 10,
+			numEventsAfter:  10,
+			registerBefore:  true,
+			expectedCount:   10,
+			op:              modelEventHub,
+		},
+		{
+			name:            "No events should be received by a handler registered after calling Close - models",
+			numEventsBefore: 10,
+			numEventsAfter:  10,
+			registerBefore:  false,
+			expectedCount:   0,
+			op:              modelEventHub,
+		},
+
+		// servers
+		{
+			name:            "Immediate close is allowed - servers",
+			numEventsBefore: 0,
+			numEventsAfter:  10,
+			registerBefore:  true,
+			expectedCount:   0,
+			op:              serverEventHub,
+		},
+		{
+			name:            "No events should be received after calling Close - servers",
+			numEventsBefore: 10,
+			numEventsAfter:  10,
+			registerBefore:  true,
+			expectedCount:   10,
+			op:              serverEventHub,
+		},
+		{
+			name:            "No events should be received by a handler registered after calling Close - servers",
+			numEventsBefore: 10,
+			numEventsAfter:  10,
+			registerBefore:  false,
+			expectedCount:   0,
+			op:              serverEventHub,
+		},
+
+		// pipelines
+		{
+			name:            "Immediate close is allowed - pipelines",
+			numEventsBefore: 0,
+			numEventsAfter:  10,
+			registerBefore:  true,
+			expectedCount:   0,
+			op:              pipelineEventHub,
+		},
+		{
+			name:            "No events should be received after calling Close - pipelines",
+			numEventsBefore: 10,
+			numEventsAfter:  10,
+			registerBefore:  true,
+			expectedCount:   10,
+			op:              pipelineEventHub,
+		},
+		{
+			name:            "No events should be received by a handler registered after calling Close - pipelines",
+			numEventsBefore: 10,
+			numEventsAfter:  10,
+			registerBefore:  false,
+			expectedCount:   0,
+			op:              pipelineEventHub,
+		},
+
+		// experiments
+		{
+			name:            "Immediate close is allowed - experiments",
+			numEventsBefore: 0,
+			numEventsAfter:  10,
+			registerBefore:  true,
+			expectedCount:   0,
+			op:              experimentEventHub,
+		},
+		{
+			name:            "No events should be received after calling Close - experiments",
+			numEventsBefore: 10,
+			numEventsAfter:  10,
+			registerBefore:  true,
+			expectedCount:   10,
+			op:              experimentEventHub,
+		},
+		{
+			name:            "No events should be received by a handler registered after calling Close - experiments",
+			numEventsBefore: 10,
+			numEventsAfter:  10,
+			registerBefore:  false,
+			expectedCount:   0,
+			op:              experimentEventHub,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			l := log.New()
+			h, err := NewEventHub(l)
+			require.Nil(t, err)
+
+			var counter int64
+			queueSize := tt.numEventsBefore + tt.numEventsAfter
+
+			register := func() {
+				if tt.op == modelEventHub {
+					h.RegisterModelEventHandler(
+						"test.handler",
+						queueSize,
+						l,
+						func(event ModelEventMsg) { atomic.AddInt64(&counter, 1) },
+					)
+				} else if tt.op == serverEventHub {
+					h.RegisterServerEventHandler(
+						"test.handler",
+						queueSize,
+						l,
+						func(event ServerEventMsg) { atomic.AddInt64(&counter, 1) },
+					)
+				} else if tt.op == pipelineEventHub {
+					h.RegisterPipelineEventHandler(
+						"test.handler",
+						queueSize,
+						l,
+						func(event PipelineEventMsg) { atomic.AddInt64(&counter, 1) },
+					)
+				} else if tt.op == experimentEventHub {
+					h.RegisterExperimentEventHandler(
+						"test.handler",
+						queueSize,
+						l,
+						func(event ExperimentEventMsg) { atomic.AddInt64(&counter, 1) },
+					)
+				}
+			}
+
+			if tt.registerBefore {
+				register()
+			}
+
+			for b := 0; b < tt.numEventsBefore; b++ {
+				if tt.op == modelEventHub {
+					h.PublishModelEvent(
+						"test.publisher",
+						ModelEventMsg{},
+					)
+				} else if tt.op == serverEventHub {
+					h.PublishServerEvent(
+						"test.publisher",
+						ServerEventMsg{},
+					)
+				} else if tt.op == pipelineEventHub {
+					h.PublishPipelineEvent(
+						"test.publisher",
+						PipelineEventMsg{},
+					)
+				} else if tt.op == experimentEventHub {
+					h.PublishExperimentEvent(
+						"test.publisher",
+						ExperimentEventMsg{},
+					)
+				}
+			}
+
+			h.Close()
+
+			if !tt.registerBefore {
+				register()
+			}
+
+			for a := 0; a < tt.numEventsAfter; a++ {
+				if tt.op == modelEventHub {
+					h.PublishModelEvent(
+						"test.publisher",
+						ModelEventMsg{},
+					)
+				} else if tt.op == serverEventHub {
+					h.PublishServerEvent(
+						"test.publisher",
+						ServerEventMsg{},
+					)
+				} else if tt.op == pipelineEventHub {
+					h.PublishPipelineEvent(
+						"test.publisher",
+						PipelineEventMsg{},
+					)
+				} else if tt.op == experimentEventHub {
+					h.PublishExperimentEvent(
+						"test.publisher",
+						ExperimentEventMsg{},
+					)
+				}
+			}
+
+			// Handlers are async, so need a little while to run
+			time.Sleep(5 * time.Millisecond)
+
+			// Some events may not have been handled before close,
+			// hence the non-strict inequality.
+			require.LessOrEqual(t, tt.expectedCount, int(counter))
+		})
+	}
+}
diff --git a/scheduler/pkg/coordinator/hub_test.go b/scheduler/pkg/coordinator/hub_test.go
index 6f0543733b..77ee02136b 100644
--- a/scheduler/pkg/coordinator/hub_test.go
+++ b/scheduler/pkg/coordinator/hub_test.go
@@ -24,8 +24,8 @@ func TestNewEventHub(t *testing.T) {
 
 	tests := []test{
 		{
-			name:           "Should register two topics",
-			expectedTopics: []string{topicModelEvents, topicExperimentEvents, topicPipelineEvents},
+			name:           "Should register four topics",
+			expectedTopics: []string{topicModelEvents, topicServerEvents, topicExperimentEvents, topicPipelineEvents},
 		},
 	}
 
diff --git a/scheduler/pkg/coordinator/model_test.go b/scheduler/pkg/coordinator/model_test.go
deleted file mode 100644
index 0b550a3839..0000000000
--- a/scheduler/pkg/coordinator/model_test.go
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
-Copyright (c) 2024 Seldon Technologies Ltd.
-
-Use of this software is governed by
-(1) the license included in the LICENSE file or
-(2) if the license included in the LICENSE file is the Business Source License 1.1,
-the Change License after the Change Date as each is defined in accordance with the LICENSE file.
-*/
-
-package coordinator
-
-import (
-	"fmt"
-	"sync/atomic"
-	"testing"
-	"time"
-
-	log "github.com/sirupsen/logrus"
-	"github.com/stretchr/testify/require"
-)
-
-func TestRegisterHandler(t *testing.T) {
-	type test struct {
-		name        string
-		numHandlers int
-	}
-
-	tests := []test{
-		{
-			name:        "0 handlers do not block publishing",
-			numHandlers: 0,
-		},
-		{
-			name:        "1 handler receives events",
-			numHandlers: 1,
-		},
-		{
-			name:        "n handlers all receive all events",
-			numHandlers: 20,
-		},
-	}
-
-	queueSize := 100
-	numEvents := 10
-	eventSource := "test.publisher"
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			l := log.New()
-			h, err := NewEventHub(l)
-			require.Nil(t, err)
-
-			var counter int64
-
-			for i := 0; i < tt.numHandlers; i++ {
-				h.RegisterModelEventHandler(
-					fmt.Sprintf("handler-%d", i),
-					queueSize,
-					l,
-					func(event ModelEventMsg) { atomic.AddInt64(&counter, 1) },
-				)
-			}
-
-			for i := 0; i < numEvents; i++ {
-				h.PublishModelEvent(
-					eventSource,
-					ModelEventMsg{},
-				)
-			}
-
-			// Handlers are async, so need a little while to run
-			time.Sleep(5 * time.Millisecond)
-
-			require.Equal(t, tt.numHandlers, len(h.bus.HandlerKeys()))
-			require.Equal(t, numEvents*tt.numHandlers, int(counter))
-		})
-	}
-}
-
-func TestPublishModelEvent(t *testing.T) {
-	type test struct {
-		name            string
-		numPublishers   int
-		numEventsBefore int
-		numEventsAfter  int
-	}
-
-	tests := []test{
-		{
-			name:            "Events published before handler registration are ignored",
-			numPublishers:   1,
-			numEventsBefore: 10,
-			numEventsAfter:  0,
-		},
-		{
-			name:            "Events published after handler registration are received",
-			numPublishers:   1,
-			numEventsBefore: 0,
-			numEventsAfter:  10,
-		},
-		{
-			name:            "Only events published after handler registration are received",
-			numPublishers:   1,
-			numEventsBefore: 10,
-			numEventsAfter:  10,
-		},
-		{
-			name:            "Multiple producers can publish to the same topic",
-			numPublishers:   10,
-			numEventsBefore: 10,
-			numEventsAfter:  10,
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			l := log.New()
-			h, err := NewEventHub(l)
-			require.Nil(t, err)
-
-			for b := 0; b < tt.numEventsBefore; b++ {
-				for p := 0; p < tt.numPublishers; p++ {
-					h.PublishModelEvent(
-						fmt.Sprintf("publisher-%d", p),
-						ModelEventMsg{},
-					)
-				}
-			}
-
-			var counter int64
-			queueSize := tt.numPublishers * (tt.numEventsBefore + tt.numEventsAfter)
-			h.RegisterModelEventHandler(
-				"test.handler",
-				queueSize,
-				l,
-				func(event ModelEventMsg) { atomic.AddInt64(&counter, 1) },
-			)
-
-			for a := 0; a < tt.numEventsAfter; a++ {
-				for p := 0; p < tt.numPublishers; p++ {
-					h.PublishModelEvent(
-						fmt.Sprintf("publisher-%d", p),
-						ModelEventMsg{},
-					)
-				}
-			}
-
-			// Handlers are async, so need a little while to run
-			time.Sleep(5 * time.Millisecond)
-
-			require.Equal(t, tt.numPublishers*tt.numEventsAfter, int(counter))
-		})
-	}
-}
-
-func TestClose(t *testing.T) {
-	type test struct {
-		name            string
-		numEventsBefore int
-		numEventsAfter  int
-		registerBefore  bool
-		expectedCount   int
-	}
-
-	tests := []test{
-		{
-			name:            "Immediate close is allowed",
-			numEventsBefore: 0,
-			numEventsAfter:  10,
-			registerBefore:  true,
-			expectedCount:   0,
-		},
-		{
-			name:            "No events should be received after calling Close",
-			numEventsBefore: 10,
-			numEventsAfter:  10,
-			registerBefore:  true,
-			expectedCount:   10,
-		},
-		{
-			name:            "No events should be received by a handler registered after calling Close",
-			numEventsBefore: 10,
-			numEventsAfter:  10,
-			registerBefore:  false,
-			expectedCount:   0,
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			l := log.New()
-			h, err := NewEventHub(l)
-			require.Nil(t, err)
-
-			var counter int64
-			queueSize := tt.numEventsBefore + tt.numEventsAfter
-
-			register := func() {
-				h.RegisterModelEventHandler(
-					"test.handler",
-					queueSize,
-					l,
-					func(event ModelEventMsg) { atomic.AddInt64(&counter, 1) },
-				)
-			}
-
-			if tt.registerBefore {
-				register()
-			}
-
-			for b := 0; b < tt.numEventsBefore; b++ {
-				h.PublishModelEvent(
-					"test.publisher",
-					ModelEventMsg{},
-				)
-			}
-
-			h.Close()
-
-			if !tt.registerBefore {
-				register()
-			}
-
-			for a := 0; a < tt.numEventsAfter; a++ {
-				h.PublishModelEvent(
-					"test.publisher",
-					ModelEventMsg{},
-				)
-			}
-
-			// Handlers are async, so need a little while to run
-			time.Sleep(5 * time.Millisecond)
-
-			// Some events may not have been handled before close,
-			// hence the non-strict inequality.
-			require.LessOrEqual(t, tt.expectedCount, int(counter))
-		})
-	}
-}
diff --git a/scheduler/pkg/scheduler/scheduler_test.go b/scheduler/pkg/scheduler/scheduler_test.go
index ba92ee3ae6..35a214e6fd 100644
--- a/scheduler/pkg/scheduler/scheduler_test.go
+++ b/scheduler/pkg/scheduler/scheduler_test.go
@@ -12,6 +12,7 @@ package scheduler
 import (
 	"sort"
 	"testing"
+	"time"
 
 	. "github.com/onsi/gomega"
 	log "github.com/sirupsen/logrus"
@@ -20,6 +21,7 @@ import (
 	pb "github.com/seldonio/seldon-core/apis/go/v2/mlops/scheduler"
 
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/store"
+	"github.com/seldonio/seldon-core/scheduler/v2/pkg/synchroniser"
 )
 
 type mockStore struct {
@@ -498,7 +500,7 @@ func TestScheduler(t *testing.T) {
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
 			mockStore := newMockStore(test.model, test.servers)
-			scheduler := NewSimpleScheduler(logger, mockStore, DefaultSchedulerConfig(mockStore))
+			scheduler := NewSimpleScheduler(logger, mockStore, DefaultSchedulerConfig(mockStore), synchroniser.NewSimpleSynchroniser(time.Duration(10*time.Millisecond)))
 			err := scheduler.Schedule(test.model.Name)
 			if test.scheduled {
 				g.Expect(err).To(BeNil())
@@ -561,7 +563,7 @@ func TestFailedModels(t *testing.T) {
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
 			mockStore := newMockStore(test.models)
-			scheduler := NewSimpleScheduler(logger, mockStore, DefaultSchedulerConfig(mockStore))
+			scheduler := NewSimpleScheduler(logger, mockStore, DefaultSchedulerConfig(mockStore), synchroniser.NewSimpleSynchroniser(time.Duration(10*time.Millisecond)))
 			failedMoels, err := scheduler.getFailedModels()
 			g.Expect(err).To(BeNil())
 			sort.Strings(failedMoels)
diff --git a/scheduler/pkg/server/server_status_test.go b/scheduler/pkg/server/server_status_test.go
index 5fdf5f34ce..787b18e493 100644
--- a/scheduler/pkg/server/server_status_test.go
+++ b/scheduler/pkg/server/server_status_test.go
@@ -24,6 +24,7 @@ import (
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/store"
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/store/experiment"
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/store/pipeline"
+	"github.com/seldonio/seldon-core/scheduler/v2/pkg/synchroniser"
 )
 
 func TestModelsStatusStream(t *testing.T) {
@@ -431,8 +432,9 @@ func createTestScheduler() (*SchedulerServer, *coordinator.EventHub) {
 		logger,
 		schedulerStore,
 		scheduler2.DefaultSchedulerConfig(schedulerStore),
+		synchroniser.NewSimpleSynchroniser(time.Duration(10*time.Millisecond)),
 	)
-	s := NewSchedulerServer(logger, schedulerStore, experimentServer, pipelineServer, scheduler, eventHub)
+	s := NewSchedulerServer(logger, schedulerStore, experimentServer, pipelineServer, scheduler, eventHub, synchroniser.NewSimpleSynchroniser(time.Duration(10*time.Millisecond)))
 
 	return s, eventHub
 }
diff --git a/scheduler/pkg/server/server_test.go b/scheduler/pkg/server/server_test.go
index 4e1afd6a87..fec0dbf726 100644
--- a/scheduler/pkg/server/server_test.go
+++ b/scheduler/pkg/server/server_test.go
@@ -12,6 +12,7 @@ package server
 import (
 	"context"
 	"fmt"
+	"sort"
 	"testing"
 	"time"
 
@@ -29,6 +30,7 @@ import (
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/store"
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/store/experiment"
 	"github.com/seldonio/seldon-core/scheduler/v2/pkg/store/pipeline"
+	"github.com/seldonio/seldon-core/scheduler/v2/pkg/synchroniser"
 )
 
 func stringPtr(s string) *string {
@@ -56,13 +58,15 @@ func TestLoadModel(t *testing.T) {
 		schedulerStore := store.NewMemoryStore(logger, store.NewLocalSchedulerStore(), eventHub)
 		experimentServer := experiment.NewExperimentServer(logger, eventHub, nil, nil)
 		pipelineServer := pipeline.NewPipelineStore(logger, eventHub, schedulerStore)
-
+		sync := synchroniser.NewSimpleSynchroniser(time.Duration(10 * time.Millisecond))
 		scheduler := scheduler2.NewSimpleScheduler(
 			logger,
 			schedulerStore,
 			scheduler2.DefaultSchedulerConfig(schedulerStore),
+			sync,
 		)
-		s := NewSchedulerServer(logger, schedulerStore, experimentServer, pipelineServer, scheduler, eventHub)
+		s := NewSchedulerServer(logger, schedulerStore, experimentServer, pipelineServer, scheduler, eventHub, sync)
+		sync.Signals(1)
 		mockAgent := &mockAgentHandler{}
 
 		return s, mockAgent
@@ -334,10 +338,14 @@ func TestUnloadModel(t *testing.T) {
 		experimentServer := experiment.NewExperimentServer(logger, eventHub, nil, nil)
 		pipelineServer := pipeline.NewPipelineStore(logger, eventHub, schedulerStore)
 		mockAgent := &mockAgentHandler{}
+		sync := synchroniser.NewSimpleSynchroniser(time.Duration(10 * time.Millisecond))
 		scheduler := scheduler2.NewSimpleScheduler(logger,
 			schedulerStore,
-			scheduler2.DefaultSchedulerConfig(schedulerStore))
-		s := NewSchedulerServer(logger, schedulerStore, experimentServer, pipelineServer, scheduler, eventHub)
+			scheduler2.DefaultSchedulerConfig(schedulerStore),
+			sync,
+		)
+		s := NewSchedulerServer(logger, schedulerStore, experimentServer, pipelineServer, scheduler, eventHub, sync)
+		sync.Signals(1)
 		return s, mockAgent, eventHub
 	}
 
@@ -654,6 +662,112 @@ func TestPipelineStatus(t *testing.T) {
 	}
 }
 
+func TestServerNotify(t *testing.T) {
+	g := NewGomegaWithT(t)
+
+	createTestScheduler := func() (*SchedulerServer, synchroniser.Synchroniser) {
+		logger := log.New()
+		log.SetLevel(log.DebugLevel)
+		eventHub, err := coordinator.NewEventHub(logger)
+		g.Expect(err).To(BeNil())
+		schedulerStore := store.NewMemoryStore(logger, store.NewLocalSchedulerStore(), eventHub)
+		sync := synchroniser.NewSimpleSynchroniser(time.Duration(10 * time.Millisecond))
+		scheduler := scheduler2.NewSimpleScheduler(logger,
+			schedulerStore,
+			scheduler2.DefaultSchedulerConfig(schedulerStore),
+			sync,
+		)
+		s := NewSchedulerServer(logger, schedulerStore, nil, nil, scheduler, eventHub, sync)
+		return s, sync
+	}
+
+	type test struct {
+		name                 string
+		req                  *pb.ServerNotifyRequest
+		expectedServerStates []*store.ServerSnapshot
+		signalTriggered      bool
+	}
+	tests := []test{
+		{
+			name: "Initial sync",
+			req: &pb.ServerNotifyRequest{
+				Servers: []*pb.ServerNotify{
+					{
+						Name:             "server1",
+						ExpectedReplicas: 2,
+						Shared:           true,
+					},
+					{
+						Name:             "server2",
+						ExpectedReplicas: 3,
+						Shared:           true,
+					},
+				},
+				IsFirstSync: true,
+			},
+			expectedServerStates: []*store.ServerSnapshot{
+				{
+					Name:             "server1",
+					ExpectedReplicas: 2,
+					Shared:           true,
+					Replicas:         map[int]*store.ServerReplica{},
+				},
+				{
+					Name:             "server2",
+					ExpectedReplicas: 3,
+					Shared:           true,
+					Replicas:         map[int]*store.ServerReplica{},
+				},
+			},
+			signalTriggered: true,
+		},
+		{
+			// this should not trigger sync.Signal()
+			name: "normal sync",
+			req: &pb.ServerNotifyRequest{
+				Servers: []*pb.ServerNotify{
+					{
+						Name:             "server1",
+						ExpectedReplicas: 2,
+						Shared:           true,
+					},
+				},
+				IsFirstSync: false,
+			},
+			expectedServerStates: []*store.ServerSnapshot{
+				{
+					Name:             "server1",
+					ExpectedReplicas: 2,
+					Shared:           true,
+					Replicas:         map[int]*store.ServerReplica{},
+				},
+			},
+			signalTriggered: false,
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			s, sync := createTestScheduler()
+
+			_, _ = s.ServerNotify(context.Background(), test.req)
+
+			time.Sleep(50 * time.Millisecond) // allow events to be processed
+
+			actualServers, err := s.modelStore.GetServers(true, false)
+			g.Expect(err).To(BeNil())
+			sort.Slice(actualServers, func(i, j int) bool {
+				return actualServers[i].Name < actualServers[j].Name
+			})
+			sort.Slice(test.expectedServerStates, func(i, j int) bool {
+				return test.expectedServerStates[i].Name < test.expectedServerStates[j].Name
+			})
+			g.Expect(actualServers).To(Equal(test.expectedServerStates))
+
+			g.Expect(sync.IsReady()).To(Equal(test.signalTriggered))
+		})
+	}
+}
+
 type stubPipelineStatusServer struct {
 	msgs      chan *pb.PipelineStatusResponse
 	sleepTime time.Duration
diff --git a/scheduler/pkg/store/memory_test.go b/scheduler/pkg/store/memory_test.go
index baa3e47f1e..80c3f499ef 100644
--- a/scheduler/pkg/store/memory_test.go
+++ b/scheduler/pkg/store/memory_test.go
@@ -11,6 +11,7 @@ package store
 
 import (
 	"errors"
+	"sync/atomic"
 	"testing"
 	"time"
 
@@ -1389,6 +1390,159 @@ func TestAddModelVersionIfNotExists(t *testing.T) {
 	}
 }
 
+func TestAddServerReplica(t *testing.T) {
+	g := NewGomegaWithT(t)
+
+	type test struct {
+		name                 string
+		store                *LocalSchedulerStore
+		req                  *agent.AgentSubscribeRequest
+		expectedSnapshot     []*ServerSnapshot
+		expectedModelEvents  int64
+		expectedServerEvents int64
+	}
+
+	tests := []test{
+		{
+			name: "AddServerReplica - existing server",
+			store: &LocalSchedulerStore{
+				servers: map[string]*Server{
+					"server1": {
+						name: "server1",
+						replicas: map[int]*ServerReplica{
+							0: {},
+							1: {},
+						},
+						expectedReplicas: 3,
+						shared:           true,
+					},
+				},
+			},
+			req: &agent.AgentSubscribeRequest{
+				ServerName: "server1",
+				ReplicaIdx: 2,
+				Shared:     true,
+			},
+			expectedSnapshot: []*ServerSnapshot{
+				{
+					Name: "server1",
+					Replicas: map[int]*ServerReplica{
+						0: {},
+						1: {},
+						2: {},
+					},
+					ExpectedReplicas: 3,
+					Shared:           true,
+				},
+			},
+			expectedModelEvents:  0,
+			expectedServerEvents: 1,
+		},
+		{
+			name: "AddServerReplica - new server",
+			store: &LocalSchedulerStore{
+				servers: map[string]*Server{},
+			},
+			req: &agent.AgentSubscribeRequest{
+				ServerName: "server1",
+				ReplicaIdx: 0,
+				Shared:     true,
+			},
+			expectedSnapshot: []*ServerSnapshot{
+				{
+					Name: "server1",
+					Replicas: map[int]*ServerReplica{
+						0: {},
+					},
+					ExpectedReplicas: -1, // expected replicas is not set
+					Shared:           true,
+				},
+			},
+			expectedModelEvents:  0,
+			expectedServerEvents: 1,
+		},
+		{
+			name: "AddServerReplica - with loaded models",
+			store: &LocalSchedulerStore{
+				servers: map[string]*Server{},
+				models:  map[string]*Model{},
+			},
+			req: &agent.AgentSubscribeRequest{
+				ServerName: "server1",
+				ReplicaIdx: 0,
+				Shared:     true,
+				LoadedModels: []*agent.ModelVersion{
+					{
+						Model: &pb.Model{
+							Meta:      &pb.MetaData{Name: "model1"},
+							ModelSpec: &pb.ModelSpec{}},
+						Version: 1,
+					},
+					{
+						Model: &pb.Model{
+							Meta:      &pb.MetaData{Name: "model2"},
+							ModelSpec: &pb.ModelSpec{}},
+						Version: 1,
+					},
+				},
+			},
+			expectedSnapshot: []*ServerSnapshot{
+				{
+					Name: "server1",
+					Replicas: map[int]*ServerReplica{
+						0: {},
+					},
+					ExpectedReplicas: -1, // expected replicas is not set
+					Shared:           true,
+				},
+			},
+			expectedModelEvents:  2,
+			expectedServerEvents: 1,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			logger := log.New()
+			eventHub, err := coordinator.NewEventHub(logger)
+			g.Expect(err).To(BeNil())
+			ms := NewMemoryStore(logger, test.store, eventHub)
+
+			// register a callback to check if the event is triggered
+			serverEvents := int64(0)
+			eventHub.RegisterServerEventHandler(
+				"handler-server",
+				10,
+				logger,
+				func(event coordinator.ServerEventMsg) { atomic.AddInt64(&serverEvents, 1) },
+			)
+
+			modelEvents := int64(0)
+			eventHub.RegisterModelEventHandler(
+				"handler-model",
+				10,
+				logger,
+				func(event coordinator.ModelEventMsg) { atomic.AddInt64(&modelEvents, 1) },
+			)
+
+			err = ms.AddServerReplica(test.req)
+			g.Expect(err).To(BeNil())
+			actualSnapshot, err := ms.GetServers(true, false)
+			g.Expect(err).To(BeNil())
+			for idx, server := range actualSnapshot {
+				g.Expect(server.Name).To(Equal(test.expectedSnapshot[idx].Name))
+				g.Expect(server.Shared).To(Equal(test.expectedSnapshot[idx].Shared))
+				g.Expect(server.ExpectedReplicas).To(Equal(test.expectedSnapshot[idx].ExpectedReplicas))
+				g.Expect(len(server.Replicas)).To(Equal(len(test.expectedSnapshot[idx].Replicas)))
+			}
+
+			time.Sleep(10 * time.Millisecond)
+			g.Expect(atomic.LoadInt64(&serverEvents)).To(Equal(test.expectedServerEvents))
+			g.Expect(atomic.LoadInt64(&modelEvents)).To(Equal(test.expectedModelEvents))
+		})
+	}
+}
+
 func TestRemoveServerReplica(t *testing.T) {
 	g := NewGomegaWithT(t)
 
diff --git a/scheduler/pkg/synchroniser/servers_sync_test.go b/scheduler/pkg/synchroniser/servers_sync_test.go
new file mode 100644
index 0000000000..3a5b2ada4e
--- /dev/null
+++ b/scheduler/pkg/synchroniser/servers_sync_test.go
@@ -0,0 +1,174 @@
+/*
+Copyright (c) 2024 Seldon Technologies Ltd.
+
+Use of this software is governed by
+(1) the license included in the LICENSE file or
+(2) if the license included in the LICENSE file is the Business Source License 1.1,
+the Change License after the Change Date as each is defined in accordance with the LICENSE file.
+*/
+
+// TODO: explain synchroniser logic here
+package synchroniser
+
+import (
+	"sync"
+	"testing"
+	"time"
+
+	. "github.com/onsi/gomega"
+	log "github.com/sirupsen/logrus"
+
+	"github.com/seldonio/seldon-core/scheduler/v2/pkg/coordinator"
+)
+
+func TestServersSyncSynchroniser(t *testing.T) {
+	g := NewGomegaWithT(t)
+
+	type test struct {
+		name             string
+		timeout          time.Duration
+		signals          uint
+		initialSignals   uint
+		isTimeout        bool
+		isDuplicateEvent bool
+		context          coordinator.ServerEventUpdateContext
+	}
+
+	tests := []test{
+		{
+			name:           "Simple",
+			timeout:        200 * time.Millisecond,
+			signals:        5,
+			initialSignals: 0,
+			context:        coordinator.SERVER_REPLICA_CONNECTED,
+		},
+		{
+			name:           "Events before signals",
+			timeout:        200 * time.Millisecond,
+			signals:        5,
+			initialSignals: 5,
+			context:        coordinator.SERVER_REPLICA_CONNECTED,
+		},
+		{
+			name:           "All events before signals",
+			timeout:        200 * time.Millisecond,
+			signals:        0,
+			initialSignals: 5,
+			context:        coordinator.SERVER_REPLICA_CONNECTED,
+		},
+		{
+			name:           "All events before signals",
+			timeout:        200 * time.Millisecond,
+			signals:        0,
+			initialSignals: 5,
+			isTimeout:      true,
+			context:        coordinator.SERVER_REPLICA_CONNECTED,
+		},
+		{
+			name:           "No signals",
+			timeout:        200 * time.Millisecond,
+			signals:        0,
+			initialSignals: 0,
+			context:        coordinator.SERVER_REPLICA_CONNECTED,
+		},
+		{
+			name:             "Duplicate events",
+			timeout:          200 * time.Millisecond,
+			signals:          5,
+			initialSignals:   0,
+			isDuplicateEvent: true,
+			context:          coordinator.SERVER_REPLICA_CONNECTED,
+		},
+		{
+			name:           "wrong context",
+			timeout:        200 * time.Millisecond,
+			signals:        5,
+			initialSignals: 0,
+			context:        coordinator.SERVER_STATUS_UPDATE,
+		},
+		{
+			name:           "long timeout", // timeout will not be reached
+			timeout:        200 * time.Second,
+			signals:        5,
+			initialSignals: 0,
+			context:        coordinator.SERVER_REPLICA_CONNECTED,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			logger := log.New()
+			eventHub, err := coordinator.NewEventHub(logger)
+			g.Expect(err).To(BeNil())
+			s := NewServerBasedSynchroniser(eventHub, logger, test.timeout)
+
+			if !test.isTimeout {
+				for i := 0; i < int(test.initialSignals); i++ {
+					idx := uint32(i)
+					if test.isDuplicateEvent {
+						idx = 0
+					}
+					go eventHub.PublishServerEvent(
+						"test",
+						coordinator.ServerEventMsg{
+							ServerName:    "test",
+							ServerIdx:     idx,
+							UpdateContext: test.context,
+						},
+					)
+				}
+			}
+
+			s.Signals(test.signals + test.initialSignals)
+			// this should have no effect
+			s.Signals(10000)
+
+			if !test.isTimeout {
+				for i := 0; i < int(test.signals); i++ {
+					idx := uint32(i) + uint32(test.initialSignals)
+					if test.isDuplicateEvent {
+						idx = 0
+					}
+					go eventHub.PublishServerEvent(
+						"test",
+						coordinator.ServerEventMsg{
+							ServerName:    "test",
+							ServerIdx:     idx,
+							UpdateContext: test.context,
+						},
+					)
+				}
+			}
+
+			g.Expect(s.IsReady()).To(BeFalse())
+
+			time.Sleep(100 * time.Millisecond)
+
+			// simulate multiple events
+			numWaitReady := 10
+			waitReadyWg := sync.WaitGroup{}
+			waitReadyWg.Add(numWaitReady)
+			waitReadyFn := func() {
+				s.WaitReady()
+				waitReadyWg.Done()
+			}
+			for i := 0; i < numWaitReady; i++ {
+				go waitReadyFn()
+			}
+			waitReadyWg.Wait()
+			g.Expect(s.IsReady()).To(BeTrue())
+
+			if test.isTimeout || test.isDuplicateEvent || test.context != coordinator.SERVER_REPLICA_CONNECTED {
+				g.Expect(len(s.connectedServers)).Should(BeNumerically("<", test.signals+test.initialSignals))
+			} else {
+				g.Expect(len(s.connectedServers)).To(Equal(int(test.signals + test.initialSignals)))
+			}
+			// make sure we are graceful after this point
+
+			s.Signals(10)
+			g.Expect(s.IsReady()).To(BeTrue())
+			s.WaitReady()
+			g.Expect(s.IsReady()).To(BeTrue())
+		})
+	}
+}
diff --git a/scheduler/pkg/synchroniser/sync_test.go b/scheduler/pkg/synchroniser/sync_test.go
new file mode 100644
index 0000000000..af33585ee8
--- /dev/null
+++ b/scheduler/pkg/synchroniser/sync_test.go
@@ -0,0 +1,61 @@
+/*
+Copyright (c) 2024 Seldon Technologies Ltd.
+
+Use of this software is governed by
+(1) the license included in the LICENSE file or
+(2) if the license included in the LICENSE file is the Business Source License 1.1,
+the Change License after the Change Date as each is defined in accordance with the LICENSE file.
+*/
+
+// This package is responsible to synchronise starting up the different components of the "scheduler".
+// In particular, it is responsible for making sure that the time between the scheduler starts and while
+// the different model servers connect that the data plane (inferences) is not affected.
+package synchroniser
+
+import (
+	"testing"
+	"time"
+
+	. "github.com/onsi/gomega"
+)
+
+func TestSimpleSynchroniser(t *testing.T) {
+	g := NewGomegaWithT(t)
+
+	type test struct {
+		name    string
+		timeout time.Duration
+		signals uint
+	}
+
+	tests := []test{
+		{
+			name:    "Simple",
+			timeout: 100 * time.Millisecond,
+			signals: 1,
+		},
+		{
+			name:    "No timer",
+			timeout: 0 * time.Millisecond,
+			signals: 1,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			s := NewSimpleSynchroniser(test.timeout)
+			g.Expect(s.IsReady()).To(BeFalse())
+			s.Signals(test.signals)
+			// this should have no effect
+			s.Signals(100000)
+			s.WaitReady()
+			g.Expect(s.IsReady()).To(BeTrue())
+
+			// make sure we are graceful after this point
+			s.Signals(10)
+			g.Expect(s.IsReady()).To(BeTrue())
+			s.WaitReady()
+			g.Expect(s.IsReady()).To(BeTrue())
+		})
+	}
+}