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
12 changes: 10 additions & 2 deletions internal/metadatadb/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type S3BackendConfig struct {
LockTTL time.Duration
}

func NewS3Backend(config S3BackendConfig) *S3Backend {
func NewS3Backend(ctx context.Context, config S3BackendConfig) (*S3Backend, error) {
if config.Prefix == "" {
config.Prefix = "_meta"
}
Expand All @@ -43,13 +43,21 @@ func NewS3Backend(config S3BackendConfig) *S3Backend {
if logger == nil {
logger = slog.Default()
}
exists, err := config.Client.BucketExists(ctx, config.Bucket)
if err != nil {
return nil, errors.Errorf("failed to check if bucket exists: %w", err)
}
if !exists {
return nil, errors.Errorf("bucket %s does not exist", config.Bucket)
}

return &S3Backend{
client: config.Client,
logger: logger,
bucket: config.Bucket,
prefix: config.Prefix,
lockTTL: config.LockTTL,
}
}, nil
}

func (s *S3Backend) stateKey(namespace string) string { return s.prefix + "/" + namespace + ".json" }
Expand Down
13 changes: 10 additions & 3 deletions internal/metadatadb/s3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"testing"
"time"

"github.com/alecthomas/assert/v2"

"github.com/block/cachew/internal/metadatadb"
"github.com/block/cachew/internal/metadatadb/metadatadbtest"
"github.com/block/cachew/internal/s3client/s3clienttest"
Expand All @@ -14,24 +16,29 @@ func TestS3Backend(t *testing.T) {

metadatadbtest.Suite(t, func(t *testing.T) metadatadb.Backend {
t.Helper()
return metadatadb.NewS3Backend(metadatadb.S3BackendConfig{
b, err := metadatadb.NewS3Backend(t.Context(), metadatadb.S3BackendConfig{
Client: s3clienttest.Client(t),
Bucket: bucket,
Prefix: "_meta-" + t.Name(),
LockTTL: 5 * time.Second,
})
assert.NoError(t, err)
return b
})
}

func TestS3BackendSoak(t *testing.T) {
bucket := s3clienttest.Start(t)

metadatadbtest.Soak(t, metadatadb.NewS3Backend(metadatadb.S3BackendConfig{
b, err := metadatadb.NewS3Backend(t.Context(), metadatadb.S3BackendConfig{
Client: s3clienttest.Client(t),
Bucket: bucket,
Prefix: "_meta-soak",
LockTTL: 5 * time.Second,
}), metadatadbtest.SoakConfig{
})
assert.NoError(t, err)

metadatadbtest.Soak(t, b, metadatadbtest.SoakConfig{
Duration: 5 * time.Second,
Concurrency: 4,
NumKeys: 10,
Expand Down
6 changes: 0 additions & 6 deletions internal/s3client/s3client.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,5 @@ func NewClient(ctx context.Context, config Config) (*minio.Client, error) {
return nil, errors.Errorf("failed to create minio client: %w", err)
}

// Verify connectivity and credentials up front so misconfiguration is
// caught at startup rather than on the first cache request.
if _, err := mc.ListBuckets(ctx); err != nil {
return nil, errors.Errorf("failed to connect to S3 endpoint %s: %w", config.Endpoint, err)
}

return mc, nil
}