package main import ( "context" "os" "path/filepath" "testing" "hakurei.app/check" "hakurei.app/internal/pkg" "hakurei.app/message" ) // cache refers to an instance of [pkg.Cache] that might be open. type cache struct { ctx context.Context msg message.Msg // Should generally not be used directly. c *pkg.Cache cures, jobs int hostAbstract, idle bool base string } // open opens the underlying [pkg.Cache]. func (cache *cache) open() (err error) { if cache.c != nil { return os.ErrInvalid } if cache.base == "" { cache.base = "cache" } var base *check.Absolute if cache.base, err = filepath.Abs(cache.base); err != nil { return } else if base, err = check.NewAbs(cache.base); err != nil { return } var flags int if cache.idle { flags |= pkg.CSchedIdle } if cache.hostAbstract { flags |= pkg.CHostAbstract } done := make(chan struct{}) defer close(done) go func() { select { case <-cache.ctx.Done(): if testing.Testing() { return } os.Exit(2) case <-done: return } }() cache.msg.Verbosef("opening cache at %s", base) cache.c, err = pkg.Open( cache.ctx, cache.msg, flags, cache.cures, cache.jobs, base, ) return } // Close closes the underlying [pkg.Cache] if it is open. func (cache *cache) Close() { if cache.c != nil { cache.c.Close() } } // Do calls f on the underlying cache and returns its error value. func (cache *cache) Do(f func(cache *pkg.Cache) error) error { if cache.c == nil { if err := cache.open(); err != nil { return err } } return f(cache.c) }