mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
Merge pull request #19356 from mikedanese/le-2
Auto commit by PR queue bot
This commit is contained in:
commit
a47c170377
@ -121,12 +121,15 @@ type LeaderElectionConfig struct {
|
|||||||
//
|
//
|
||||||
// possible future callbacks:
|
// possible future callbacks:
|
||||||
// * OnChallenge()
|
// * OnChallenge()
|
||||||
// * OnNewLeader()
|
|
||||||
type LeaderCallbacks struct {
|
type LeaderCallbacks struct {
|
||||||
// OnStartedLeading is called when a LeaderElector client starts leading
|
// OnStartedLeading is called when a LeaderElector client starts leading
|
||||||
OnStartedLeading func(stop <-chan struct{})
|
OnStartedLeading func(stop <-chan struct{})
|
||||||
// OnStoppedLeading is called when a LeaderElector client stops leading
|
// OnStoppedLeading is called when a LeaderElector client stops leading
|
||||||
OnStoppedLeading func()
|
OnStoppedLeading func()
|
||||||
|
// OnNewLeader is called when the client observes a leader that is
|
||||||
|
// not the previously observed leader. This includes the first observed
|
||||||
|
// leader when the client starts.
|
||||||
|
OnNewLeader func(identity string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LeaderElector is a leader election client.
|
// LeaderElector is a leader election client.
|
||||||
@ -139,6 +142,10 @@ type LeaderElector struct {
|
|||||||
// internal bookkeeping
|
// internal bookkeeping
|
||||||
observedRecord LeaderElectionRecord
|
observedRecord LeaderElectionRecord
|
||||||
observedTime time.Time
|
observedTime time.Time
|
||||||
|
// used to implement OnNewLeader(), may lag slightly from the
|
||||||
|
// value observedRecord.HolderIdentity if the transistion has
|
||||||
|
// not yet been reported.
|
||||||
|
reportedLeader string
|
||||||
}
|
}
|
||||||
|
|
||||||
// LeaderElectionRecord is the record that is stored in the leader election annotation.
|
// LeaderElectionRecord is the record that is stored in the leader election annotation.
|
||||||
@ -182,6 +189,7 @@ func (le *LeaderElector) acquire() {
|
|||||||
stop := make(chan struct{})
|
stop := make(chan struct{})
|
||||||
util.Until(func() {
|
util.Until(func() {
|
||||||
succeeded := le.tryAcquireOrRenew()
|
succeeded := le.tryAcquireOrRenew()
|
||||||
|
le.maybeReportTransition()
|
||||||
if !succeeded {
|
if !succeeded {
|
||||||
glog.V(4).Infof("failed to renew lease %v/%v", le.config.EndpointsMeta.Namespace, le.config.EndpointsMeta.Name)
|
glog.V(4).Infof("failed to renew lease %v/%v", le.config.EndpointsMeta.Namespace, le.config.EndpointsMeta.Name)
|
||||||
time.Sleep(wait.Jitter(le.config.RetryPeriod, JitterFactor))
|
time.Sleep(wait.Jitter(le.config.RetryPeriod, JitterFactor))
|
||||||
@ -200,6 +208,7 @@ func (le *LeaderElector) renew() {
|
|||||||
err := wait.Poll(le.config.RetryPeriod, le.config.RenewDeadline, func() (bool, error) {
|
err := wait.Poll(le.config.RetryPeriod, le.config.RenewDeadline, func() (bool, error) {
|
||||||
return le.tryAcquireOrRenew(), nil
|
return le.tryAcquireOrRenew(), nil
|
||||||
})
|
})
|
||||||
|
le.maybeReportTransition()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
glog.V(4).Infof("succesfully renewed lease %v/%v", le.config.EndpointsMeta.Namespace, le.config.EndpointsMeta.Name)
|
glog.V(4).Infof("succesfully renewed lease %v/%v", le.config.EndpointsMeta.Namespace, le.config.EndpointsMeta.Name)
|
||||||
return
|
return
|
||||||
@ -296,3 +305,13 @@ func (le *LeaderElector) tryAcquireOrRenew() bool {
|
|||||||
le.observedTime = time.Now()
|
le.observedTime = time.Now()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *LeaderElector) maybeReportTransition() {
|
||||||
|
if l.observedRecord.HolderIdentity == l.reportedLeader {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
l.reportedLeader = l.observedRecord.HolderIdentity
|
||||||
|
if l.config.Callbacks.OnNewLeader != nil {
|
||||||
|
go l.config.Callbacks.OnNewLeader(l.reportedLeader)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -22,6 +22,7 @@ package leaderelection
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -195,14 +196,24 @@ func TestTryAcquireOrRenew(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
lec := LeaderElectionConfig{
|
|
||||||
EndpointsMeta: api.ObjectMeta{Namespace: "foo", Name: "bar"},
|
|
||||||
Identity: "baz",
|
|
||||||
EventRecorder: &record.FakeRecorder{},
|
|
||||||
LeaseDuration: 10 * time.Second,
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
|
// OnNewLeader is called async so we have to wait for it.
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(1)
|
||||||
|
var reportedLeader string
|
||||||
|
|
||||||
|
lec := LeaderElectionConfig{
|
||||||
|
EndpointsMeta: api.ObjectMeta{Namespace: "foo", Name: "bar"},
|
||||||
|
Identity: "baz",
|
||||||
|
EventRecorder: &record.FakeRecorder{},
|
||||||
|
LeaseDuration: 10 * time.Second,
|
||||||
|
Callbacks: LeaderCallbacks{
|
||||||
|
OnNewLeader: func(l string) {
|
||||||
|
defer wg.Done()
|
||||||
|
reportedLeader = l
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
c := &testclient.Fake{}
|
c := &testclient.Fake{}
|
||||||
for _, reactor := range test.reactors {
|
for _, reactor := range test.reactors {
|
||||||
c.AddReactor(reactor.verb, "endpoints", reactor.reaction)
|
c.AddReactor(reactor.verb, "endpoints", reactor.reaction)
|
||||||
@ -237,5 +248,11 @@ func TestTryAcquireOrRenew(t *testing.T) {
|
|||||||
if !test.transitionLeader && le.observedRecord.LeaderTransitions != 0 {
|
if !test.transitionLeader && le.observedRecord.LeaderTransitions != 0 {
|
||||||
t.Errorf("[%v]leader should not have transitioned but did", i)
|
t.Errorf("[%v]leader should not have transitioned but did", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
le.maybeReportTransition()
|
||||||
|
wg.Wait()
|
||||||
|
if reportedLeader != test.outHolder {
|
||||||
|
t.Errorf("[%v]reported leader was not the new leader. expected %q, got %q", i, test.outHolder, reportedLeader)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user