aboutsummaryrefslogtreecommitdiffhomepage
path: root/cmd/mbf/cache.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-04-16 15:43:06 +0900
committerOphestra <cat@gensokyo.uk>2026-04-16 15:59:34 +0900
commit136bc0917be7c02b818bfc8d4d54ec8ffbc8d21b (patch)
tree08fec4ac2d6beb05c4c536497cd88678feb419e1 /cmd/mbf/cache.go
parentd6b082dd0b162197c06b8ac06279024c64ceb0e3 (diff)
cmd/mbf: optionally open cache
Some commands do not require the cache. This change also makes acquisition of locked cache cancelable. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'cmd/mbf/cache.go')
-rw-r--r--cmd/mbf/cache.go90
1 files changed, 90 insertions, 0 deletions
diff --git a/cmd/mbf/cache.go b/cmd/mbf/cache.go
new file mode 100644
index 00000000..16e77cbc
--- /dev/null
+++ b/cmd/mbf/cache.go
@@ -0,0 +1,90 @@
+package main
+
+import (
+ "context"
+ "os"
+ "path/filepath"
+
+ "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():
+ 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)
+}