github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/util/errorutil/tenant_deprecated_wrapper.go (about) 1 // Copyright 2020 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 errorutil 12 13 // TenantSQLDeprecatedWrapper is a helper to annotate uses of components that 14 // are in the progress of being phased out due to work towards multi-tenancy. 15 // It is usually usually used under a layer of abstraction that is aware of 16 // the wrapped object's type. 17 // 18 // Deprecated objects are broadly objects that reach deeply into the KV layer 19 // and which will be inaccessible from a SQL tenant server. Their uses in SQL 20 // fall into two categories: 21 // 22 // - functionality essential for multi-tenancy, i.e. a use which will 23 // have to be removed before we can start SQL tenant servers. 24 // - non-essential functionality, which will be disabled when run in 25 // a SQL tenant server. It may or may not be a long-term goal to remove 26 // this usage; this is determined on a case-by-case basis. 27 // 28 // As work towards multi-tenancy is taking place, semi-dedicated SQL tenant 29 // servers are supported. These are essentially SQL tenant servers that get 30 // to reach into the KV layer as needed while the first category above is 31 // being whittled down. 32 // 33 // This wrapper aids that process by offering two methods corresponding to 34 // the categories above: 35 // 36 // Deprecated() trades in a reference to Github issue (tracking the removal of 37 // an essential usage) for the wrapped object; OptionalErr() returns the wrapped 38 // object only if the wrapper was set up to allow this. 39 // 40 // Note that the wrapped object will in fact always have to be present as long 41 // as calls to Deprecated() exist. However, when running semi-dedicated SQL 42 // tenants, the wrapper should be set up with exposed=false so that it can 43 // pretend that the object is in fact not available. 44 // 45 // Finally, once all Deprecated() calls have been removed, it is possible to 46 // treat the wrapper as a pure option type, i.e. wrap a nil value with 47 // exposed=false. 48 type TenantSQLDeprecatedWrapper struct { 49 v interface{} 50 exposed bool 51 } 52 53 // MakeTenantSQLDeprecatedWrapper wraps an arbitrary object. When the 'exposed' 54 // parameter is set to true, Optional() will return the object. 55 func MakeTenantSQLDeprecatedWrapper(v interface{}, exposed bool) TenantSQLDeprecatedWrapper { 56 return TenantSQLDeprecatedWrapper{v: v, exposed: exposed} 57 } 58 59 // Optional returns the wrapped object if it is available (meaning that the 60 // wrapper was set up to make it available). This should be called by 61 // functionality that relies on the wrapped object but can be disabled when this 62 // is desired. 63 // 64 // Optional functionality should be used sparingly as it increases the 65 // maintenance and testing burden. It is preferable to use OptionalErr() 66 // (and return the error) where possible. 67 func (w TenantSQLDeprecatedWrapper) Optional() (interface{}, bool) { 68 if !w.exposed { 69 return nil, false 70 } 71 return w.v, true 72 } 73 74 // OptionalErr calls Optional and returns an error (referring to the optionally 75 // supplied Github issues) if the wrapped object is not available. 76 func (w TenantSQLDeprecatedWrapper) OptionalErr(issue int) (interface{}, error) { 77 v, ok := w.Optional() 78 if !ok { 79 return nil, UnsupportedUnderClusterVirtualization(issue) 80 } 81 return v, nil 82 }