diff --git a/pkg/bass/cache_path.go b/pkg/bass/cache_path.go index 124e5a46..c7dada3a 100644 --- a/pkg/bass/cache_path.go +++ b/pkg/bass/cache_path.go @@ -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(".")) } @@ -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) } diff --git a/pkg/bass/ground.go b/pkg/bass/ground.go index d625fa7f..a39bb703 100644 --- a/pkg/bass/ground.go +++ b/pkg/bass/ground.go @@ -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), diff --git a/pkg/bass/proto.go b/pkg/bass/proto.go index 533dfecd..c5a8b7d6 100644 --- a/pkg/bass/proto.go +++ b/pkg/bass/proto.go @@ -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{} @@ -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() diff --git a/pkg/proto/bass.pb.go b/pkg/proto/bass.pb.go index e75091b6..e590648c 100644 --- a/pkg/proto/bass.pb.go +++ b/pkg/proto/bass.pb.go @@ -20,6 +20,55 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type ConcurrencyMode int32 + +const ( + ConcurrencyMode_CONCURRENCY_MODE_SHARED ConcurrencyMode = 0 + ConcurrencyMode_CONCURRENCY_MODE_PRIVATE ConcurrencyMode = 1 + ConcurrencyMode_CONCURRENCY_MODE_LOCKED ConcurrencyMode = 2 +) + +// Enum value maps for ConcurrencyMode. +var ( + ConcurrencyMode_name = map[int32]string{ + 0: "CONCURRENCY_MODE_SHARED", + 1: "CONCURRENCY_MODE_PRIVATE", + 2: "CONCURRENCY_MODE_LOCKED", + } + ConcurrencyMode_value = map[string]int32{ + "CONCURRENCY_MODE_SHARED": 0, + "CONCURRENCY_MODE_PRIVATE": 1, + "CONCURRENCY_MODE_LOCKED": 2, + } +) + +func (x ConcurrencyMode) Enum() *ConcurrencyMode { + p := new(ConcurrencyMode) + *p = x + return p +} + +func (x ConcurrencyMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ConcurrencyMode) Descriptor() protoreflect.EnumDescriptor { + return file_bass_proto_enumTypes[0].Descriptor() +} + +func (ConcurrencyMode) Type() protoreflect.EnumType { + return &file_bass_proto_enumTypes[0] +} + +func (x ConcurrencyMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ConcurrencyMode.Descriptor instead. +func (ConcurrencyMode) EnumDescriptor() ([]byte, []int) { + return file_bass_proto_rawDescGZIP(), []int{0} +} + type Value struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1812,8 +1861,9 @@ type CachePath struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Path *FilesystemPath `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Path *FilesystemPath `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + Concurrency ConcurrencyMode `protobuf:"varint,3,opt,name=concurrency,proto3,enum=bass.ConcurrencyMode" json:"concurrency,omitempty"` } func (x *CachePath) Reset() { @@ -1862,6 +1912,13 @@ func (x *CachePath) GetPath() *FilesystemPath { return nil } +func (x *CachePath) GetConcurrency() ConcurrencyMode { + if x != nil { + return x.Concurrency + } + return ConcurrencyMode_CONCURRENCY_MODE_SHARED +} + type Secret struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2644,53 +2701,63 @@ var file_bass_proto_rawDesc = []byte{ 0x65, 0x22, 0x1b, 0x0a, 0x03, 0x49, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x1e, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x45, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x7e, 0x0a, 0x09, 0x43, 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x28, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x52, - 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x1c, 0x0a, 0x06, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x22, 0x21, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x61, - 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x1e, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61, - 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x1d, 0x0a, 0x07, 0x44, 0x69, 0x72, 0x50, 0x61, 0x74, - 0x68, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x61, 0x0a, 0x0e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, - 0x74, 0x65, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x12, 0x24, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, - 0x65, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x21, 0x0a, - 0x03, 0x64, 0x69, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x62, 0x61, 0x73, - 0x73, 0x2e, 0x44, 0x69, 0x72, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, 0x52, 0x03, 0x64, 0x69, 0x72, - 0x42, 0x06, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x58, 0x0a, 0x09, 0x54, 0x68, 0x75, 0x6e, - 0x6b, 0x50, 0x61, 0x74, 0x68, 0x12, 0x21, 0x0a, 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, - 0x6b, 0x52, 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x12, 0x28, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, - 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x22, 0x4e, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, - 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x28, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, - 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x22, 0xec, 0x01, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, - 0x74, 0x68, 0x12, 0x2c, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x16, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, - 0x61, 0x74, 0x68, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, - 0x12, 0x29, 0x0a, 0x03, 0x64, 0x69, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x62, 0x61, 0x73, 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, - 0x2e, 0x44, 0x69, 0x72, 0x48, 0x00, 0x52, 0x03, 0x64, 0x69, 0x72, 0x1a, 0x34, 0x0a, 0x04, 0x46, - 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x1a, 0x46, 0x0a, 0x03, 0x44, 0x69, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x07, - 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, - 0x62, 0x61, 0x73, 0x73, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, - 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x70, 0x61, 0x74, - 0x68, 0x42, 0x0b, 0x5a, 0x09, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x37, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x62, 0x61, 0x73, + 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x6f, 0x64, + 0x65, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x1c, + 0x0a, 0x06, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x21, 0x0a, 0x0b, + 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, + 0x1e, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x70, + 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, + 0x1d, 0x0a, 0x07, 0x44, 0x69, 0x72, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, + 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x61, + 0x0a, 0x0e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x61, 0x74, 0x68, + 0x12, 0x24, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, + 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x48, 0x00, + 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x21, 0x0a, 0x03, 0x64, 0x69, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x44, 0x69, 0x72, 0x50, 0x61, + 0x74, 0x68, 0x48, 0x00, 0x52, 0x03, 0x64, 0x69, 0x72, 0x42, 0x06, 0x0a, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x22, 0x58, 0x0a, 0x09, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x50, 0x61, 0x74, 0x68, 0x12, 0x21, + 0x0a, 0x05, 0x74, 0x68, 0x75, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, + 0x62, 0x61, 0x73, 0x73, 0x2e, 0x54, 0x68, 0x75, 0x6e, 0x6b, 0x52, 0x05, 0x74, 0x68, 0x75, 0x6e, + 0x6b, 0x12, 0x28, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x4e, 0x0a, 0x08, 0x48, + 0x6f, 0x73, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x12, 0x28, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0xec, 0x01, 0x0a, 0x0b, + 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2c, 0x0a, 0x04, 0x66, + 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x61, 0x73, 0x73, + 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x2e, 0x46, 0x69, 0x6c, + 0x65, 0x48, 0x00, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x29, 0x0a, 0x03, 0x64, 0x69, 0x72, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x4c, 0x6f, + 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x2e, 0x44, 0x69, 0x72, 0x48, 0x00, 0x52, + 0x03, 0x64, 0x69, 0x72, 0x1a, 0x34, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x1a, 0x46, 0x0a, 0x03, 0x44, 0x69, + 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x61, 0x73, 0x73, 0x2e, 0x4c, 0x6f, + 0x67, 0x69, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, + 0x65, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x2a, 0x69, 0x0a, 0x0f, 0x43, 0x6f, + 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, + 0x17, 0x43, 0x4f, 0x4e, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x4d, 0x4f, 0x44, + 0x45, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, + 0x4e, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x50, + 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4e, 0x43, + 0x55, 0x52, 0x52, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x4c, 0x4f, 0x43, + 0x4b, 0x45, 0x44, 0x10, 0x02, 0x42, 0x0b, 0x5a, 0x09, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2705,113 +2772,116 @@ func file_bass_proto_rawDescGZIP() []byte { return file_bass_proto_rawDescData } +var file_bass_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_bass_proto_msgTypes = make([]protoimpl.MessageInfo, 33) var file_bass_proto_goTypes = []interface{}{ - (*Value)(nil), // 0: bass.Value - (*Thunk)(nil), // 1: bass.Thunk - (*ThunkAddr)(nil), // 2: bass.ThunkAddr - (*ThunkPort)(nil), // 3: bass.ThunkPort - (*ThunkTLS)(nil), // 4: bass.ThunkTLS - (*ThunkImage)(nil), // 5: bass.ThunkImage - (*ImageRef)(nil), // 6: bass.ImageRef - (*ImageArchive)(nil), // 7: bass.ImageArchive - (*ImageDockerBuild)(nil), // 8: bass.ImageDockerBuild - (*ImageBuildInput)(nil), // 9: bass.ImageBuildInput - (*BuildArg)(nil), // 10: bass.BuildArg - (*Platform)(nil), // 11: bass.Platform - (*ThunkDir)(nil), // 12: bass.ThunkDir - (*ThunkMountSource)(nil), // 13: bass.ThunkMountSource - (*ThunkMount)(nil), // 14: bass.ThunkMount - (*Array)(nil), // 15: bass.Array - (*Object)(nil), // 16: bass.Object - (*Binding)(nil), // 17: bass.Binding - (*Null)(nil), // 18: bass.Null - (*Bool)(nil), // 19: bass.Bool - (*Int)(nil), // 20: bass.Int - (*String)(nil), // 21: bass.String - (*CachePath)(nil), // 22: bass.CachePath - (*Secret)(nil), // 23: bass.Secret - (*CommandPath)(nil), // 24: bass.CommandPath - (*FilePath)(nil), // 25: bass.FilePath - (*DirPath)(nil), // 26: bass.DirPath - (*FilesystemPath)(nil), // 27: bass.FilesystemPath - (*ThunkPath)(nil), // 28: bass.ThunkPath - (*HostPath)(nil), // 29: bass.HostPath - (*LogicalPath)(nil), // 30: bass.LogicalPath - (*LogicalPath_File)(nil), // 31: bass.LogicalPath.File - (*LogicalPath_Dir)(nil), // 32: bass.LogicalPath.Dir + (ConcurrencyMode)(0), // 0: bass.ConcurrencyMode + (*Value)(nil), // 1: bass.Value + (*Thunk)(nil), // 2: bass.Thunk + (*ThunkAddr)(nil), // 3: bass.ThunkAddr + (*ThunkPort)(nil), // 4: bass.ThunkPort + (*ThunkTLS)(nil), // 5: bass.ThunkTLS + (*ThunkImage)(nil), // 6: bass.ThunkImage + (*ImageRef)(nil), // 7: bass.ImageRef + (*ImageArchive)(nil), // 8: bass.ImageArchive + (*ImageDockerBuild)(nil), // 9: bass.ImageDockerBuild + (*ImageBuildInput)(nil), // 10: bass.ImageBuildInput + (*BuildArg)(nil), // 11: bass.BuildArg + (*Platform)(nil), // 12: bass.Platform + (*ThunkDir)(nil), // 13: bass.ThunkDir + (*ThunkMountSource)(nil), // 14: bass.ThunkMountSource + (*ThunkMount)(nil), // 15: bass.ThunkMount + (*Array)(nil), // 16: bass.Array + (*Object)(nil), // 17: bass.Object + (*Binding)(nil), // 18: bass.Binding + (*Null)(nil), // 19: bass.Null + (*Bool)(nil), // 20: bass.Bool + (*Int)(nil), // 21: bass.Int + (*String)(nil), // 22: bass.String + (*CachePath)(nil), // 23: bass.CachePath + (*Secret)(nil), // 24: bass.Secret + (*CommandPath)(nil), // 25: bass.CommandPath + (*FilePath)(nil), // 26: bass.FilePath + (*DirPath)(nil), // 27: bass.DirPath + (*FilesystemPath)(nil), // 28: bass.FilesystemPath + (*ThunkPath)(nil), // 29: bass.ThunkPath + (*HostPath)(nil), // 30: bass.HostPath + (*LogicalPath)(nil), // 31: bass.LogicalPath + (*LogicalPath_File)(nil), // 32: bass.LogicalPath.File + (*LogicalPath_Dir)(nil), // 33: bass.LogicalPath.Dir } var file_bass_proto_depIdxs = []int32{ - 18, // 0: bass.Value.null:type_name -> bass.Null - 19, // 1: bass.Value.bool:type_name -> bass.Bool - 20, // 2: bass.Value.int:type_name -> bass.Int - 21, // 3: bass.Value.string:type_name -> bass.String - 23, // 4: bass.Value.secret:type_name -> bass.Secret - 15, // 5: bass.Value.array:type_name -> bass.Array - 16, // 6: bass.Value.object:type_name -> bass.Object - 1, // 7: bass.Value.thunk:type_name -> bass.Thunk - 24, // 8: bass.Value.command_path:type_name -> bass.CommandPath - 25, // 9: bass.Value.file_path:type_name -> bass.FilePath - 26, // 10: bass.Value.dir_path:type_name -> bass.DirPath - 29, // 11: bass.Value.host_path:type_name -> bass.HostPath - 28, // 12: bass.Value.thunk_path:type_name -> bass.ThunkPath - 30, // 13: bass.Value.logical_path:type_name -> bass.LogicalPath - 2, // 14: bass.Value.thunk_addr:type_name -> bass.ThunkAddr - 22, // 15: bass.Value.cache_path:type_name -> bass.CachePath - 5, // 16: bass.Thunk.image:type_name -> bass.ThunkImage - 0, // 17: bass.Thunk.args:type_name -> bass.Value - 0, // 18: bass.Thunk.stdin:type_name -> bass.Value - 17, // 19: bass.Thunk.env:type_name -> bass.Binding - 12, // 20: bass.Thunk.dir:type_name -> bass.ThunkDir - 14, // 21: bass.Thunk.mounts:type_name -> bass.ThunkMount - 17, // 22: bass.Thunk.labels:type_name -> bass.Binding - 3, // 23: bass.Thunk.ports:type_name -> bass.ThunkPort - 4, // 24: bass.Thunk.tls:type_name -> bass.ThunkTLS - 1, // 25: bass.ThunkAddr.thunk:type_name -> bass.Thunk - 25, // 26: bass.ThunkTLS.cert:type_name -> bass.FilePath - 25, // 27: bass.ThunkTLS.key:type_name -> bass.FilePath - 6, // 28: bass.ThunkImage.ref:type_name -> bass.ImageRef - 1, // 29: bass.ThunkImage.thunk:type_name -> bass.Thunk - 7, // 30: bass.ThunkImage.archive:type_name -> bass.ImageArchive - 8, // 31: bass.ThunkImage.docker_build:type_name -> bass.ImageDockerBuild - 11, // 32: bass.ImageRef.platform:type_name -> bass.Platform - 28, // 33: bass.ImageRef.file:type_name -> bass.ThunkPath - 2, // 34: bass.ImageRef.addr:type_name -> bass.ThunkAddr - 11, // 35: bass.ImageArchive.platform:type_name -> bass.Platform - 28, // 36: bass.ImageArchive.file:type_name -> bass.ThunkPath - 11, // 37: bass.ImageDockerBuild.platform:type_name -> bass.Platform - 9, // 38: bass.ImageDockerBuild.context:type_name -> bass.ImageBuildInput - 10, // 39: bass.ImageDockerBuild.args:type_name -> bass.BuildArg - 28, // 40: bass.ImageBuildInput.thunk:type_name -> bass.ThunkPath - 29, // 41: bass.ImageBuildInput.host:type_name -> bass.HostPath - 30, // 42: bass.ImageBuildInput.logical:type_name -> bass.LogicalPath - 26, // 43: bass.ThunkDir.local:type_name -> bass.DirPath - 28, // 44: bass.ThunkDir.thunk:type_name -> bass.ThunkPath - 29, // 45: bass.ThunkDir.host:type_name -> bass.HostPath - 28, // 46: bass.ThunkMountSource.thunk:type_name -> bass.ThunkPath - 29, // 47: bass.ThunkMountSource.host:type_name -> bass.HostPath - 30, // 48: bass.ThunkMountSource.logical:type_name -> bass.LogicalPath - 22, // 49: bass.ThunkMountSource.cache:type_name -> bass.CachePath - 23, // 50: bass.ThunkMountSource.secret:type_name -> bass.Secret - 13, // 51: bass.ThunkMount.source:type_name -> bass.ThunkMountSource - 27, // 52: bass.ThunkMount.target:type_name -> bass.FilesystemPath - 0, // 53: bass.Array.values:type_name -> bass.Value - 17, // 54: bass.Object.bindings:type_name -> bass.Binding - 0, // 55: bass.Binding.value:type_name -> bass.Value - 27, // 56: bass.CachePath.path:type_name -> bass.FilesystemPath - 25, // 57: bass.FilesystemPath.file:type_name -> bass.FilePath - 26, // 58: bass.FilesystemPath.dir:type_name -> bass.DirPath - 1, // 59: bass.ThunkPath.thunk:type_name -> bass.Thunk - 27, // 60: bass.ThunkPath.path:type_name -> bass.FilesystemPath - 27, // 61: bass.HostPath.path:type_name -> bass.FilesystemPath - 31, // 62: bass.LogicalPath.file:type_name -> bass.LogicalPath.File - 32, // 63: bass.LogicalPath.dir:type_name -> bass.LogicalPath.Dir - 30, // 64: bass.LogicalPath.Dir.entries:type_name -> bass.LogicalPath - 65, // [65:65] is the sub-list for method output_type - 65, // [65:65] is the sub-list for method input_type - 65, // [65:65] is the sub-list for extension type_name - 65, // [65:65] is the sub-list for extension extendee - 0, // [0:65] is the sub-list for field type_name + 19, // 0: bass.Value.null:type_name -> bass.Null + 20, // 1: bass.Value.bool:type_name -> bass.Bool + 21, // 2: bass.Value.int:type_name -> bass.Int + 22, // 3: bass.Value.string:type_name -> bass.String + 24, // 4: bass.Value.secret:type_name -> bass.Secret + 16, // 5: bass.Value.array:type_name -> bass.Array + 17, // 6: bass.Value.object:type_name -> bass.Object + 2, // 7: bass.Value.thunk:type_name -> bass.Thunk + 25, // 8: bass.Value.command_path:type_name -> bass.CommandPath + 26, // 9: bass.Value.file_path:type_name -> bass.FilePath + 27, // 10: bass.Value.dir_path:type_name -> bass.DirPath + 30, // 11: bass.Value.host_path:type_name -> bass.HostPath + 29, // 12: bass.Value.thunk_path:type_name -> bass.ThunkPath + 31, // 13: bass.Value.logical_path:type_name -> bass.LogicalPath + 3, // 14: bass.Value.thunk_addr:type_name -> bass.ThunkAddr + 23, // 15: bass.Value.cache_path:type_name -> bass.CachePath + 6, // 16: bass.Thunk.image:type_name -> bass.ThunkImage + 1, // 17: bass.Thunk.args:type_name -> bass.Value + 1, // 18: bass.Thunk.stdin:type_name -> bass.Value + 18, // 19: bass.Thunk.env:type_name -> bass.Binding + 13, // 20: bass.Thunk.dir:type_name -> bass.ThunkDir + 15, // 21: bass.Thunk.mounts:type_name -> bass.ThunkMount + 18, // 22: bass.Thunk.labels:type_name -> bass.Binding + 4, // 23: bass.Thunk.ports:type_name -> bass.ThunkPort + 5, // 24: bass.Thunk.tls:type_name -> bass.ThunkTLS + 2, // 25: bass.ThunkAddr.thunk:type_name -> bass.Thunk + 26, // 26: bass.ThunkTLS.cert:type_name -> bass.FilePath + 26, // 27: bass.ThunkTLS.key:type_name -> bass.FilePath + 7, // 28: bass.ThunkImage.ref:type_name -> bass.ImageRef + 2, // 29: bass.ThunkImage.thunk:type_name -> bass.Thunk + 8, // 30: bass.ThunkImage.archive:type_name -> bass.ImageArchive + 9, // 31: bass.ThunkImage.docker_build:type_name -> bass.ImageDockerBuild + 12, // 32: bass.ImageRef.platform:type_name -> bass.Platform + 29, // 33: bass.ImageRef.file:type_name -> bass.ThunkPath + 3, // 34: bass.ImageRef.addr:type_name -> bass.ThunkAddr + 12, // 35: bass.ImageArchive.platform:type_name -> bass.Platform + 29, // 36: bass.ImageArchive.file:type_name -> bass.ThunkPath + 12, // 37: bass.ImageDockerBuild.platform:type_name -> bass.Platform + 10, // 38: bass.ImageDockerBuild.context:type_name -> bass.ImageBuildInput + 11, // 39: bass.ImageDockerBuild.args:type_name -> bass.BuildArg + 29, // 40: bass.ImageBuildInput.thunk:type_name -> bass.ThunkPath + 30, // 41: bass.ImageBuildInput.host:type_name -> bass.HostPath + 31, // 42: bass.ImageBuildInput.logical:type_name -> bass.LogicalPath + 27, // 43: bass.ThunkDir.local:type_name -> bass.DirPath + 29, // 44: bass.ThunkDir.thunk:type_name -> bass.ThunkPath + 30, // 45: bass.ThunkDir.host:type_name -> bass.HostPath + 29, // 46: bass.ThunkMountSource.thunk:type_name -> bass.ThunkPath + 30, // 47: bass.ThunkMountSource.host:type_name -> bass.HostPath + 31, // 48: bass.ThunkMountSource.logical:type_name -> bass.LogicalPath + 23, // 49: bass.ThunkMountSource.cache:type_name -> bass.CachePath + 24, // 50: bass.ThunkMountSource.secret:type_name -> bass.Secret + 14, // 51: bass.ThunkMount.source:type_name -> bass.ThunkMountSource + 28, // 52: bass.ThunkMount.target:type_name -> bass.FilesystemPath + 1, // 53: bass.Array.values:type_name -> bass.Value + 18, // 54: bass.Object.bindings:type_name -> bass.Binding + 1, // 55: bass.Binding.value:type_name -> bass.Value + 28, // 56: bass.CachePath.path:type_name -> bass.FilesystemPath + 0, // 57: bass.CachePath.concurrency:type_name -> bass.ConcurrencyMode + 26, // 58: bass.FilesystemPath.file:type_name -> bass.FilePath + 27, // 59: bass.FilesystemPath.dir:type_name -> bass.DirPath + 2, // 60: bass.ThunkPath.thunk:type_name -> bass.Thunk + 28, // 61: bass.ThunkPath.path:type_name -> bass.FilesystemPath + 28, // 62: bass.HostPath.path:type_name -> bass.FilesystemPath + 32, // 63: bass.LogicalPath.file:type_name -> bass.LogicalPath.File + 33, // 64: bass.LogicalPath.dir:type_name -> bass.LogicalPath.Dir + 31, // 65: bass.LogicalPath.Dir.entries:type_name -> bass.LogicalPath + 66, // [66:66] is the sub-list for method output_type + 66, // [66:66] is the sub-list for method input_type + 66, // [66:66] is the sub-list for extension type_name + 66, // [66:66] is the sub-list for extension extendee + 0, // [0:66] is the sub-list for field type_name } func init() { file_bass_proto_init() } @@ -3278,13 +3348,14 @@ func file_bass_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_bass_proto_rawDesc, - NumEnums: 0, + NumEnums: 1, NumMessages: 33, NumExtensions: 0, NumServices: 0, }, GoTypes: file_bass_proto_goTypes, DependencyIndexes: file_bass_proto_depIdxs, + EnumInfos: file_bass_proto_enumTypes, MessageInfos: file_bass_proto_msgTypes, }.Build() File_bass_proto = out.File diff --git a/pkg/runtimes/buildkit.go b/pkg/runtimes/buildkit.go index 5755c4ef..ed50712c 100644 --- a/pkg/runtimes/buildkit.go +++ b/pkg/runtimes/buildkit.go @@ -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 diff --git a/pkg/runtimes/dagger.go b/pkg/runtimes/dagger.go index 03c29186..d9105e5b 100644 --- a/pkg/runtimes/dagger.go +++ b/pkg/runtimes/dagger.go @@ -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: diff --git a/pkg/runtimes/suite.go b/pkg/runtimes/suite.go index 355a684a..5a15986b 100644 --- a/pkg/runtimes/suite.go +++ b/pkg/runtimes/suite.go @@ -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", diff --git a/pkg/runtimes/testdata/cache-sync.bass b/pkg/runtimes/testdata/cache-sync.bass index 0e0805d5..21cefdac 100644 --- a/pkg/runtimes/testdata/cache-sync.bass +++ b/pkg/runtimes/testdata/cache-sync.bass @@ -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 @@ -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")) diff --git a/proto/bass.proto b/proto/bass.proto index eb6d580d..dc86a675 100644 --- a/proto/bass.proto +++ b/proto/bass.proto @@ -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 {