github.com/mre-fog/trillianxx@v1.1.2-0.20180615153820-ae375a99d36a/util/election/stub/election.go (about) 1 // Copyright 2018 Google Inc. All Rights Reserved. 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 stub contains a MasterElection implementation for testing. 16 package stub 17 18 import ( 19 "context" 20 "sync" 21 "time" 22 23 "github.com/google/trillian/util" 24 "github.com/google/trillian/util/election" 25 ) 26 27 // Errors contains errors to be returned by each of MasterElection methods. 28 type Errors struct { 29 Start error 30 Wait error // WaitForMastership error. 31 IsMaster error 32 Resign error // ResignAndRestart error. 33 Close error 34 GetMaster error // GetCurrentMaster error. 35 } 36 37 // ErrAll creates Errors containing the same err associated with each method. 38 func ErrAll(err error) *Errors { 39 return &Errors{err, err, err, err, err, err} 40 } 41 42 // MasterElection implements election.MasterElection interface for testing. 43 type MasterElection struct { 44 isMaster bool 45 errs Errors 46 mu sync.RWMutex 47 } 48 49 // NewMasterElection returns a new initialized MasterElection for testing. 50 func NewMasterElection(isMaster bool, errs *Errors) *MasterElection { 51 me := &MasterElection{isMaster: isMaster} 52 if errs != nil { 53 me.errs = *errs 54 } 55 return me 56 } 57 58 // Update changes mastership status and errors returned by interface calls. 59 func (e *MasterElection) Update(isMaster bool, errs *Errors) { 60 e.mu.Lock() 61 defer e.mu.Unlock() 62 if errs == nil { 63 errs = &Errors{} 64 } 65 e.isMaster, e.errs = isMaster, *errs 66 } 67 68 // Start returns the stored error for this call. 69 func (e *MasterElection) Start(context.Context) error { 70 e.mu.RLock() 71 defer e.mu.RUnlock() 72 return e.errs.Start 73 } 74 75 // WaitForMastership blocks until this instance is master, or an error is 76 // supplied, or context is done. 77 func (e *MasterElection) WaitForMastership(ctx context.Context) error { 78 for { 79 is, err := func() (bool, error) { 80 e.mu.Lock() 81 defer e.mu.Unlock() 82 if ctx.Err() != nil { 83 return false, ctx.Err() 84 } 85 if e.errs.Wait != nil { 86 return false, e.errs.Wait 87 } 88 return e.isMaster, nil 89 }() 90 if is || err != nil { 91 return err 92 } 93 if err := util.SleepContext(ctx, 5*time.Millisecond); err != nil { 94 return err 95 } 96 } 97 } 98 99 // IsMaster returns the stored mastership status and error. 100 func (e *MasterElection) IsMaster(context.Context) (bool, error) { 101 e.mu.RLock() 102 defer e.mu.RUnlock() 103 return e.isMaster, e.errs.IsMaster 104 } 105 106 // Resign returns the stored error and resets mastership status if the error is 107 // nil. 108 func (e *MasterElection) Resign(context.Context) error { 109 e.mu.Lock() 110 defer e.mu.Unlock() 111 if e.errs.Resign == nil { 112 e.isMaster = false 113 } 114 return e.errs.Resign 115 } 116 117 // Close returns the stored error. 118 func (e *MasterElection) Close(context.Context) error { 119 e.mu.RLock() 120 defer e.mu.RUnlock() 121 return e.errs.Close 122 } 123 124 // GetCurrentMaster returns the current master which is *this* instance, or 125 // error if not currently the master. 126 func (e *MasterElection) GetCurrentMaster(context.Context) (string, error) { 127 e.mu.RLock() 128 defer e.mu.RUnlock() 129 if e.errs.GetMaster != nil { 130 return "", e.errs.GetMaster 131 } 132 if e.isMaster { 133 return "self", nil 134 } 135 return "", election.ErrNoMaster 136 }