mirror of
https://github.com/kopia/kopia.git
synced 2026-07-10 21:56:36 -04:00
- upgrade to golangci-lint 2.6.1 - updates for gosec - updates for govet - updates for perfsprint - updates modernize Leaves out modernize:omitempty due to conflicts with tests
135 lines
3.7 KiB
Go
135 lines
3.7 KiB
Go
//go:build darwin || (linux && amd64)
|
|
|
|
package framework
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"sync"
|
|
|
|
"github.com/kopia/kopia/tests/robustness"
|
|
)
|
|
|
|
// MultiClientFileWriter manages a set of client FileWriter instances and
|
|
// implements the FileWriter interface itself. FileWriter methods must be
|
|
// provided with a client-wrapped context so the MultiClientFileWriter can
|
|
// delegate to a specific client FileWriter.
|
|
type MultiClientFileWriter struct {
|
|
// Map of client ID to FileWriter and associated mutex
|
|
mu sync.RWMutex
|
|
|
|
// +checklocks:mu
|
|
fileWriters map[string]FileWriter
|
|
|
|
// Function used to generate new FileWriters
|
|
newFileWriter newFileWriterFn
|
|
}
|
|
|
|
// MultiClientFileWriter implements robustness.FileWriter.
|
|
var _ robustness.FileWriter = (*MultiClientFileWriter)(nil)
|
|
|
|
type newFileWriterFn func() (FileWriter, error)
|
|
|
|
// NewMultiClientFileWriter returns a MultiClientFileWriter that is responsible
|
|
// for delegating FileWriter method calls to a specific client's FileWriter instance.
|
|
func NewMultiClientFileWriter(f newFileWriterFn) *MultiClientFileWriter {
|
|
return &MultiClientFileWriter{
|
|
newFileWriter: f,
|
|
fileWriters: map[string]FileWriter{},
|
|
}
|
|
}
|
|
|
|
// DataDirectory delegates to a specific client's FileWriter.
|
|
func (mcfw *MultiClientFileWriter) DataDirectory(ctx context.Context) string {
|
|
fw, err := mcfw.createOrGetFileWriter(ctx)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
|
|
return fw.DataDirectory(ctx)
|
|
}
|
|
|
|
// WriteRandomFiles delegates to a specific client's FileWriter.
|
|
func (mcfw *MultiClientFileWriter) WriteRandomFiles(ctx context.Context, opts map[string]string) (map[string]string, error) {
|
|
fw, err := mcfw.createOrGetFileWriter(ctx)
|
|
if err != nil {
|
|
return opts, err
|
|
}
|
|
|
|
return fw.WriteRandomFiles(ctx, opts)
|
|
}
|
|
|
|
// DeleteRandomSubdirectory delegates to a specific client's FileWriter.
|
|
func (mcfw *MultiClientFileWriter) DeleteRandomSubdirectory(ctx context.Context, opts map[string]string) (map[string]string, error) {
|
|
fw, err := mcfw.createOrGetFileWriter(ctx)
|
|
if err != nil {
|
|
return opts, err
|
|
}
|
|
|
|
return fw.DeleteRandomSubdirectory(ctx, opts)
|
|
}
|
|
|
|
// DeleteDirectoryContents delegates to a specific client's FileWriter.
|
|
func (mcfw *MultiClientFileWriter) DeleteDirectoryContents(ctx context.Context, opts map[string]string) (map[string]string, error) {
|
|
fw, err := mcfw.createOrGetFileWriter(ctx)
|
|
if err != nil {
|
|
return opts, err
|
|
}
|
|
|
|
return fw.DeleteDirectoryContents(ctx, opts)
|
|
}
|
|
|
|
// DeleteEverything delegates to a specific client's FileWriter.
|
|
func (mcfw *MultiClientFileWriter) DeleteEverything(ctx context.Context) error {
|
|
fw, err := mcfw.createOrGetFileWriter(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return fw.DeleteEverything(ctx)
|
|
}
|
|
|
|
// Cleanup delegates to a specific client's FileWriter for cleanup and removes
|
|
// the client FileWriter instance from the MultiClientFileWriter.
|
|
func (mcfw *MultiClientFileWriter) Cleanup() {
|
|
mcfw.mu.Lock()
|
|
defer mcfw.mu.Unlock()
|
|
|
|
for clientID, fw := range mcfw.fileWriters {
|
|
fw.Cleanup()
|
|
delete(mcfw.fileWriters, clientID)
|
|
}
|
|
}
|
|
|
|
// createOrGetFileWriter gets a client's FileWriter from the given context if
|
|
// possible or creates a new FileWriter.
|
|
func (mcfw *MultiClientFileWriter) createOrGetFileWriter(ctx context.Context) (robustness.FileWriter, error) {
|
|
c := UnwrapContext(ctx)
|
|
if c == nil {
|
|
log.Println("Context does not contain a client")
|
|
return nil, robustness.ErrKeyNotFound
|
|
}
|
|
|
|
// Get existing FileWriter if available
|
|
mcfw.mu.RLock()
|
|
fw, ok := mcfw.fileWriters[c.ID]
|
|
mcfw.mu.RUnlock()
|
|
|
|
if ok {
|
|
return fw, nil
|
|
}
|
|
|
|
// Create new FileWriter and register with MultiClientFileWriter
|
|
fw, err := mcfw.newFileWriter()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
mcfw.mu.Lock()
|
|
defer mcfw.mu.Unlock()
|
|
|
|
mcfw.fileWriters[c.ID] = fw
|
|
|
|
return fw, nil
|
|
}
|