@@ -32,12 +32,12 @@ import (
3232)
3333
3434const (
35- // updatePeriod is the period which condition manager checks update.
35+ // updatePeriod is the period at which condition manager checks update.
3636 updatePeriod = 1 * time .Second
37- // updateTimeout is the timeout of condition update operation .
38- updateTimeout = 10 * time .Second
39- // resyncPeriod is the period which condition manager does resync no matter whether these is any update .
40- resyncPeriod = 30 * time .Second
37+ // resyncPeriod is the period at which condition manager does resync, only updates when needed .
38+ resyncPeriod = 10 * time .Second
39+ // heartbeatPeriod is the period at which condition manager does forcibly sync with apiserver .
40+ heartbeatPeriod = 1 * time .Minute
4141)
4242
4343// ConditionManager synchronizes node conditions with the apiserver with problem client.
@@ -52,17 +52,21 @@ const (
5252type ConditionManager interface {
5353 // Start starts the condition manager.
5454 Start ()
55- // UpdateCondition update specific condition.
55+ // UpdateCondition updates a specific condition.
5656 UpdateCondition (types.Condition )
5757}
5858
5959type conditionManager struct {
60- sync.Mutex
61- clock clock.Clock
62- latest time.Time
63- client problemclient.Client
64- updates map [string ]types.Condition
65- conditions map [string ]types.Condition
60+ clock clock.Clock
61+ latestTry time.Time
62+ resyncNeeded bool
63+ client problemclient.Client
64+ // updatesLock is the lock protecting updates. Only the field `updates`
65+ // will be accessed by random caller and the sync routine, so only it
66+ // needs to be protected.
67+ updatesLock sync.Mutex
68+ updates map [string ]types.Condition
69+ conditions map [string ]types.Condition
6670}
6771
6872// NewConditionManager creates a condition manager.
@@ -80,8 +84,8 @@ func (c *conditionManager) Start() {
8084}
8185
8286func (c * conditionManager ) UpdateCondition (condition types.Condition ) {
83- c .Lock ()
84- defer c .Unlock ()
87+ c .updatesLock . Lock ()
88+ defer c .updatesLock . Unlock ()
8589 // New node condition will override the old condition, because we only need the newest
8690 // condition for each condition type.
8791 c .updates [condition .Type ] = condition
@@ -92,17 +96,17 @@ func (c *conditionManager) syncLoop() {
9296 for {
9397 select {
9498 case <- updateCh :
95- if c .checkUpdates () || c .checkResync () {
99+ if c .needUpdates () || c .needResync () || c . needHeartbeat () {
96100 c .sync ()
97101 }
98102 }
99103 }
100104}
101105
102- // checkUpdates checks whether there are recent updates.
103- func (c * conditionManager ) checkUpdates () bool {
104- c .Lock ()
105- defer c .Unlock ()
106+ // needUpdates checks whether there are recent updates.
107+ func (c * conditionManager ) needUpdates () bool {
108+ c .updatesLock . Lock ()
109+ defer c .updatesLock . Unlock ()
106110 needUpdate := false
107111 for t , update := range c .updates {
108112 if ! reflect .DeepEqual (c .conditions [t ], update ) {
@@ -114,21 +118,29 @@ func (c *conditionManager) checkUpdates() bool {
114118 return needUpdate
115119}
116120
117- // checkResync checks whether a resync is needed.
118- func (c * conditionManager ) checkResync () bool {
119- return c .clock .Now ().Sub (c .latest ) >= resyncPeriod
121+ // needResync checks whether a resync is needed.
122+ func (c * conditionManager ) needResync () bool {
123+ // Only update when resync is needed.
124+ return c .clock .Now ().Sub (c .latestTry ) >= resyncPeriod && c .resyncNeeded
125+ }
126+
127+ // needHeartbeat checks whether a forcible heartbeat is needed.
128+ func (c * conditionManager ) needHeartbeat () bool {
129+ return c .clock .Now ().Sub (c .latestTry ) >= heartbeatPeriod
120130}
121131
122132// sync synchronizes node conditions with the apiserver.
123133func (c * conditionManager ) sync () {
134+ c .latestTry = c .clock .Now ()
135+ c .resyncNeeded = false
124136 conditions := []api.NodeCondition {}
125137 for i := range c .conditions {
126138 conditions = append (conditions , problemutil .ConvertToAPICondition (c .conditions [i ]))
127139 }
128140 if err := c .client .SetConditions (conditions ); err != nil {
129141 // The conditions will be updated again in future sync
130142 glog .Errorf ("failed to update node conditions: %v" , err )
143+ c .resyncNeeded = true
131144 return
132145 }
133- c .latest = c .clock .Now ()
134146}
0 commit comments