stop watch process when associated up process is stopped

Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com>
This commit is contained in:
Guillaume Lours 2024-06-17 10:59:57 +02:00
parent 36ef5b3881
commit 54a5e7d4aa
4 changed files with 28 additions and 14 deletions

View File

@ -73,7 +73,7 @@ func (ke *KeyboardError) error() string {
type KeyboardWatch struct { type KeyboardWatch struct {
Watcher watch.Notify Watcher watch.Notify
Watching bool Watching bool
WatchFn func(ctx context.Context, project *types.Project, services []string, options api.WatchOptions) error WatchFn func(ctx context.Context, doneCh chan bool, project *types.Project, services []string, options api.WatchOptions) error
Ctx context.Context Ctx context.Context
Cancel context.CancelFunc Cancel context.CancelFunc
} }
@ -117,6 +117,7 @@ var eg multierror.Group
func NewKeyboardManager(ctx context.Context, isDockerDesktopActive, isWatchConfigured, isDockerDesktopConfigActive bool, func NewKeyboardManager(ctx context.Context, isDockerDesktopActive, isWatchConfigured, isDockerDesktopConfigActive bool,
sc chan<- os.Signal, sc chan<- os.Signal,
watchFn func(ctx context.Context, watchFn func(ctx context.Context,
doneCh chan bool,
project *types.Project, project *types.Project,
services []string, services []string,
options api.WatchOptions, options api.WatchOptions,
@ -272,7 +273,7 @@ func (lk *LogKeyboard) keyboardError(prefix string, err error) {
}() }()
} }
func (lk *LogKeyboard) StartWatch(ctx context.Context, project *types.Project, options api.UpOptions) { func (lk *LogKeyboard) StartWatch(ctx context.Context, doneCh chan bool, project *types.Project, options api.UpOptions) {
if !lk.IsWatchConfigured { if !lk.IsWatchConfigured {
eg.Go(tracing.EventWrapFuncForErrGroup(ctx, "menu/watch", tracing.SpanOptions{}, eg.Go(tracing.EventWrapFuncForErrGroup(ctx, "menu/watch", tracing.SpanOptions{},
func(ctx context.Context) error { func(ctx context.Context) error {
@ -297,7 +298,7 @@ func (lk *LogKeyboard) StartWatch(ctx context.Context, project *types.Project, o
lk.Watch.newContext(ctx) lk.Watch.newContext(ctx)
buildOpts := *options.Create.Build buildOpts := *options.Create.Build
buildOpts.Quiet = true buildOpts.Quiet = true
return lk.Watch.WatchFn(lk.Watch.Ctx, project, options.Start.Services, api.WatchOptions{ return lk.Watch.WatchFn(lk.Watch.Ctx, doneCh, project, options.Start.Services, api.WatchOptions{
Build: &buildOpts, Build: &buildOpts,
LogTo: options.Start.Attach, LogTo: options.Start.Attach,
}) })
@ -305,12 +306,12 @@ func (lk *LogKeyboard) StartWatch(ctx context.Context, project *types.Project, o
} }
} }
func (lk *LogKeyboard) HandleKeyEvents(event keyboard.KeyEvent, ctx context.Context, project *types.Project, options api.UpOptions) { func (lk *LogKeyboard) HandleKeyEvents(event keyboard.KeyEvent, ctx context.Context, doneCh chan bool, project *types.Project, options api.UpOptions) {
switch kRune := event.Rune; kRune { switch kRune := event.Rune; kRune {
case 'v': case 'v':
lk.openDockerDesktop(ctx, project) lk.openDockerDesktop(ctx, project)
case 'w': case 'w':
lk.StartWatch(ctx, project, options) lk.StartWatch(ctx, doneCh, project, options)
case 'o': case 'o':
lk.openDDComposeUI(ctx, project) lk.openDDComposeUI(ctx, project)
} }

View File

@ -101,9 +101,9 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options
isDockerDesktopComposeUI := s.isDesktopUIEnabled() isDockerDesktopComposeUI := s.isDesktopUIEnabled()
tracing.KeyboardMetrics(ctx, options.Start.NavigationMenu, isDockerDesktopActive, isWatchConfigured, isDockerDesktopComposeUI) tracing.KeyboardMetrics(ctx, options.Start.NavigationMenu, isDockerDesktopActive, isWatchConfigured, isDockerDesktopComposeUI)
formatter.NewKeyboardManager(ctx, isDockerDesktopActive, isWatchConfigured, isDockerDesktopComposeUI, signalChan, s.Watch) formatter.NewKeyboardManager(ctx, isDockerDesktopActive, isWatchConfigured, isDockerDesktopComposeUI, signalChan, s.watch)
if options.Start.Watch { if options.Start.Watch {
formatter.KeyboardManager.StartWatch(ctx, project, options) formatter.KeyboardManager.StartWatch(ctx, doneCh, project, options)
} }
} }
} }
@ -136,7 +136,7 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options
}) })
return nil return nil
case event := <-kEvents: case event := <-kEvents:
formatter.KeyboardManager.HandleKeyEvents(event, ctx, project, options) formatter.KeyboardManager.HandleKeyEvents(event, ctx, doneCh, project, options)
} }
} }
}) })
@ -160,7 +160,7 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options
eg.Go(func() error { eg.Go(func() error {
buildOpts := *options.Create.Build buildOpts := *options.Create.Build
buildOpts.Quiet = true buildOpts.Quiet = true
return s.Watch(ctx, project, options.Start.Services, api.WatchOptions{ return s.watch(ctx, doneCh, project, options.Start.Services, api.WatchOptions{
Build: &buildOpts, Build: &buildOpts,
LogTo: options.Start.Attach, LogTo: options.Start.Attach,
}) })

View File

@ -77,7 +77,10 @@ func (s *composeService) shouldWatch(project *types.Project) bool {
return shouldWatch return shouldWatch
} }
func (s *composeService) Watch(ctx context.Context, project *types.Project, services []string, options api.WatchOptions) error { //nolint: gocyclo func (s *composeService) Watch(ctx context.Context, project *types.Project, services []string, options api.WatchOptions) error {
return s.watch(ctx, nil, project, services, options)
}
func (s *composeService) watch(ctx context.Context, syncChannel chan bool, project *types.Project, services []string, options api.WatchOptions) error { //nolint: gocyclo
var err error var err error
if project, err = project.WithSelectedServices(services); err != nil { if project, err = project.WithSelectedServices(services); err != nil {
return err return err
@ -172,7 +175,7 @@ func (s *composeService) Watch(ctx context.Context, project *types.Project, serv
watching = true watching = true
eg.Go(func() error { eg.Go(func() error {
defer watcher.Close() //nolint:errcheck defer watcher.Close() //nolint:errcheck
return s.watch(ctx, project, service.Name, options, watcher, syncer, config.Watch) return s.watchEvents(ctx, project, service.Name, options, watcher, syncer, config.Watch)
}) })
} }
if !watching { if !watching {
@ -180,10 +183,20 @@ func (s *composeService) Watch(ctx context.Context, project *types.Project, serv
} }
options.LogTo.Log(api.WatchLogger, "Watch enabled") options.LogTo.Log(api.WatchLogger, "Watch enabled")
return eg.Wait() err = eg.Wait()
for {
select {
case <-ctx.Done():
return err
case <-syncChannel:
options.LogTo.Log(api.WatchLogger, "Watch disabled")
ctx.Done()
return err
}
}
} }
func (s *composeService) watch(ctx context.Context, project *types.Project, name string, options api.WatchOptions, watcher watch.Notify, syncer sync.Syncer, triggers []types.Trigger) error { func (s *composeService) watchEvents(ctx context.Context, project *types.Project, name string, options api.WatchOptions, watcher watch.Notify, syncer sync.Syncer, triggers []types.Trigger) error {
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
defer cancel() defer cancel()

View File

@ -144,7 +144,7 @@ func TestWatch_Sync(t *testing.T) {
dockerCli: cli, dockerCli: cli,
clock: clock, clock: clock,
} }
err := service.watch(ctx, &proj, "test", api.WatchOptions{ err := service.watchEvents(ctx, &proj, "test", api.WatchOptions{
Build: &api.BuildOptions{}, Build: &api.BuildOptions{},
LogTo: stdLogger{}, LogTo: stdLogger{},
}, watcher, syncer, []types.Trigger{ }, watcher, syncer, []types.Trigger{