github.com/benchkram/bob@v0.0.0-20240314204020-b7a57f2f9be9/pkg/store/remotestore/remotestore.go (about)

     1  package remotestore
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  	"sync"
     8  
     9  	"github.com/benchkram/errz"
    10  
    11  	"github.com/benchkram/bob/pkg/store"
    12  	storeclient "github.com/benchkram/bob/pkg/store-client"
    13  )
    14  
    15  type s struct {
    16  	// client to call the remote store.
    17  	client storeclient.I
    18  
    19  	username string
    20  	project  string
    21  
    22  	wg  sync.WaitGroup
    23  	err error
    24  }
    25  
    26  // New creates a remote store. The caller is responsible to pass a
    27  // existing directory.
    28  func New(username, project string, opts ...Option) store.Store {
    29  	s := &s{
    30  		username: username,
    31  		project:  project,
    32  	}
    33  
    34  	for _, opt := range opts {
    35  		if opt == nil {
    36  			continue
    37  		}
    38  		opt(s)
    39  	}
    40  
    41  	if s.client == nil {
    42  		panic(fmt.Errorf("no client"))
    43  	}
    44  
    45  	return s
    46  }
    47  
    48  // NewArtifact uploads an artifact. The caller is responsible to call Close().
    49  // Existing artifacts are overwritten.
    50  func (s *s) NewArtifact(ctx context.Context, artifactID string, size int64) (wc io.WriteCloser, err error) {
    51  	s.wg.Add(1)
    52  	reader, writer := io.Pipe()
    53  
    54  	go func() {
    55  		defer s.wg.Done()
    56  		err := s.client.UploadArtifact(
    57  			ctx,
    58  			s.project,
    59  			artifactID,
    60  			reader,
    61  			size,
    62  		)
    63  		if err != nil {
    64  			// store the error, it will be returned from s.Done()
    65  			s.err = err
    66  		}
    67  	}()
    68  
    69  	return writer, nil
    70  }
    71  
    72  // GetArtifact opens a file
    73  func (s *s) GetArtifact(ctx context.Context, id string) (rc io.ReadCloser, size int64, err error) {
    74  	defer errz.Recover(&err)
    75  
    76  	rc, size, err = s.client.GetArtifact(ctx, s.project, id)
    77  	errz.Fatal(err)
    78  
    79  	return rc, size, nil
    80  }
    81  
    82  func (s *s) Clean(_ context.Context) (err error) {
    83  	defer errz.Recover(&err)
    84  	return fmt.Errorf("not implemented")
    85  }
    86  
    87  // List the items id's in the store
    88  func (s *s) List(ctx context.Context) (ids []string, err error) {
    89  	defer errz.Recover(&err)
    90  
    91  	ids, err = s.client.ListArtifacts(ctx, s.project)
    92  	errz.Fatal(err)
    93  
    94  	return ids, nil
    95  }
    96  
    97  // Done waits till all processing finished
    98  func (s *s) Done() error {
    99  	s.wg.Wait()
   100  
   101  	return s.err
   102  }
   103  
   104  // ArtifactExists TODO: naive implementation.. implement one without downloading the artifact
   105  func (s *s) ArtifactExists(ctx context.Context, id string) bool {
   106  	_, _, err := s.client.GetArtifact(ctx, s.project, id)
   107  	return err == nil
   108  }
   109  
   110  func (s *s) ArtifactRemove(ctx context.Context, id string) error {
   111  	// not implemented
   112  	return nil
   113  }