func NewRetryStorer(inner api.Storer, timeout time.Duration) api.Storer {
	return &retryStorer{
		inner:   inner,
		timeout: timeout,
	}
}
NewRetryStorer creates a new api.Storer with exponential backoff retries.
package client
import (
	"time"
	cbackoff "github.com/cenkalti/backoff"
	"github.com/drausin/libri/libri/librarian/api"
	"github.com/pkg/errors"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
)
const (
	defaultExpBackoffInitialInterval     = 10 * time.Millisecond
	defaultExpBackoffRandomizationFactor = 0.25
	defaultExpBackoffMultiplier          = 1.414
	defaultExpBackoffMaxInterval         = 250 * time.Millisecond
)
var (
	ErrGetMissingValue = errors.New("Get response expected to have value but it is missing")
)
type retryFinder struct {
	inner   api.Finder
	timeout time.Duration
}
func NewRetryFinder(inner api.Finder, timeout time.Duration) api.Finder {
	return &retryFinder{
		inner:   inner,
		timeout: timeout,
	}
}
func (r *retryFinder) Find(ctx context.Context, rq *api.FindRequest, opts ...grpc.CallOption) (
	*api.FindResponse, error) {
	var rp *api.FindResponse
	operation := func() error {
		var err error
		rp, err = r.inner.Find(ctx, rq, opts...)
		return err
	}
	backoff := NewExpBackoff(r.timeout)
	if err := cbackoff.Retry(operation, backoff); err != nil {
		return nil, err
	}
	return rp, nil
}
type retryVerifier struct {
	inner   api.Verifier
	timeout time.Duration
}
func NewRetryVerifier(inner api.Verifier, timeout time.Duration) api.Verifier {
	return &retryVerifier{
		inner:   inner,
		timeout: timeout,
	}
}
func (r *retryVerifier) Verify(
	ctx context.Context, rq *api.VerifyRequest, opts ...grpc.CallOption,
) (*api.VerifyResponse, error) {
	var rp *api.VerifyResponse
	operation := func() error {
		var err error
		rp, err = r.inner.Verify(ctx, rq, opts...)
		return err
	}
	backoff := NewExpBackoff(r.timeout)
	if err := cbackoff.Retry(operation, backoff); err != nil {
		return nil, err
	}
	return rp, nil
}
type retryStorer struct {
	inner   api.Storer
	timeout time.Duration
}