Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions pkg/bass/cache_path.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,22 @@ import (

// CachePath is a Path within an ephemeral directory managed by the runtime.
type CachePath struct {
ID string
Path FileOrDirPath
ID string
ConcurrencyMode ConcurrencyMode
Path FileOrDirPath
}

type ConcurrencyMode int

const (
ConcurrencyModeShared = iota
ConcurrencyModePrivate
ConcurrencyModeLocked
)

var _ Value = CachePath{}

func NewCacheDir(id string) CachePath {
func NewCacheDir(id string, mode ...ConcurrencyMode) CachePath {
return NewCachePath(id, ParseFileOrDirPath("."))
}

Expand Down Expand Up @@ -86,6 +95,7 @@ func (path *CachePath) UnmarshalProto(msg proto.Message) error {
}

path.ID = p.Id
path.ConcurrencyMode = ConcurrencyMode(p.Concurrency)

return path.Path.UnmarshalProto(p.Path)
}
Expand Down
28 changes: 25 additions & 3 deletions pkg/bass/ground.go
Original file line number Diff line number Diff line change
Expand Up @@ -801,9 +801,31 @@ func init() {
)

Ground.Set("cache-dir",
Func("cache-dir", "[id]", NewCacheDir),
`returns a cache directory corresponding to the string identifier`,
`Cache directories may be mounted to thunks. Their content persists across thunk runs.`)
Func("cache-dir", "[id & mode]", func(id string, mode ...Symbol) (CachePath, error) {
cache := NewCacheDir(id)
if len(mode) > 0 {
switch mode[0] {
case "locked":
cache.ConcurrencyMode = ConcurrencyModeLocked
case "private":
cache.ConcurrencyMode = ConcurrencyModePrivate
case "shared":
cache.ConcurrencyMode = ConcurrencyModeShared
default:
return CachePath{}, fmt.Errorf("invalid cache mode: %s", mode[0])
}
}

return cache, nil
}),
`returns a cache directory with the given identifier and concurrency mode`,
`Cache directories may be mounted to thunks. Their content persists across thunk runs.`,
`The :shared concurrency mode allows multiple thunks to run concurrently with the same cache.`,
`The :locked mode allows only one thunk to run at a time with the same cache.`,
`The :private mode creates a new mount for concurrent thunks.`,
`The default mode is :shared.`,
`=> (cache-dir "foo")`,
`=> (cache-dir "foo" :locked)`)

Ground.Set("binds?",
Func("binds?", "[scope sym]", (*Scope).Binds),
Expand Down
8 changes: 5 additions & 3 deletions pkg/bass/proto.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ func FromProto(val *proto.Value) (Value, error) {
}, nil
case *proto.Value_CachePath:
return CachePath{
ID: x.CachePath.Id,
Path: fod(x.CachePath.Path),
ID: x.CachePath.Id,
Path: fod(x.CachePath.Path),
ConcurrencyMode: ConcurrencyMode(x.CachePath.Concurrency),
}, nil
case *proto.Value_LogicalPath:
fsp := &FSPath{}
Expand Down Expand Up @@ -308,7 +309,8 @@ func (value *FSPath) MarshalProto() (proto.Message, error) {

func (value CachePath) MarshalProto() (proto.Message, error) {
pv := &proto.CachePath{
Id: value.ID,
Id: value.ID,
Concurrency: proto.ConcurrencyMode(value.ConcurrencyMode),
}

pathp, err := value.Path.MarshalProto()
Expand Down
369 changes: 220 additions & 149 deletions pkg/proto/bass.pb.go

Large diffs are not rendered by default.

12 changes: 11 additions & 1 deletion pkg/runtimes/buildkit.go
Original file line number Diff line number Diff line change
Expand Up @@ -1312,10 +1312,20 @@ func (b *buildkitBuilder) initializeMount(ctx context.Context, source bass.Thunk
return llb.AddMount(targetPath, st, llb.SourcePath(sp)), sp, false, nil

case source.Cache != nil:
var mode llb.CacheMountSharingMode
switch source.Cache.ConcurrencyMode {
case bass.ConcurrencyModeShared:
mode = llb.CacheMountShared
case bass.ConcurrencyModePrivate:
mode = llb.CacheMountPrivate
case bass.ConcurrencyModeLocked:
mode = llb.CacheMountLocked
}

return llb.AddMount(
targetPath,
llb.Scratch(),
llb.AsPersistentCacheDir(source.Cache.ID, llb.CacheMountLocked),
llb.AsPersistentCacheDir(source.Cache.ID, mode),
llb.SourcePath(source.Cache.Path.FilesystemPath().FromSlash()),
), "", false, nil

Expand Down
12 changes: 11 additions & 1 deletion pkg/runtimes/dagger.go
Original file line number Diff line number Diff line change
Expand Up @@ -413,11 +413,21 @@ func (runtime *Dagger) mount(ctx context.Context, client *dagger.Client, ctr *da
return nil, fmt.Errorf("mounting subpaths of cache not implemented yet: %s", fsp.Slash())
}

var mode dagger.CacheSharingMode
switch src.Cache.ConcurrencyMode {
case bass.ConcurrencyModeShared:
mode = dagger.Shared
case bass.ConcurrencyModePrivate:
mode = dagger.Private
case bass.ConcurrencyModeLocked:
mode = dagger.Locked
}

return ctr.WithMountedCache(
target,
client.CacheVolume(src.Cache.ID),
dagger.ContainerWithMountedCacheOpts{
Sharing: dagger.Locked,
Sharing: mode,
},
), nil
case src.FSPath != nil:
Expand Down
12 changes: 0 additions & 12 deletions pkg/runtimes/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,18 +169,6 @@ func Suite(t *testing.T, runtimeConfig bass.RuntimeConfig, opts ...SuiteOpt) {
},
{
File: "cache-sync.bass",
Result: bass.NewList(
bass.NewList(bass.String("1")),
bass.NewList(bass.String("2")),
bass.NewList(bass.String("3")),
bass.NewList(bass.String("4")),
bass.NewList(bass.String("5")),
bass.NewList(bass.String("6")),
bass.NewList(bass.String("7")),
bass.NewList(bass.String("8")),
bass.NewList(bass.String("9")),
bass.NewList(bass.String("10")),
),
},
{
File: "cache-cmd.bass",
Expand Down
7 changes: 4 additions & 3 deletions pkg/runtimes/testdata/cache-sync.bass
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(def test-cache-path
(cache-dir (str "test-cache-sync-" (now 0))))
(cache-dir (str "test-cache-sync-" (now 0)) :locked))

(defn counter [tag]
(subpath
Expand All @@ -18,7 +18,8 @@
(let [files (map counter tags)]
(-> ($ sh -c "cat $@ | sort -n" ignored & $files)
(with-image (linux/alpine))
(read :unix-table)
(read :lines)
all)))

(counts "a" "b" "c" "d" "e" "f" "g" "h" "i" "j")
(assert = ["1" "2" "3" "4" "5" "6" "7" "8" "9" "10"]
(counts "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"))
7 changes: 7 additions & 0 deletions proto/bass.proto
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ message String {
message CachePath {
string id = 1;
FilesystemPath path = 2;
ConcurrencyMode concurrency = 3;
};

enum ConcurrencyMode {
CONCURRENCY_MODE_SHARED = 0;
CONCURRENCY_MODE_PRIVATE = 1;
CONCURRENCY_MODE_LOCKED = 2;
};

message Secret {
Expand Down