97 lines
2.6 KiB
Go
97 lines
2.6 KiB
Go
// Copyright (C) 2019 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package testblobs
|
|
|
|
import (
|
|
"context"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
"storj.io/storj/storage"
|
|
"storj.io/storj/storagenode"
|
|
)
|
|
|
|
// SlowDB implements slow storage node DB.
|
|
type SlowDB struct {
|
|
storagenode.DB
|
|
blobs *SlowBlobs
|
|
log *zap.Logger
|
|
}
|
|
|
|
// NewSlowDB creates a new slow storage node DB wrapping the provided db.
|
|
// Use SetLatency to dynamically configure the latency of all piece operations.
|
|
func NewSlowDB(log *zap.Logger, db storagenode.DB) *SlowDB {
|
|
return &SlowDB{
|
|
DB: db,
|
|
blobs: NewSlowBlobs(log, db.Pieces()),
|
|
log: log,
|
|
}
|
|
}
|
|
|
|
// Pieces returns the blob store.
|
|
func (slow *SlowDB) Pieces() storage.Blobs {
|
|
return slow.blobs
|
|
}
|
|
|
|
// SetLatency enables a sleep for delay duration for all piece operations.
|
|
// A zero or negative delay means no sleep.
|
|
func (slow *SlowDB) SetLatency(delay time.Duration) {
|
|
slow.blobs.SetLatency(delay)
|
|
}
|
|
|
|
// SlowBlobs implements a slow blob store.
|
|
type SlowBlobs struct {
|
|
delay int64 // time.Duration
|
|
blobs storage.Blobs
|
|
log *zap.Logger
|
|
}
|
|
|
|
// NewSlowBlobs creates a new slow blob store wrapping the provided blobs.
|
|
// Use SetLatency to dynamically configure the latency of all operations.
|
|
func NewSlowBlobs(log *zap.Logger, blobs storage.Blobs) *SlowBlobs {
|
|
return &SlowBlobs{
|
|
log: log,
|
|
blobs: blobs,
|
|
}
|
|
}
|
|
|
|
// Create creates a new blob that can be written optionally takes a size
|
|
// argument for performance improvements, -1 is unknown size.
|
|
func (slow *SlowBlobs) Create(ctx context.Context, ref storage.BlobRef, size int64) (storage.BlobWriter, error) {
|
|
slow.sleep()
|
|
return slow.blobs.Create(ctx, ref, size)
|
|
}
|
|
|
|
// Open opens a reader with the specified namespace and key.
|
|
func (slow *SlowBlobs) Open(ctx context.Context, ref storage.BlobRef) (storage.BlobReader, error) {
|
|
slow.sleep()
|
|
return slow.blobs.Open(ctx, ref)
|
|
}
|
|
|
|
// Delete deletes the blob with the namespace and key.
|
|
func (slow *SlowBlobs) Delete(ctx context.Context, ref storage.BlobRef) error {
|
|
slow.sleep()
|
|
return slow.blobs.Delete(ctx, ref)
|
|
}
|
|
|
|
// FreeSpace return how much free space left for writing.
|
|
func (slow *SlowBlobs) FreeSpace() (int64, error) {
|
|
slow.sleep()
|
|
return slow.blobs.FreeSpace()
|
|
}
|
|
|
|
// SetLatency configures the blob store to sleep for delay duration for all
|
|
// operations. A zero or negative delay means no sleep.
|
|
func (slow *SlowBlobs) SetLatency(delay time.Duration) {
|
|
atomic.StoreInt64(&slow.delay, int64(delay))
|
|
}
|
|
|
|
// sleep sleeps for the duration set to slow.delay
|
|
func (slow *SlowBlobs) sleep() {
|
|
delay := time.Duration(atomic.LoadInt64(&slow.delay))
|
|
time.Sleep(delay)
|
|
}
|