use context to stop main() jobs

use
This commit is contained in:
sentriz
2024-02-27 00:33:39 +00:00
parent a66463a68c
commit 02606087dc
6 changed files with 24 additions and 50 deletions

View File

@@ -325,13 +325,7 @@ func main() {
defer logJob("scan watcher")() defer logJob("scan watcher")()
done := make(chan struct{}) return scannr.ExecuteWatch(ctx)
errgrp.Go(func() error {
<-ctx.Done()
done <- struct{}{}
return nil
})
return scannr.ExecuteWatch(done)
}) })
errgrp.Go(func() error { errgrp.Go(func() error {
@@ -350,14 +344,7 @@ func main() {
return fmt.Errorf("create tmp sock file: %w", err) return fmt.Errorf("create tmp sock file: %w", err)
} }
sockPath := filepath.Join(jukeboxTempDir, "sock") sockPath := filepath.Join(jukeboxTempDir, "sock")
if err := jukebx.Start(sockPath, extraArgs); err != nil { if err := jukebx.Start(ctx, sockPath, extraArgs); err != nil {
return fmt.Errorf("start jukebox: %w", err)
}
errgrp.Go(func() error {
<-ctx.Done()
return jukebx.Quit()
})
if err := jukebx.Wait(); err != nil {
return fmt.Errorf("start jukebox: %w", err) return fmt.Errorf("start jukebox: %w", err)
} }
return nil return nil

4
go.mod
View File

@@ -25,7 +25,7 @@ require (
github.com/sentriz/audiotags v0.0.0-20240202193907-618ae39d7743 github.com/sentriz/audiotags v0.0.0-20240202193907-618ae39d7743
github.com/sentriz/gormstore v0.0.0-20220105134332-64e31f7f6981 github.com/sentriz/gormstore v0.0.0-20220105134332-64e31f7f6981
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
go.senan.xyz/flagconf v0.1.4 go.senan.xyz/flagconf v0.1.5
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 golang.org/x/exp v0.0.0-20240222234643-814bf88cf225
golang.org/x/net v0.21.0 golang.org/x/net v0.21.0
golang.org/x/sync v0.6.0 golang.org/x/sync v0.6.0
@@ -59,7 +59,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
golang.org/x/crypto v0.19.0 // indirect golang.org/x/crypto v0.20.0 // indirect
golang.org/x/image v0.15.0 // indirect golang.org/x/image v0.15.0 // indirect
golang.org/x/sys v0.17.0 // indirect golang.org/x/sys v0.17.0 // indirect
golang.org/x/text v0.14.0 // indirect golang.org/x/text v0.14.0 // indirect

8
go.sum
View File

@@ -137,15 +137,15 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.senan.xyz/flagconf v0.1.4 h1:j92ZqK4o299UBH2wVjhV6VevyhIHwrPSkzgj/+ShDCA= go.senan.xyz/flagconf v0.1.5 h1:5HTNpA5jzH1XnsyR79pClXf9T+V+6OL/IsESORMrExs=
go.senan.xyz/flagconf v0.1.4/go.mod h1:CGD/sgYWiTacz1ojgsQRwErqLxtShWMpBxxnsJI6yaE= go.senan.xyz/flagconf v0.1.5/go.mod h1:CGD/sgYWiTacz1ojgsQRwErqLxtShWMpBxxnsJI6yaE=
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ=
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=

View File

@@ -4,6 +4,7 @@
package jukebox package jukebox
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"os" "os"
@@ -46,7 +47,7 @@ func New() *Jukebox {
return &Jukebox{} return &Jukebox{}
} }
func (j *Jukebox) Start(sockPath string, mpvExtraArgs []string) error { func (j *Jukebox) Start(ctx context.Context, sockPath string, mpvExtraArgs []string) error {
const mpvName = "mpv" const mpvName = "mpv"
if _, err := exec.LookPath(mpvName); err != nil { if _, err := exec.LookPath(mpvName); err != nil {
return fmt.Errorf("look path: %w. did you forget to install it?", err) return fmt.Errorf("look path: %w. did you forget to install it?", err)
@@ -56,7 +57,7 @@ func (j *Jukebox) Start(sockPath string, mpvExtraArgs []string) error {
mpvArgs = append(mpvArgs, "--idle", "--no-config", "--no-video", MPVArg("--audio-display", "no"), MPVArg("--input-ipc-server", sockPath)) mpvArgs = append(mpvArgs, "--idle", "--no-config", "--no-video", MPVArg("--audio-display", "no"), MPVArg("--input-ipc-server", sockPath))
mpvArgs = append(mpvArgs, mpvExtraArgs...) mpvArgs = append(mpvArgs, mpvExtraArgs...)
j.cmd = exec.Command(mpvName, mpvArgs...) j.cmd = exec.CommandContext(ctx, mpvName, mpvArgs...)
if err := j.cmd.Start(); err != nil { if err := j.cmd.Start(); err != nil {
return fmt.Errorf("start mpv process: %w", err) return fmt.Errorf("start mpv process: %w", err)
} }
@@ -87,14 +88,15 @@ func (j *Jukebox) Start(sockPath string, mpvExtraArgs []string) error {
return fmt.Errorf("observe property: %w", err) return fmt.Errorf("observe property: %w", err)
} }
return nil
}
func (j *Jukebox) Wait() error {
var exitError *exec.ExitError var exitError *exec.ExitError
if err := j.cmd.Wait(); err != nil && !errors.As(err, &exitError) { if err := j.cmd.Wait(); err != nil && !errors.As(err, &exitError) {
return fmt.Errorf("wait jukebox: %w", err) return fmt.Errorf("wait jukebox: %w", err)
} }
if err := j.conn.Close(); err != nil {
return fmt.Errorf("close: %w", err)
}
j.conn.WaitUntilClosed()
return nil return nil
} }
@@ -309,26 +311,6 @@ func (j *Jukebox) GetStatus() (*Status, error) {
return &status, nil return &status, nil
} }
func (j *Jukebox) Quit() error {
defer lock(&j.mu)()
if j.conn == nil || j.conn.IsClosed() {
return nil
}
go func() {
_, _ = j.conn.Call("quit")
}()
time.Sleep(250 * time.Millisecond)
_ = j.cmd.Process.Kill()
if err := j.conn.Close(); err != nil {
return fmt.Errorf("close: %w", err)
}
j.conn.WaitUntilClosed()
return nil
}
func getDecode(conn *mpvipc.Connection, dest any, property string) error { func getDecode(conn *mpvipc.Connection, dest any, property string) error {
raw, err := conn.Get(property) raw, err := conn.Get(property)
if err != nil { if err != nil {

View File

@@ -1,6 +1,7 @@
package jukebox_test package jukebox_test
import ( import (
"context"
"errors" "errors"
"os" "os"
"path/filepath" "path/filepath"
@@ -193,8 +194,11 @@ func newJukebox(tb testing.TB) *jukebox.Jukebox {
sockPath := filepath.Join(tb.TempDir(), "mpv.sock") sockPath := filepath.Join(tb.TempDir(), "mpv.sock")
ctx, cancel := context.WithCancel(context.Background())
j := jukebox.New() j := jukebox.New()
err := j.Start( err := j.Start(
ctx,
sockPath, sockPath,
[]string{jukebox.MPVArg("--ao", "null")}, []string{jukebox.MPVArg("--ao", "null")},
) )
@@ -205,7 +209,7 @@ func newJukebox(tb testing.TB) *jukebox.Jukebox {
tb.Fatalf("start jukebox: %v", err) tb.Fatalf("start jukebox: %v", err)
} }
tb.Cleanup(func() { tb.Cleanup(func() {
j.Quit() cancel()
}) })
return j return j
} }

View File

@@ -2,6 +2,7 @@
package scanner package scanner
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"io/fs" "io/fs"
@@ -111,7 +112,7 @@ func (s *Scanner) ScanAndClean(opts ScanOptions) (*State, error) {
return st, errors.Join(st.errs...) return st, errors.Join(st.errs...)
} }
func (s *Scanner) ExecuteWatch(done <-chan struct{}) error { func (s *Scanner) ExecuteWatch(ctx context.Context) error {
watcher, err := fsnotify.NewWatcher() watcher, err := fsnotify.NewWatcher()
if err != nil { if err != nil {
return fmt.Errorf("creating watcher: %w", err) return fmt.Errorf("creating watcher: %w", err)
@@ -180,7 +181,7 @@ func (s *Scanner) ExecuteWatch(done <-chan struct{}) error {
case err := <-watcher.Errors: case err := <-watcher.Errors:
log.Printf("error from watcher: %v\n", err) log.Printf("error from watcher: %v\n", err)
case <-done: case <-ctx.Done():
return nil return nil
} }
} }