github.com/matrixorigin/matrixone@v1.2.0/pkg/pb/lock/lock.go (about) 1 // Copyright 2023 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 lock 16 17 import ( 18 "bytes" 19 "context" 20 "encoding/hex" 21 "fmt" 22 23 "github.com/matrixorigin/matrixone/pkg/common/moerr" 24 ) 25 26 // SetID implement morpc Messgae 27 func (m *Request) SetID(id uint64) { 28 m.RequestID = id 29 } 30 31 // GetID implement morpc Messgae 32 func (m *Request) GetID() uint64 { 33 return m.RequestID 34 } 35 36 // DebugString returns the debug string 37 func (m *Request) DebugString() string { 38 var buffer bytes.Buffer 39 buffer.WriteString(fmt.Sprintf("%d: ", m.RequestID)) 40 buffer.WriteString(m.Method.String()) 41 buffer.WriteString("/") 42 if m.LockTable.Table > 0 { 43 buffer.WriteString(m.LockTable.DebugString()) 44 buffer.WriteString("/") 45 } 46 switch m.Method { 47 case Method_Lock: 48 buffer.WriteString(m.Lock.DebugString()) 49 case Method_Unlock: 50 buffer.WriteString(m.Unlock.DebugString()) 51 case Method_GetBind: 52 buffer.WriteString(m.GetBind.DebugString()) 53 case Method_GetTxnLock: 54 buffer.WriteString(m.GetTxnLock.DebugString()) 55 case Method_GetWaitingList: 56 buffer.WriteString(m.GetWaitingList.DebugString()) 57 case Method_KeepLockTableBind: 58 buffer.WriteString(m.KeepLockTableBind.DebugString()) 59 case Method_KeepRemoteLock: 60 buffer.WriteString(m.KeepRemoteLock.DebugString()) 61 } 62 return buffer.String() 63 } 64 65 // SetID implement morpc Messgae 66 func (m *Response) SetID(id uint64) { 67 m.RequestID = id 68 } 69 70 // GetID implement morpc Messgae 71 func (m *Response) GetID() uint64 { 72 return m.RequestID 73 } 74 75 // DebugString returns the debug string 76 func (m *Response) DebugString() string { 77 var buffer bytes.Buffer 78 buffer.WriteString(fmt.Sprintf("%d: ", m.RequestID)) 79 buffer.WriteString(m.Method.String()) 80 buffer.WriteString("/") 81 switch m.Method { 82 case Method_Lock: 83 buffer.WriteString(m.Lock.DebugString()) 84 case Method_Unlock: 85 buffer.WriteString(m.Unlock.DebugString()) 86 case Method_GetBind: 87 buffer.WriteString(m.GetBind.DebugString()) 88 case Method_GetTxnLock: 89 buffer.WriteString(m.GetTxnLock.DebugString()) 90 case Method_GetWaitingList: 91 buffer.WriteString(m.GetWaitingList.DebugString()) 92 case Method_KeepLockTableBind: 93 buffer.WriteString(m.KeepLockTableBind.DebugString()) 94 case Method_KeepRemoteLock: 95 buffer.WriteString(m.KeepRemoteLock.DebugString()) 96 } 97 return buffer.String() 98 } 99 100 // Changed returns true if LockTable bind changed 101 func (m LockTable) Changed(v LockTable) bool { 102 return m.Version != v.Version || 103 m.ServiceID != v.ServiceID 104 } 105 106 // Equal return true means same bind 107 func (m LockTable) Equal(v LockTable) bool { 108 return m.Table == v.Table && m.Version == v.Version 109 } 110 111 // DebugString returns the debug string 112 func (m LockTable) DebugString() string { 113 return fmt.Sprintf("%d-%s-%d", m.Table, m.ServiceID, m.Version) 114 } 115 116 // WithGranularity set rows granularity, the default granularity is Row. 117 func (m LockOptions) WithGranularity(granularity Granularity) LockOptions { 118 m.Granularity = granularity 119 return m 120 } 121 122 // WithMode set lock mode, the default mode is Exclusive. 123 func (m LockOptions) WithMode(mode LockMode) LockOptions { 124 m.Mode = mode 125 return m 126 } 127 128 // WithWaitPolicy set wait policy, the default policy is Wait. 129 func (m LockOptions) WithWaitPolicy(policy WaitPolicy) LockOptions { 130 m.Policy = policy 131 return m 132 } 133 134 // WrapError wrapper error to TxnError 135 func (m *Response) WrapError(err error) { 136 me := moerr.ConvertGoError(context.TODO(), err).(*moerr.Error) 137 data, e := me.MarshalBinary() 138 if e != nil { 139 panic(e) 140 } 141 m.Error = data 142 } 143 144 // UnwrapError unwrap the moerr from the error bytes 145 func (m Response) UnwrapError() error { 146 if len(m.Error) == 0 { 147 return nil 148 } 149 150 err := &moerr.Error{} 151 if e := err.UnmarshalBinary(m.Error); e != nil { 152 panic(e) 153 } 154 return err 155 } 156 157 // DebugString debug string 158 func (m LockOptions) DebugString() string { 159 return fmt.Sprintf("%s-%s-%s", 160 m.Mode.String(), 161 m.Granularity.String(), 162 m.Policy.String()) 163 } 164 165 func (m *LockRequest) DebugString() string { 166 return fmt.Sprintf("%s-%s-%s-%s", 167 hex.EncodeToString(m.TxnID), 168 m.ServiceID, 169 bytesArrayString(m.Rows), 170 m.Options.DebugString()) 171 } 172 173 func (m *LockResponse) DebugString() string { 174 return "" 175 } 176 177 func (m *UnlockRequest) DebugString() string { 178 return hex.EncodeToString(m.TxnID) 179 } 180 181 func (m *UnlockResponse) DebugString() string { 182 return "" 183 } 184 185 func (m *GetBindRequest) DebugString() string { 186 return fmt.Sprintf("%s-%d", m.ServiceID, m.Table) 187 } 188 189 func (m *GetBindResponse) DebugString() string { 190 return m.LockTable.DebugString() 191 } 192 193 func (m *GetTxnLockRequest) DebugString() string { 194 return fmt.Sprintf("%s-%s", 195 hex.EncodeToString(m.TxnID), 196 hex.EncodeToString(m.Row)) 197 } 198 199 func (m *GetTxnLockResponse) DebugString() string { 200 return fmt.Sprintf("%d-%s", 201 m.Value, 202 waitTxnArrayString(m.WaitingList)) 203 } 204 205 func (m *GetWaitingListRequest) DebugString() string { 206 return m.Txn.DebugString() 207 } 208 209 func (m *GetWaitingListResponse) DebugString() string { 210 return waitTxnArrayString(m.WaitingList) 211 } 212 213 func (m *KeepLockTableBindRequest) DebugString() string { 214 return m.ServiceID 215 } 216 217 func (m *KeepLockTableBindResponse) DebugString() string { 218 if m.OK { 219 return "true" 220 } 221 return "false" 222 } 223 224 func (m *KeepRemoteLockRequest) DebugString() string { 225 return m.ServiceID 226 } 227 228 func (m *KeepRemoteLockResponse) DebugString() string { 229 if m.OK { 230 return "true" 231 } 232 return "false" 233 } 234 235 func bytesArrayString(values [][]byte) string { 236 var buffer bytes.Buffer 237 for idx, v := range values { 238 buffer.WriteString(hex.EncodeToString(v)) 239 if idx != len(values)-1 { 240 buffer.WriteString(",") 241 } 242 } 243 return buffer.String() 244 } 245 246 func waitTxnArrayString(values []WaitTxn) string { 247 var buffer bytes.Buffer 248 for idx, v := range values { 249 buffer.WriteString(v.String()) 250 if idx != len(values)-1 { 251 buffer.WriteString(",") 252 } 253 } 254 return buffer.String() 255 } 256 257 func (m *WaitTxn) DebugString() string { 258 return fmt.Sprintf("%s(%s)", 259 hex.EncodeToString(m.TxnID), 260 m.CreatedOn) 261 } 262 263 func (m Request) TypeName() string { 264 return "lockservice.request" 265 } 266 267 func (m Response) TypeName() string { 268 return "lockservice.response" 269 } 270 271 func (m LockOptions) Validate(rows [][]byte) { 272 if m.Sharding == Sharding_None { 273 return 274 } 275 276 if m.Granularity != Granularity_Row { 277 panic("cannot lock with sharding without row granularity") 278 } 279 280 if len(rows) != 1 { 281 panic("cannot lock with sharding without single row") 282 } 283 }