Skip to content

Commit 135ea2b

Browse files
authored
Code cleanup for command checkins (#3376)
* Small cleanups * more cleanups
1 parent 7e86d24 commit 135ea2b

File tree

4 files changed

+77
-70
lines changed

4 files changed

+77
-70
lines changed

pkg/component/runtime/command.go

+26-12
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,31 @@ type commandRuntime struct {
7373
current component.Component
7474
monitor MonitoringManager
7575

76-
ch chan ComponentState
76+
// ch is the reporting channel for the current state. When a policy change
77+
// or client checkin affects the component state, its new value is sent
78+
// here and handled by (componentRuntimeState).runLoop.
79+
ch chan ComponentState
80+
81+
// When the managed process closes, its termination status is sent on procCh
82+
// by the watching goroutine, and handled by (*commandRuntime).Run.
83+
procCh chan procState
84+
85+
// compCh forwards new component metadata from the runtime manager to
86+
// the command runtime. It is written by calls to (*commandRuntime).Update
87+
// and read by the run loop in (*commandRuntime).Run.
88+
compCh chan component.Component
89+
90+
// The most recent mode received on actionCh. The mode will be either
91+
// actionStart (indicating the process should be running, and should be
92+
// created if it is not), or actionStop or actionTeardown (indicating that
93+
// it should terminate).
94+
actionState actionMode
95+
96+
// actionState is changed by sending its new value on actionCh, where it is
97+
// handled by (*commandRuntime).Run.
7798
actionCh chan actionMode
78-
procCh chan procState
79-
compCh chan component.Component
8099

81-
actionState actionMode
82-
proc *process.Info
100+
proc *process.Info
83101

84102
state ComponentState
85103
lastCheckin time.Time
@@ -204,14 +222,10 @@ func (c *commandRuntime) Run(ctx context.Context, comm Communicator) error {
204222
} else {
205223
// running and should be running
206224
now := time.Now().UTC()
207-
if c.lastCheckin.IsZero() {
208-
// never checked-in
209-
c.missedCheckins++
210-
} else if now.Sub(c.lastCheckin) > checkinPeriod {
211-
// missed check-in during required period
212-
c.missedCheckins++
213-
} else if now.Sub(c.lastCheckin) <= checkinPeriod {
225+
if now.Sub(c.lastCheckin) <= checkinPeriod {
214226
c.missedCheckins = 0
227+
} else {
228+
c.missedCheckins++
215229
}
216230
if c.missedCheckins == 0 {
217231
c.compState(client.UnitStateHealthy)

pkg/component/runtime/manager.go

+4-12
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,6 @@ func (m *Manager) State() []ComponentComponentState {
268268
defer m.currentMx.RUnlock()
269269
states := make([]ComponentComponentState, 0, len(m.current))
270270
for _, crs := range m.current {
271-
crs.latestMx.RLock()
272271
var legacyPID string
273272
if crs.runtime != nil {
274273
if commandRuntime, ok := crs.runtime.(*commandRuntime); ok {
@@ -282,10 +281,9 @@ func (m *Manager) State() []ComponentComponentState {
282281
}
283282
states = append(states, ComponentComponentState{
284283
Component: crs.getCurrent(),
285-
State: crs.latestState.Copy(),
284+
State: crs.getLatest(),
286285
LegacyPID: legacyPID,
287286
})
288-
crs.latestMx.RUnlock()
289287
}
290288
return states
291289
}
@@ -484,9 +482,7 @@ func (m *Manager) Subscribe(ctx context.Context, componentID string) *Subscripti
484482
comp, ok := m.current[componentID]
485483
m.currentMx.RUnlock()
486484
if ok {
487-
comp.latestMx.RLock()
488-
latestState := comp.latestState.Copy()
489-
comp.latestMx.RUnlock()
485+
latestState := comp.getLatest()
490486
go func() {
491487
select {
492488
case <-ctx.Done():
@@ -532,9 +528,7 @@ func (m *Manager) SubscribeAll(ctx context.Context) *SubscriptionAll {
532528
m.currentMx.RLock()
533529
latest := make([]ComponentComponentState, 0, len(m.current))
534530
for _, comp := range m.current {
535-
comp.latestMx.RLock()
536-
latest = append(latest, ComponentComponentState{Component: comp.getCurrent(), State: comp.latestState.Copy()})
537-
comp.latestMx.RUnlock()
531+
latest = append(latest, ComponentComponentState{Component: comp.getCurrent(), State: comp.getLatest()})
538532
}
539533
m.currentMx.RUnlock()
540534
if len(latest) > 0 {
@@ -759,9 +753,7 @@ func (m *Manager) waitForStopped(comp *componentRuntimeState) {
759753

760754
timeoutCh := time.After(timeout)
761755
for {
762-
comp.latestMx.RLock()
763-
latestState := comp.latestState
764-
comp.latestMx.RUnlock()
756+
latestState := comp.getLatest()
765757
if latestState.State == client.UnitStateStopped {
766758
return
767759
}

pkg/component/runtime/runtime.go

+6
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,12 @@ func (s *componentRuntimeState) setCurrent(current component.Component) {
176176
s.currCompMx.Unlock()
177177
}
178178

179+
func (s *componentRuntimeState) getLatest() ComponentState {
180+
s.latestMx.RLock()
181+
defer s.latestMx.RUnlock()
182+
return s.latestState.Copy()
183+
}
184+
179185
func (s *componentRuntimeState) start() error {
180186
return s.runtime.Start()
181187
}

pkg/component/runtime/state.go

+41-46
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,10 @@ func newComponentState(comp *component.Component) (s ComponentState) {
102102
s.expectedFeaturesIdx = 1
103103
s.expectedComponentIdx = 1
104104

105-
s.syncComponent(comp)
105+
// Merge initial component state.
106+
s.syncExpected(comp)
107+
s.syncUnits(comp)
108+
106109
return s
107110
}
108111

@@ -131,15 +134,6 @@ func (s *ComponentState) Copy() (c ComponentState) {
131134
return c
132135
}
133136

134-
func (s *ComponentState) syncComponent(comp *component.Component) bool {
135-
changed := s.syncExpected(comp)
136-
s.syncUnits(comp)
137-
if changed {
138-
return true
139-
}
140-
return s.unsettled()
141-
}
142-
143137
func (s *ComponentState) syncExpected(comp *component.Component) bool {
144138
changed := false
145139
touched := make(map[ComponentUnitKey]bool)
@@ -151,34 +145,34 @@ func (s *ComponentState) syncExpected(comp *component.Component) bool {
151145
}
152146

153147
touched[key] = true
154-
existing, ok := s.expectedUnits[key]
148+
expected, ok := s.expectedUnits[key]
155149
if ok {
156-
if existing.logLevel != unit.LogLevel {
157-
existing.logLevel = unit.LogLevel
150+
if expected.logLevel != unit.LogLevel {
151+
expected.logLevel = unit.LogLevel
158152
changed = true
159153
}
160-
if !gproto.Equal(existing.config, unit.Config) {
161-
existing.config = unit.Config
162-
existing.configStateIdx++
154+
if !gproto.Equal(expected.config, unit.Config) {
155+
expected.config = unit.Config
156+
expected.configStateIdx++
163157
changed = true
164158
}
165159
} else {
166-
existing.state = client.UnitStateHealthy
167-
existing.logLevel = unit.LogLevel
168-
existing.config = unit.Config
169-
existing.configStateIdx = 1
160+
expected.state = client.UnitStateHealthy
161+
expected.logLevel = unit.LogLevel
162+
expected.config = unit.Config
163+
expected.configStateIdx = 1
170164
changed = true
171165
}
172166

173-
if !errors.Is(existing.err, unit.Err) {
174-
existing.err = unit.Err
175-
if existing.err != nil {
176-
existing.state = client.UnitStateFailed
167+
if !errors.Is(expected.err, unit.Err) {
168+
expected.err = unit.Err
169+
if expected.err != nil {
170+
expected.state = client.UnitStateFailed
177171
}
178172
changed = true
179173
}
180174

181-
s.expectedUnits[key] = existing
175+
s.expectedUnits[key] = expected
182176
}
183177

184178
for key, unit := range s.expectedUnits {
@@ -320,27 +314,28 @@ func (s *ComponentState) syncCheckin(checkin *proto.CheckinObserved) bool {
320314
}
321315

322316
for key, unit := range s.Units {
323-
_, ok := touched[key]
324-
if !ok {
325-
unit.unitState = client.UnitStateStarting
326-
unit.unitMessage = ""
327-
unit.unitPayload = nil
328-
unit.configStateIdx = 0
329-
if unit.err != nil {
330-
errMsg := unit.err.Error()
331-
if unit.State != client.UnitStateFailed || unit.Message != errMsg || diffPayload(unit.Payload, nil) {
332-
changed = true
333-
unit.State = client.UnitStateFailed
334-
unit.Message = errMsg
335-
unit.Payload = nil
336-
}
337-
} else if unit.State != client.UnitStateStarting && unit.State != client.UnitStateStopped {
338-
if unit.State != client.UnitStateFailed || unit.Message != missingMsg || diffPayload(unit.Payload, nil) {
339-
changed = true
340-
unit.State = client.UnitStateFailed
341-
unit.Message = missingMsg
342-
unit.Payload = nil
343-
}
317+
// Look for units that weren't in the checkin.
318+
if _, ok := touched[key]; ok {
319+
continue
320+
}
321+
unit.unitState = client.UnitStateStarting
322+
unit.unitMessage = ""
323+
unit.unitPayload = nil
324+
unit.configStateIdx = 0
325+
if unit.err != nil {
326+
errMsg := unit.err.Error()
327+
if unit.State != client.UnitStateFailed || unit.Message != errMsg || diffPayload(unit.Payload, nil) {
328+
changed = true
329+
unit.State = client.UnitStateFailed
330+
unit.Message = errMsg
331+
unit.Payload = nil
332+
}
333+
} else if unit.State != client.UnitStateStarting && unit.State != client.UnitStateStopped {
334+
if unit.State != client.UnitStateFailed || unit.Message != missingMsg || diffPayload(unit.Payload, nil) {
335+
changed = true
336+
unit.State = client.UnitStateFailed
337+
unit.Message = missingMsg
338+
unit.Payload = nil
344339
}
345340
}
346341

0 commit comments

Comments
 (0)