github.com/matrixorigin/matrixone@v0.7.0/pkg/common/runtime/runtime.go (about) 1 // Copyright 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 runtime 16 17 import ( 18 "sync" 19 "sync/atomic" 20 "time" 21 22 "github.com/matrixorigin/matrixone/pkg/common/log" 23 "github.com/matrixorigin/matrixone/pkg/logutil" 24 "github.com/matrixorigin/matrixone/pkg/pb/metadata" 25 "github.com/matrixorigin/matrixone/pkg/txn/clock" 26 "go.uber.org/zap" 27 ) 28 29 var ( 30 processLevel atomic.Value 31 ) 32 33 type LoggerName int 34 35 const ( 36 Default LoggerName = iota 37 SystemInit 38 ) 39 40 // ProcessLevelRuntime returns a process-lelve runtime 41 func ProcessLevelRuntime() Runtime { 42 v := processLevel.Load() 43 if v == nil { 44 return nil 45 } 46 return v.(Runtime) 47 } 48 49 // SetupProcessLevelRuntime set a process-level runtime. If the service does not 50 // support a service-level runtime when running in launch mode, it will use the 51 // process-level runtime. The process-level runtime must setup in main. 52 func SetupProcessLevelRuntime(r Runtime) { 53 processLevel.Store(r) 54 } 55 56 // WithClock setup clock for a runtime, CN and DN must contain an instance of the 57 // Clock that is used to provide the timestamp service to the transaction. 58 func WithClock(clock clock.Clock) Option { 59 return func(r *runtime) { 60 r.global.clock = clock 61 } 62 } 63 64 // NewRuntime create a mo runtime environment. 65 func NewRuntime(service metadata.ServiceType, uuid string, logger *zap.Logger, opts ...Option) Runtime { 66 rt := &runtime{ 67 serviceType: service, 68 serviceUUID: uuid, 69 } 70 for _, opt := range opts { 71 opt(rt) 72 } 73 rt.global.logger = log.GetServiceLogger(logutil.Adjust(logger), service, uuid) 74 rt.initSystemInitLogger() 75 return rt 76 } 77 78 type runtime struct { 79 serviceType metadata.ServiceType 80 serviceUUID string 81 82 global struct { 83 clock clock.Clock 84 logger *log.MOLogger 85 variables sync.Map 86 87 systemInitLogger *log.MOLogger 88 } 89 } 90 91 func (r *runtime) Logger() *log.MOLogger { 92 return r.global.logger 93 } 94 95 func (r *runtime) SubLogger(name LoggerName) *log.MOLogger { 96 switch name { 97 case SystemInit: 98 return r.global.systemInitLogger 99 default: 100 return r.Logger() 101 } 102 } 103 104 func (r *runtime) Clock() clock.Clock { 105 return r.global.clock 106 } 107 108 func (r *runtime) ServiceType() metadata.ServiceType { 109 return r.serviceType 110 } 111 112 func (r *runtime) ServiceUUID() string { 113 return r.serviceUUID 114 } 115 116 func (r *runtime) SetGlobalVariables(name string, value any) { 117 r.global.variables.Store(name, value) 118 } 119 120 func (r *runtime) GetGlobalVariables(name string) (any, bool) { 121 return r.global.variables.Load(name) 122 } 123 124 // DefaultRuntime used to test 125 func DefaultRuntime() Runtime { 126 return NewRuntime( 127 metadata.ServiceType_CN, 128 "", 129 logutil.GetPanicLoggerWithLevel(zap.DebugLevel), 130 WithClock(clock.NewHLCClock(func() int64 { 131 return time.Now().UTC().UnixNano() 132 }, 0))) 133 } 134 135 func (r *runtime) initSystemInitLogger() { 136 if r.global.logger == nil { 137 r.global.logger = log.GetServiceLogger(logutil.Adjust(nil), r.serviceType, r.serviceUUID) 138 } 139 r.global.systemInitLogger = r.Logger().WithProcess(log.SystemInit) 140 }