github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/kv/kvserver/batcheval/eval_context.go (about) 1 // Copyright 2017 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package batcheval 12 13 import ( 14 "context" 15 "fmt" 16 17 "github.com/cockroachdb/cockroach/pkg/kv" 18 "github.com/cockroachdb/cockroach/pkg/kv/kvserver/abortspan" 19 "github.com/cockroachdb/cockroach/pkg/kv/kvserver/concurrency" 20 "github.com/cockroachdb/cockroach/pkg/kv/kvserver/kvserverbase" 21 "github.com/cockroachdb/cockroach/pkg/roachpb" 22 "github.com/cockroachdb/cockroach/pkg/settings/cluster" 23 "github.com/cockroachdb/cockroach/pkg/storage" 24 "github.com/cockroachdb/cockroach/pkg/storage/cloud" 25 "github.com/cockroachdb/cockroach/pkg/storage/enginepb" 26 "github.com/cockroachdb/cockroach/pkg/util/hlc" 27 "github.com/cockroachdb/cockroach/pkg/util/limit" 28 "github.com/cockroachdb/cockroach/pkg/util/uuid" 29 "golang.org/x/time/rate" 30 ) 31 32 // Limiters is the collection of per-store limits used during cmd evaluation. 33 type Limiters struct { 34 BulkIOWriteRate *rate.Limiter 35 ConcurrentImportRequests limit.ConcurrentRequestLimiter 36 ConcurrentExportRequests limit.ConcurrentRequestLimiter 37 ConcurrentAddSSTableRequests limit.ConcurrentRequestLimiter 38 // concurrentRangefeedIters is a semaphore used to limit the number of 39 // rangefeeds in the "catch-up" state across the store. The "catch-up" state 40 // is a temporary state at the beginning of a rangefeed which is expensive 41 // because it uses an engine iterator. 42 ConcurrentRangefeedIters limit.ConcurrentRequestLimiter 43 } 44 45 // EvalContext is the interface through which command evaluation accesses the 46 // underlying state. 47 type EvalContext interface { 48 fmt.Stringer 49 ClusterSettings() *cluster.Settings 50 EvalKnobs() kvserverbase.BatchEvalTestingKnobs 51 52 Engine() storage.Engine 53 Clock() *hlc.Clock 54 DB() *kv.DB 55 AbortSpan() *abortspan.AbortSpan 56 GetConcurrencyManager() concurrency.Manager 57 GetLimiters() *Limiters 58 59 NodeID() roachpb.NodeID 60 StoreID() roachpb.StoreID 61 GetRangeID() roachpb.RangeID 62 GetNodeLocality() roachpb.Locality 63 64 IsFirstRange() bool 65 GetFirstIndex() (uint64, error) 66 GetTerm(uint64) (uint64, error) 67 GetLeaseAppliedIndex() uint64 68 69 Desc() *roachpb.RangeDescriptor 70 ContainsKey(key roachpb.Key) bool 71 72 // CanCreateTxnRecord determines whether a transaction record can be created 73 // for the provided transaction information. See Replica.CanCreateTxnRecord 74 // for details about its arguments, return values, and preconditions. 75 CanCreateTxnRecord( 76 txnID uuid.UUID, txnKey []byte, txnMinTS hlc.Timestamp, 77 ) (ok bool, minCommitTS hlc.Timestamp, reason roachpb.TransactionAbortedReason) 78 79 // GetMVCCStats returns a snapshot of the MVCC stats for the range. 80 // If called from a command that declares a read/write span on the 81 // entire range, the stats will be consistent with the data that is 82 // visible to the batch. Otherwise, it may return inconsistent 83 // results due to concurrent writes. 84 GetMVCCStats() enginepb.MVCCStats 85 86 // GetSplitQPS returns the queries/s request rate for this range. 87 // 88 // NOTE: This should not be used when the load based splitting cluster 89 // setting is disabled. 90 GetSplitQPS() float64 91 92 GetGCThreshold() hlc.Timestamp 93 GetLastReplicaGCTimestamp(context.Context) (hlc.Timestamp, error) 94 GetLease() (roachpb.Lease, roachpb.Lease) 95 96 GetExternalStorage(ctx context.Context, dest roachpb.ExternalStorage) (cloud.ExternalStorage, error) 97 GetExternalStorageFromURI(ctx context.Context, uri string) (cloud.ExternalStorage, error) 98 } 99 100 // MockEvalCtx is a dummy implementation of EvalContext for testing purposes. 101 // For technical reasons, the interface is implemented by a wrapper .EvalContext(). 102 type MockEvalCtx struct { 103 ClusterSettings *cluster.Settings 104 Desc *roachpb.RangeDescriptor 105 StoreID roachpb.StoreID 106 Clock *hlc.Clock 107 Stats enginepb.MVCCStats 108 QPS float64 109 AbortSpan *abortspan.AbortSpan 110 GCThreshold hlc.Timestamp 111 Term, FirstIndex uint64 112 CanCreateTxn func() (bool, hlc.Timestamp, roachpb.TransactionAbortedReason) 113 Lease roachpb.Lease 114 } 115 116 // EvalContext returns the MockEvalCtx as an EvalContext. It will reflect future 117 // modifications to the underlying MockEvalContext. 118 func (m *MockEvalCtx) EvalContext() EvalContext { 119 return &mockEvalCtxImpl{m} 120 } 121 122 type mockEvalCtxImpl struct { 123 // Hide the fields of MockEvalCtx which have names that conflict with some 124 // of the interface methods. 125 *MockEvalCtx 126 } 127 128 func (m *mockEvalCtxImpl) String() string { 129 return "mock" 130 } 131 func (m *mockEvalCtxImpl) ClusterSettings() *cluster.Settings { 132 return m.MockEvalCtx.ClusterSettings 133 } 134 func (m *mockEvalCtxImpl) EvalKnobs() kvserverbase.BatchEvalTestingKnobs { 135 return kvserverbase.BatchEvalTestingKnobs{} 136 } 137 func (m *mockEvalCtxImpl) Engine() storage.Engine { 138 panic("unimplemented") 139 } 140 func (m *mockEvalCtxImpl) Clock() *hlc.Clock { 141 return m.MockEvalCtx.Clock 142 } 143 func (m *mockEvalCtxImpl) DB() *kv.DB { 144 panic("unimplemented") 145 } 146 func (m *mockEvalCtxImpl) GetLimiters() *Limiters { 147 panic("unimplemented") 148 } 149 func (m *mockEvalCtxImpl) AbortSpan() *abortspan.AbortSpan { 150 return m.MockEvalCtx.AbortSpan 151 } 152 func (m *mockEvalCtxImpl) GetConcurrencyManager() concurrency.Manager { 153 panic("unimplemented") 154 } 155 func (m *mockEvalCtxImpl) NodeID() roachpb.NodeID { 156 panic("unimplemented") 157 } 158 func (m *mockEvalCtxImpl) GetNodeLocality() roachpb.Locality { 159 panic("unimplemented") 160 } 161 func (m *mockEvalCtxImpl) StoreID() roachpb.StoreID { 162 return m.MockEvalCtx.StoreID 163 } 164 func (m *mockEvalCtxImpl) GetRangeID() roachpb.RangeID { 165 return m.MockEvalCtx.Desc.RangeID 166 } 167 func (m *mockEvalCtxImpl) IsFirstRange() bool { 168 panic("unimplemented") 169 } 170 func (m *mockEvalCtxImpl) GetFirstIndex() (uint64, error) { 171 return m.FirstIndex, nil 172 } 173 func (m *mockEvalCtxImpl) GetTerm(uint64) (uint64, error) { 174 return m.Term, nil 175 } 176 func (m *mockEvalCtxImpl) GetLeaseAppliedIndex() uint64 { 177 panic("unimplemented") 178 } 179 func (m *mockEvalCtxImpl) Desc() *roachpb.RangeDescriptor { 180 return m.MockEvalCtx.Desc 181 } 182 func (m *mockEvalCtxImpl) ContainsKey(key roachpb.Key) bool { 183 return false 184 } 185 func (m *mockEvalCtxImpl) GetMVCCStats() enginepb.MVCCStats { 186 return m.Stats 187 } 188 func (m *mockEvalCtxImpl) GetSplitQPS() float64 { 189 return m.QPS 190 } 191 func (m *mockEvalCtxImpl) CanCreateTxnRecord( 192 uuid.UUID, []byte, hlc.Timestamp, 193 ) (bool, hlc.Timestamp, roachpb.TransactionAbortedReason) { 194 return m.CanCreateTxn() 195 } 196 func (m *mockEvalCtxImpl) GetGCThreshold() hlc.Timestamp { 197 return m.GCThreshold 198 } 199 func (m *mockEvalCtxImpl) GetLastReplicaGCTimestamp(context.Context) (hlc.Timestamp, error) { 200 panic("unimplemented") 201 } 202 func (m *mockEvalCtxImpl) GetLease() (roachpb.Lease, roachpb.Lease) { 203 return m.Lease, roachpb.Lease{} 204 } 205 206 func (m *mockEvalCtxImpl) GetExternalStorage( 207 ctx context.Context, dest roachpb.ExternalStorage, 208 ) (cloud.ExternalStorage, error) { 209 panic("unimplemented") 210 } 211 212 func (m *mockEvalCtxImpl) GetExternalStorageFromURI( 213 ctx context.Context, uri string, 214 ) (cloud.ExternalStorage, error) { 215 panic("unimplemented") 216 }