github.com/matrixorigin/matrixone@v1.2.0/pkg/tests/service/dnservice.go (about) 1 // Copyright 2021 - 2022 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package service 16 17 import ( 18 "context" 19 "fmt" 20 "path/filepath" 21 "sync" 22 "time" 23 24 "github.com/google/uuid" 25 26 "github.com/matrixorigin/matrixone/pkg/common/moerr" 27 "github.com/matrixorigin/matrixone/pkg/common/morpc" 28 "github.com/matrixorigin/matrixone/pkg/common/runtime" 29 "github.com/matrixorigin/matrixone/pkg/fileservice" 30 "github.com/matrixorigin/matrixone/pkg/logservice" 31 "github.com/matrixorigin/matrixone/pkg/pb/metadata" 32 "github.com/matrixorigin/matrixone/pkg/taskservice" 33 "github.com/matrixorigin/matrixone/pkg/tnservice" 34 "github.com/matrixorigin/matrixone/pkg/util/toml" 35 ) 36 37 // TNService describes expected behavior for tn service. 38 type TNService interface { 39 // Start sends heartbeat and start to handle command. 40 Start() error 41 // Close stops store 42 Close() error 43 // Status returns the status of service. 44 Status() ServiceStatus 45 46 // ID returns uuid of store 47 ID() string 48 49 // StartTNReplica start the TNShard replica 50 StartTNReplica(shard metadata.TNShard) error 51 // CloseTNReplica close the TNShard replica. 52 CloseTNReplica(shard metadata.TNShard) error 53 54 // GetTaskService returns the taskservice 55 GetTaskService() (taskservice.TaskService, bool) 56 } 57 58 // tnService wraps tnservice.Service. 59 // 60 // The main purpose of this structure is to maintain status. 61 type tnService struct { 62 sync.Mutex 63 status ServiceStatus 64 uuid string 65 svc tnservice.Service 66 } 67 68 func (ds *tnService) Start() error { 69 ds.Lock() 70 defer ds.Unlock() 71 72 if ds.status == ServiceInitialized { 73 err := ds.svc.Start() 74 if err != nil { 75 return err 76 } 77 ds.status = ServiceStarted 78 } 79 80 return nil 81 } 82 83 func (ds *tnService) Close() error { 84 ds.Lock() 85 defer ds.Unlock() 86 87 if ds.status == ServiceStarted { 88 err := ds.svc.Close() 89 if err != nil { 90 return err 91 } 92 ds.status = ServiceClosed 93 } 94 95 return nil 96 } 97 98 func (ds *tnService) Status() ServiceStatus { 99 ds.Lock() 100 defer ds.Unlock() 101 return ds.status 102 } 103 104 func (ds *tnService) ID() string { 105 ds.Lock() 106 defer ds.Unlock() 107 return ds.uuid 108 } 109 110 func (ds *tnService) StartTNReplica(shard metadata.TNShard) error { 111 ds.Lock() 112 defer ds.Unlock() 113 114 if ds.status != ServiceStarted { 115 return moerr.NewNoServiceNoCtx(ds.uuid) 116 } 117 118 return ds.svc.StartTNReplica(shard) 119 } 120 121 func (ds *tnService) CloseTNReplica(shard metadata.TNShard) error { 122 ds.Lock() 123 defer ds.Unlock() 124 125 if ds.status != ServiceStarted { 126 return moerr.NewNoServiceNoCtx(ds.uuid) 127 } 128 129 return ds.svc.CloseTNReplica(shard) 130 } 131 132 func (ds *tnService) GetTaskService() (taskservice.TaskService, bool) { 133 return ds.svc.GetTaskService() 134 } 135 136 // tnOptions is options for a tn service. 137 type tnOptions []tnservice.Option 138 139 // newTNService initializes an instance of `TNService`. 140 func newTNService( 141 cfg *tnservice.Config, 142 rt runtime.Runtime, 143 fs fileservice.FileService, 144 opts tnOptions, 145 ) (TNService, error) { 146 svc, err := tnservice.NewService(cfg, rt, fs, nil, opts...) 147 if err != nil { 148 return nil, err 149 } 150 return &tnService{ 151 status: ServiceInitialized, 152 uuid: cfg.UUID, 153 svc: svc, 154 }, nil 155 } 156 157 // buildTNConfig builds configuration for a tn service. 158 func buildTNConfig( 159 index int, opt Options, address *serviceAddresses, 160 ) *tnservice.Config { 161 uid, _ := uuid.NewV7() 162 cfg := &tnservice.Config{ 163 UUID: uid.String(), 164 ListenAddress: address.getTnListenAddress(index), 165 } 166 cfg.ServiceAddress = cfg.ListenAddress 167 cfg.LogtailServer.ListenAddress = address.getTnLogtailAddress(index) 168 cfg.LogtailServer.ServiceAddress = cfg.LogtailServer.ListenAddress 169 cfg.LockService.ListenAddress = address.getTNLockListenAddress(index) 170 cfg.LockService.ServiceAddress = cfg.LockService.ListenAddress 171 cfg.LockService.KeepBindTimeout.Duration = time.Second * 30 172 cfg.DataDir = filepath.Join(opt.rootDataDir, cfg.UUID) 173 cfg.HAKeeper.ClientConfig.ServiceAddresses = address.listHAKeeperListenAddresses() 174 cfg.HAKeeper.HeatbeatInterval.Duration = opt.heartbeat.tn 175 cfg.Txn.Storage.Backend = opt.storage.tnStorage 176 177 // FIXME: disable tae flush 178 cfg.Ckp.MinCount = 2000000 179 cfg.Ckp.FlushInterval.Duration = time.Second * 100000 180 cfg.Ckp.ScanInterval.Duration = time.Second * 100000 181 cfg.Ckp.IncrementalInterval.Duration = time.Second * 100000 182 cfg.Ckp.GlobalMinCount = 10000 183 184 // logtail push service config for tae storage 185 cfg.LogtailServer.RpcMaxMessageSize = toml.ByteSize(opt.logtailPushServer.rpcMaxMessageSize) 186 cfg.LogtailServer.LogtailCollectInterval.Duration = opt.logtailPushServer.logtailCollectInterval 187 cfg.LogtailServer.LogtailRPCStreamPoisonTime.Duration = opt.logtailPushServer.logtailRPCStreamPoisonTIme 188 cfg.LogtailServer.LogtailResponseSendTimeout.Duration = opt.logtailPushServer.logtailResponseSendTimeout 189 190 // We need the filled version of configuration. 191 // It's necessary when building tnservice.Option. 192 if err := cfg.Validate(); err != nil { 193 panic(fmt.Sprintf("fatal when building tnservice.Config: %s", err)) 194 } 195 196 return cfg 197 } 198 199 // buildTNOptions builds options for a tn service. 200 // 201 // NB: We need the filled version of tnservice.Config. 202 func buildTNOptions(cfg *tnservice.Config, filter FilterFunc) tnOptions { 203 // factory to construct client for hakeeper 204 hakeeperClientFactory := func() (logservice.TNHAKeeperClient, error) { 205 ctx, cancel := context.WithTimeout( 206 context.Background(), cfg.HAKeeper.DiscoveryTimeout.Duration, 207 ) 208 defer cancel() 209 210 // transfer morpc.BackendOption via context 211 ctx = logservice.SetBackendOptions(ctx, morpc.WithBackendFilter(filter)) 212 213 client, err := logservice.NewTNHAKeeperClient( 214 ctx, cfg.HAKeeper.ClientConfig, 215 ) 216 if err != nil { 217 return nil, err 218 } 219 return client, nil 220 } 221 222 // factory to construct client for log service 223 logServiceClientFactory := func(shard metadata.TNShard) (logservice.Client, error) { 224 ctx, cancel := context.WithTimeout( 225 context.Background(), cfg.LogService.ConnectTimeout.Duration, 226 ) 227 defer cancel() 228 229 // transfer morpc.BackendOption via context 230 ctx = logservice.SetBackendOptions(ctx, morpc.WithBackendFilter(filter)) 231 232 return logservice.NewClient(ctx, logservice.ClientConfig{ 233 Tag: "Test-TN", 234 ReadOnly: false, 235 LogShardID: shard.LogShardID, 236 TNReplicaID: shard.ReplicaID, 237 ServiceAddresses: cfg.HAKeeper.ClientConfig.ServiceAddresses, 238 }) 239 } 240 241 return []tnservice.Option{ 242 tnservice.WithHAKeeperClientFactory(hakeeperClientFactory), 243 tnservice.WithLogServiceClientFactory(logServiceClientFactory), 244 tnservice.WithBackendFilter(filter), 245 } 246 }