aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-04-15 15:35:45 +0900
committerOphestra <cat@gensokyo.uk>2026-04-15 15:36:44 +0900
commitf7f48d57e9260f4e076e47013318714a52527b2f (patch)
treed16fa26a0b7843c9ff568d3f86df4219c0eedcab
parent5c2345128e06c53702b36c7a0920a6b7778f3e61 (diff)
internal/pkg: pass impure job count
This is cleaner than checking cpu count during cure, it is impossible to avoid impurity in both situations but this is configurable. Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--cmd/mbf/main.go7
-rw-r--r--internal/pkg/pkg.go18
-rw-r--r--internal/pkg/pkg_test.go12
-rw-r--r--internal/rosa/rosa_test.go2
4 files changed, 27 insertions, 12 deletions
diff --git a/cmd/mbf/main.go b/cmd/mbf/main.go
index c79a61bf..a9d9a0c8 100644
--- a/cmd/mbf/main.go
+++ b/cmd/mbf/main.go
@@ -72,6 +72,7 @@ func main() {
var (
flagQuiet bool
flagCures int
+ flagJobs int
flagBase string
flagIdle bool
@@ -99,7 +100,7 @@ func main() {
if flagHostAbstract {
flags |= pkg.CHostAbstract
}
- cache, err = pkg.Open(ctx, msg, flags, flagCures, base)
+ cache, err = pkg.Open(ctx, msg, flags, flagCures, flagJobs, base)
return
}).Flag(
@@ -111,6 +112,10 @@ func main() {
"cures", command.IntFlag(0),
"Maximum number of dependencies to cure at any given time",
).Flag(
+ &flagJobs,
+ "jobs", command.IntFlag(0),
+ "Preferred number of jobs to run, when applicable",
+ ).Flag(
&flagBase,
"d", command.StringFlag("$MBF_CACHE_DIR"),
"Directory to store cured artifacts",
diff --git a/internal/pkg/pkg.go b/internal/pkg/pkg.go
index 1ecd4b5c..b2eceb25 100644
--- a/internal/pkg/pkg.go
+++ b/internal/pkg/pkg.go
@@ -188,6 +188,10 @@ func (c *common) Unwrap() context.Context { return c.cache.ctx }
// GetMessage returns [message.Msg] held by the underlying [Cache].
func (c *common) GetMessage() message.Msg { return c.cache.msg }
+// GetJobs returns the preferred number of jobs to run, when applicable. Its
+// value must not affect cure outcome.
+func (c *common) GetJobs() int { return c.cache.jobs }
+
// GetWorkDir returns a pathname to a directory which [Artifact] is expected to
// write its output to. This is not the final resting place of the [Artifact]
// and this pathname should not be directly referred to in the final contents.
@@ -552,6 +556,8 @@ type Cache struct {
base *check.Absolute
// Immutable cure options set by [Open].
flags int
+ // Immutable job count, when applicable.
+ jobs int
// Artifact to [unique.Handle] of identifier cache.
artifact sync.Map
@@ -1818,7 +1824,7 @@ func (c *Cache) Close() {
// caller-supplied value, however direct calls to [Cache.Cure] is not subject
// to this limitation.
//
-// A cures value of 0 or lower is equivalent to the value returned by
+// A cures or jobs value of 0 or lower is equivalent to the value returned by
// [runtime.NumCPU].
//
// A successful call to Open guarantees exclusive access to the on-filesystem
@@ -1828,10 +1834,10 @@ func (c *Cache) Close() {
func Open(
ctx context.Context,
msg message.Msg,
- flags, cures int,
+ flags, cures, jobs int,
base *check.Absolute,
) (*Cache, error) {
- return open(ctx, msg, flags, cures, base, true)
+ return open(ctx, msg, flags, cures, jobs, base, true)
}
// open implements Open but allows omitting the [lockedfile] lock when called
@@ -1839,13 +1845,16 @@ func Open(
func open(
ctx context.Context,
msg message.Msg,
- flags, cures int,
+ flags, cures, jobs int,
base *check.Absolute,
lock bool,
) (*Cache, error) {
if cures < 1 {
cures = runtime.NumCPU()
}
+ if jobs < 1 {
+ jobs = runtime.NumCPU()
+ }
for _, name := range []string{
dirIdentifier,
@@ -1862,6 +1871,7 @@ func open(
c := Cache{
cures: make(chan struct{}, cures),
flags: flags,
+ jobs: jobs,
msg: msg,
base: base,
diff --git a/internal/pkg/pkg_test.go b/internal/pkg/pkg_test.go
index b2a5dfbc..387f7b31 100644
--- a/internal/pkg/pkg_test.go
+++ b/internal/pkg/pkg_test.go
@@ -35,7 +35,7 @@ import (
func unsafeOpen(
ctx context.Context,
msg message.Msg,
- flags, cures int,
+ flags, cures, jobs int,
base *check.Absolute,
lock bool,
) (*pkg.Cache, error)
@@ -230,7 +230,7 @@ func TestIdent(t *testing.T) {
var cache *pkg.Cache
if a, err := check.NewAbs(t.TempDir()); err != nil {
t.Fatal(err)
- } else if cache, err = pkg.Open(t.Context(), msg, 0, 0, a); err != nil {
+ } else if cache, err = pkg.Open(t.Context(), msg, 0, 0, 0, a); err != nil {
t.Fatal(err)
}
t.Cleanup(cache.Close)
@@ -304,7 +304,7 @@ func checkWithCache(t *testing.T, testCases []cacheTestCase) {
}
var scrubFunc func() error // scrub after hashing
- if c, err := pkg.Open(t.Context(), msg, flags, 1<<4, base); err != nil {
+ if c, err := pkg.Open(t.Context(), msg, flags, 1<<4, 0, base); err != nil {
t.Fatalf("Open: error = %v", err)
} else {
t.Cleanup(c.Close)
@@ -606,7 +606,7 @@ func TestCache(t *testing.T) {
if c0, err := unsafeOpen(
t.Context(),
message.New(nil),
- 0, 0, base, false,
+ 0, 0, 0, base, false,
); err != nil {
t.Fatalf("open: error = %v", err)
} else {
@@ -1263,7 +1263,7 @@ func TestNew(t *testing.T) {
if _, err := pkg.Open(
t.Context(),
message.New(nil),
- 0, 0, check.MustAbs(container.Nonexistent),
+ 0, 0, 0, check.MustAbs(container.Nonexistent),
); !reflect.DeepEqual(err, wantErr) {
t.Errorf("Open: error = %#v, want %#v", err, wantErr)
}
@@ -1291,7 +1291,7 @@ func TestNew(t *testing.T) {
if _, err := pkg.Open(
t.Context(),
message.New(nil),
- 0, 0, tempDir.Append("cache"),
+ 0, 0, 0, tempDir.Append("cache"),
); !reflect.DeepEqual(err, wantErr) {
t.Errorf("Open: error = %#v, want %#v", err, wantErr)
}
diff --git a/internal/rosa/rosa_test.go b/internal/rosa/rosa_test.go
index fd92547c..0386aee7 100644
--- a/internal/rosa/rosa_test.go
+++ b/internal/rosa/rosa_test.go
@@ -60,7 +60,7 @@ func getCache(t *testing.T) *pkg.Cache {
msg := message.New(log.New(os.Stderr, "rosa: ", 0))
msg.SwapVerbose(true)
- if buildTestCache, err = pkg.Open(ctx, msg, 0, 0, a); err != nil {
+ if buildTestCache, err = pkg.Open(ctx, msg, 0, 0, 0, a); err != nil {
t.Fatal(err)
}
}