github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/pkg/election/config.go (about) 1 // Copyright 2022 PingCAP, 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 election 15 16 import ( 17 "context" 18 "time" 19 20 "github.com/pingcap/tiflow/pkg/errors" 21 ) 22 23 const ( 24 defaultLeaseDuration = time.Second * 10 25 defaultRenewInterval = time.Second * 2 26 defaultRenewDeadline = defaultLeaseDuration - defaultRenewInterval 27 defaultReleaseTimeout = 5 * time.Second 28 defaultResignTimeout = 5 * time.Second 29 ) 30 31 // Config is the configuration for the leader election. 32 type Config struct { 33 // ID is id of the current member. 34 // It is used to distinguish different members. 35 // It must be unique among all members. 36 ID string 37 // Name is the human-readable name of the current member. 38 // It is used for logging and diagnostics. 39 Name string 40 // Address is the address of the current member. 41 Address string 42 // Storage is the storage to store the election record. 43 Storage Storage 44 // LeaderCallback is the callback function when the current member becomes leader. 45 // If current member loses the leadership, the ctx will be canceled. Callback should 46 // return as soon as possible when the ctx is canceled. 47 LeaderCallback func(ctx context.Context) error 48 // LeaseDuration is the duration that a client will wait before 49 // it can remove this member when the client hasn't observed any 50 // renewals from the member. 51 // 52 // A client will wait a full LeaseDuration without observing any 53 // renewals from the member before it can remove the member. 54 // When all clients are shutdown and a new set of clients are started 55 // with different id against the same storage, they must wait a full 56 // LeaseDuration before they can acquire a leadership. So the LeaseDuration 57 // should be set as short as possible to avoid the long waits in this case. 58 // 59 // It defaults to 10 seconds if not set. 60 LeaseDuration time.Duration 61 // RenewInterval is the interval that the current member tries to 62 // refresh the election record and renew the lease. 63 // 64 // It defaults to 2 seconds if not set. 65 RenewInterval time.Duration 66 // RenewDeadline is the duration that the current member waits before 67 // it gives up on the leadership when it can't renew the lease. To avoid 68 // two members from both acting as leader at the same time, RenewDeadline 69 // should be set shorter than LeaseDuration - RenewInterval. 70 // 71 // It defaults to 8 seconds if not set. 72 RenewDeadline time.Duration 73 // ExitOnRenewFail indicates whether the current member should exit when 74 // failing to renew the lease. 75 ExitOnRenewFail bool 76 } 77 78 // AdjustAndValidate adjusts the config and validates it. 79 func (c *Config) AdjustAndValidate() error { 80 if c.LeaseDuration == 0 { 81 c.LeaseDuration = defaultLeaseDuration 82 } 83 if c.RenewInterval == 0 { 84 c.RenewInterval = defaultRenewInterval 85 } 86 if c.RenewDeadline == 0 { 87 c.RenewDeadline = defaultRenewDeadline 88 } 89 if c.ID == "" { 90 return errors.Errorf("id must not be empty") 91 } 92 if c.Storage == nil { 93 return errors.Errorf("storage must not be nil") 94 } 95 if c.LeaderCallback == nil { 96 return errors.Errorf("LeaderCallback must not be nil") 97 } 98 if c.RenewInterval > c.LeaseDuration { 99 return errors.Errorf("RenewInterval must not be greater than LeaseDuration") 100 } 101 if c.RenewDeadline > c.LeaseDuration-c.RenewInterval { 102 return errors.Errorf("RenewDeadline must not be greater than LeaseDuration - RenewInterval") 103 } 104 return nil 105 }