2019-03-18 10:55:06 +00:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package piecestore
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"io"
|
|
|
|
|
|
|
|
"github.com/zeebo/errs"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
|
2019-12-27 11:48:47 +00:00
|
|
|
"storj.io/common/identity"
|
|
|
|
"storj.io/common/memory"
|
|
|
|
"storj.io/common/pb"
|
|
|
|
"storj.io/common/rpc"
|
|
|
|
"storj.io/common/storj"
|
2019-03-18 10:55:06 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Error is the default error class for piecestore client.
|
|
|
|
var Error = errs.Class("piecestore")
|
|
|
|
|
2019-11-19 15:30:48 +00:00
|
|
|
// Config defines piecestore client parameters for upload and download.
|
2019-03-18 10:55:06 +00:00
|
|
|
type Config struct {
|
|
|
|
UploadBufferSize int64
|
|
|
|
DownloadBufferSize int64
|
|
|
|
|
|
|
|
InitialStep int64
|
|
|
|
MaximumStep int64
|
|
|
|
}
|
|
|
|
|
|
|
|
// DefaultConfig are the default params used for upload and download.
|
|
|
|
var DefaultConfig = Config{
|
|
|
|
UploadBufferSize: 256 * memory.KiB.Int64(),
|
|
|
|
DownloadBufferSize: 256 * memory.KiB.Int64(),
|
|
|
|
|
|
|
|
InitialStep: 64 * memory.KiB.Int64(),
|
|
|
|
MaximumStep: 1 * memory.MiB.Int64(),
|
|
|
|
}
|
|
|
|
|
|
|
|
// Client implements uploading, downloading and deleting content from a piecestore.
|
|
|
|
type Client struct {
|
|
|
|
log *zap.Logger
|
2019-12-22 14:52:55 +00:00
|
|
|
client pb.DRPCPiecestoreClient
|
2019-09-19 05:46:39 +01:00
|
|
|
conn *rpc.Conn
|
2019-03-18 10:55:06 +00:00
|
|
|
config Config
|
|
|
|
}
|
|
|
|
|
2019-06-26 13:14:48 +01:00
|
|
|
// Dial dials the target piecestore endpoint.
|
2019-09-19 05:46:39 +01:00
|
|
|
func Dial(ctx context.Context, dialer rpc.Dialer, target *pb.Node, log *zap.Logger, config Config) (*Client, error) {
|
|
|
|
conn, err := dialer.DialNode(ctx, target)
|
2019-06-26 13:14:48 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, Error.Wrap(err)
|
|
|
|
}
|
|
|
|
|
2019-03-18 10:55:06 +00:00
|
|
|
return &Client{
|
|
|
|
log: log,
|
2019-12-22 15:07:50 +00:00
|
|
|
client: pb.NewDRPCPiecestoreClient(conn.Raw()),
|
2019-06-26 13:14:48 +01:00
|
|
|
conn: conn,
|
2019-03-18 10:55:06 +00:00
|
|
|
config: config,
|
2019-06-26 13:14:48 +01:00
|
|
|
}, nil
|
2019-03-18 10:55:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Delete uses delete order limit to delete a piece on piece store.
|
2019-12-18 15:33:12 +00:00
|
|
|
//
|
|
|
|
// DEPRECATED in favor of DeletePieces.
|
2019-07-11 21:51:40 +01:00
|
|
|
func (client *Client) Delete(ctx context.Context, limit *pb.OrderLimit, privateKey storj.PiecePrivateKey) (err error) {
|
2019-06-05 16:03:11 +01:00
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
_, err = client.client.Delete(ctx, &pb.PieceDeleteRequest{
|
2019-03-18 10:55:06 +00:00
|
|
|
Limit: limit,
|
|
|
|
})
|
|
|
|
return Error.Wrap(err)
|
|
|
|
}
|
|
|
|
|
2019-11-26 17:47:19 +00:00
|
|
|
// DeletePiece deletes a piece.
|
2019-12-18 15:33:12 +00:00
|
|
|
//
|
|
|
|
// DEPRECATED in favor of DeletePieces.
|
2019-11-26 17:47:19 +00:00
|
|
|
func (client *Client) DeletePiece(ctx context.Context, id storj.PieceID) (err error) {
|
|
|
|
defer mon.Task()(&ctx, id.String())(&err)
|
|
|
|
_, err = client.client.DeletePiece(ctx, &pb.PieceDeletePieceRequest{
|
|
|
|
PieceId: id,
|
|
|
|
})
|
|
|
|
return Error.Wrap(err)
|
|
|
|
}
|
|
|
|
|
2019-12-18 15:33:12 +00:00
|
|
|
// DeletePieces deletes a set of pieces.
|
|
|
|
func (client *Client) DeletePieces(ctx context.Context, ids ...storj.PieceID) (err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
if len(ids) == 0 {
|
|
|
|
// Avoid RPC calls if no pieces to delete.
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
_, err = client.client.DeletePieces(ctx, &pb.DeletePiecesRequest{
|
|
|
|
PieceIds: ids,
|
|
|
|
})
|
|
|
|
return Error.Wrap(err)
|
|
|
|
}
|
|
|
|
|
2019-07-11 21:04:22 +01:00
|
|
|
// Retain uses a bloom filter to tell the piece store which pieces to keep.
|
|
|
|
func (client *Client) Retain(ctx context.Context, req *pb.RetainRequest) (err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
_, err = client.client.Retain(ctx, req)
|
|
|
|
return Error.Wrap(err)
|
|
|
|
}
|
|
|
|
|
2019-03-18 10:55:06 +00:00
|
|
|
// Close closes the underlying connection.
|
|
|
|
func (client *Client) Close() error {
|
|
|
|
return client.conn.Close()
|
|
|
|
}
|
|
|
|
|
2019-10-25 18:16:20 +01:00
|
|
|
// GetPeerIdentity gets the connection's peer identity
|
|
|
|
func (client *Client) GetPeerIdentity() (*identity.PeerIdentity, error) {
|
|
|
|
return client.conn.PeerIdentity()
|
|
|
|
}
|
|
|
|
|
2019-03-18 10:55:06 +00:00
|
|
|
// next allocation step find the next trusted step.
|
|
|
|
func (client *Client) nextAllocationStep(previous int64) int64 {
|
|
|
|
// TODO: ensure that this is frame idependent
|
|
|
|
next := previous * 3 / 2
|
|
|
|
if next > client.config.MaximumStep {
|
|
|
|
next = client.config.MaximumStep
|
|
|
|
}
|
|
|
|
return next
|
|
|
|
}
|
|
|
|
|
|
|
|
// ignoreEOF is an utility func for ignoring EOF error, when it's not important.
|
|
|
|
func ignoreEOF(err error) error {
|
|
|
|
if err == io.EOF {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|