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 }