Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite225434

Browse files
committed
refactor ticker and refresh
1 parent0122e43 commite225434

File tree

1 file changed

+40
-44
lines changed

1 file changed

+40
-44
lines changed

‎agent/agentcontainers/api.go

Lines changed: 40 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ type API struct {
3838
watcherDonechanstruct{}
3939
updaterDonechanstruct{}
4040
initialUpdateDonechanstruct{}// Closed after first update in updaterLoop.
41-
refreshTriggerchanchanerror// Channel to trigger manual refresh.
41+
updateTriggerchanchanerror// Channel to trigger manual refresh.
4242
updateInterval time.Duration// Interval for periodic container updates.
4343
logger slog.Logger
4444
watcher watcher.Watcher
@@ -164,7 +164,7 @@ func NewAPI(logger slog.Logger, options ...Option) *API {
164164
watcherDone:make(chanstruct{}),
165165
updaterDone:make(chanstruct{}),
166166
initialUpdateDone:make(chanstruct{}),
167-
refreshTrigger:make(chanchanerror),
167+
updateTrigger:make(chanchanerror),
168168
updateInterval:defaultUpdateInterval,
169169
logger:logger,
170170
clock:quartz.NewReal(),
@@ -247,27 +247,12 @@ func (api *API) updaterLoop() {
247247
deferapi.logger.Debug(api.ctx,"updater loop stopped")
248248
api.logger.Debug(api.ctx,"updater loop started")
249249

250-
// Ensure that only once instance of the updateContainers is running
251-
// at a time. This is a workaround since quartz.Ticker does not
252-
// allow us to know if the routine has completed.
253-
sema:=make(chanstruct{},1)
254-
sema<-struct{}{}
255-
256-
// Ensure only one updateContainers is running at a time, others are
257-
// queued.
258-
doUpdate:=func()error {
259-
select {
260-
case<-api.ctx.Done():
261-
returnapi.ctx.Err()
262-
case<-sema:
263-
}
264-
deferfunc() {sema<-struct{}{} }()
265-
266-
returnapi.updateContainers(api.ctx)
267-
}
268-
250+
// Perform an initial update to populate the container list, this
251+
// gives us a guarantee that the API has loaded the initial state
252+
// before returning any responses. This is useful for both tests
253+
// and anyone looking to interact with the API.
269254
api.logger.Debug(api.ctx,"performing initial containers update")
270-
iferr:=doUpdate();err!=nil {
255+
iferr:=api.updateContainers(api.ctx);err!=nil {
271256
api.logger.Error(api.ctx,"initial containers update failed",slog.Error(err))
272257
}else {
273258
api.logger.Debug(api.ctx,"initial containers update complete")
@@ -276,34 +261,39 @@ func (api *API) updaterLoop() {
276261
// Other services can wait on this if they need the first data to be available.
277262
close(api.initialUpdateDone)
278263

279-
// Use a ticker func to ensure that doUpdate has run to completion
280-
// when advancing time.
281-
waiter:=api.clock.TickerFunc(api.ctx,api.updateInterval,func()error {
282-
err:=doUpdate()
283-
iferr!=nil {
284-
api.logger.Error(api.ctx,"periodic containers update failed",slog.Error(err))
264+
// We utilize a TickerFunc here instead of a regular Ticker so that
265+
// we can guarantee execution of the updateContainers method after
266+
// advancing the clock.
267+
ticker:=api.clock.TickerFunc(api.ctx,api.updateInterval,func()error {
268+
done:=make(chanerror,1)
269+
deferclose(done)
270+
271+
select {
272+
case<-api.ctx.Done():
273+
returnapi.ctx.Err()
274+
caseapi.updateTrigger<-done:
275+
err:=<-done
276+
iferr!=nil {
277+
api.logger.Error(api.ctx,"updater loop ticker failed",slog.Error(err))
278+
}
279+
default:
280+
api.logger.Debug(api.ctx,"updater loop ticker skipped, update in progress")
285281
}
286-
returnnil// Always nil, keep going.
287-
})
282+
283+
returnnil// Always nil to keep the ticker going.
284+
},"updaterLoop")
288285
deferfunc() {
289-
iferr:=waiter.Wait();err!=nil {
286+
iferr:=ticker.Wait("updaterLoop");err!=nil&&!errors.Is(err,context.Canceled) {
290287
api.logger.Error(api.ctx,"updater loop ticker failed",slog.Error(err))
291288
}
292289
}()
293290

294291
for {
295292
select {
296293
case<-api.ctx.Done():
297-
api.logger.Debug(api.ctx,"updater loop context canceled")
298294
return
299-
casech:=<-api.refreshTrigger:
300-
api.logger.Debug(api.ctx,"manual containers update triggered")
301-
err:=doUpdate()
302-
iferr!=nil {
303-
api.logger.Error(api.ctx,"manual containers update failed",slog.Error(err))
304-
}
305-
ch<-err
306-
close(ch)
295+
casedone:=<-api.updateTrigger:
296+
done<-api.updateContainers(api.ctx)
307297
}
308298
}
309299
}
@@ -506,17 +496,23 @@ func (api *API) processUpdatedContainersLocked(ctx context.Context, updated code
506496

507497
// refreshContainers triggers an immediate update of the container list
508498
// and waits for it to complete.
509-
func (api*API)refreshContainers(ctx context.Context)error {
499+
func (api*API)refreshContainers(ctx context.Context) (errerror) {
500+
deferfunc() {
501+
iferr!=nil {
502+
err=xerrors.Errorf("refresh containers failed: %w",err)
503+
}
504+
}()
505+
510506
done:=make(chanerror,1)
511507
select {
512508
case<-api.ctx.Done():
513-
returnxerrors.Errorf("API closed, cannot send refresh trigger: %w",api.ctx.Err())
509+
returnxerrors.Errorf("API closed: %w",api.ctx.Err())
514510
case<-ctx.Done():
515511
returnctx.Err()
516-
caseapi.refreshTrigger<-done:
512+
caseapi.updateTrigger<-done:
517513
select {
518514
case<-api.ctx.Done():
519-
returnxerrors.Errorf("API closed, cannot wait for refresh: %w",api.ctx.Err())
515+
returnxerrors.Errorf("API closed: %w",api.ctx.Err())
520516
case<-ctx.Done():
521517
returnctx.Err()
522518
caseerr:=<-done:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp