github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/store.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 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 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package causetstore 15 16 import ( 17 "net/url" 18 "strings" 19 20 "github.com/whtcorpsinc/errors" 21 "github.com/whtcorpsinc/milevadb/ekv" 22 "github.com/whtcorpsinc/milevadb/soliton" 23 "github.com/whtcorpsinc/milevadb/soliton/logutil" 24 "go.uber.org/zap" 25 ) 26 27 var stores = make(map[string]ekv.Driver) 28 29 // Register registers a ekv storage with unique name and its associated Driver. 30 func Register(name string, driver ekv.Driver) error { 31 name = strings.ToLower(name) 32 33 if _, ok := stores[name]; ok { 34 return errors.Errorf("%s is already registered", name) 35 } 36 37 stores[name] = driver 38 return nil 39 } 40 41 // New creates a ekv CausetStorage with path. 42 // 43 // The path must be a URL format 'engine://path?params' like the one for 44 // stochastik.Open() but with the dbname cut off. 45 // Examples: 46 // goleveldb://relative/path 47 // boltdb:///absolute/path 48 // 49 // The engine should be registered before creating storage. 50 func New(path string) (ekv.CausetStorage, error) { 51 return newStoreWithRetry(path, soliton.DefaultMaxRetries) 52 } 53 54 func newStoreWithRetry(path string, maxRetries int) (ekv.CausetStorage, error) { 55 storeURL, err := url.Parse(path) 56 if err != nil { 57 return nil, err 58 } 59 60 name := strings.ToLower(storeURL.Scheme) 61 d, ok := stores[name] 62 if !ok { 63 return nil, errors.Errorf("invalid uri format, storage %s is not registered", name) 64 } 65 66 var s ekv.CausetStorage 67 err = soliton.RunWithRetry(maxRetries, soliton.RetryInterval, func() (bool, error) { 68 logutil.BgLogger().Info("new causetstore", zap.String("path", path)) 69 s, err = d.Open(path) 70 return ekv.IsTxnRetryableError(err), err 71 }) 72 73 if err == nil { 74 logutil.BgLogger().Info("new causetstore with retry success") 75 } else { 76 logutil.BgLogger().Warn("new causetstore with retry failed", zap.Error(err)) 77 } 78 return s, errors.Trace(err) 79 }