github.com/diggerhq/digger/libs@v0.0.0-20240604170430-9d61cdf01cc5/locking/gcp/gcp_lock.go (about) 1 package gcp 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 "strconv" 8 "time" 9 10 "cloud.google.com/go/storage" 11 ) 12 13 type GoogleStorageLock struct { 14 Client *storage.Client 15 Bucket *storage.BucketHandle 16 Context context.Context 17 } 18 19 func (googleLock *GoogleStorageLock) Lock(transactionId int, resource string) (bool, error) { 20 now := time.Now().Format(time.RFC3339) 21 fileName := resource 22 23 wc := googleLock.Bucket.Object(fileName).NewWriter(googleLock.Context) 24 wc.ContentType = "text/plain" 25 wc.Metadata = map[string]string{ 26 "LockId": strconv.Itoa(transactionId), 27 "CreatedAt": now, 28 } 29 30 bucketAttrs, err := googleLock.Bucket.Attrs(googleLock.Context) 31 if err != nil { 32 log.Printf("failed to get bucket attributes: %v\n", err) 33 } 34 bucketName := bucketAttrs.Name 35 36 if err := wc.Close(); err != nil { 37 log.Printf("createFile: unable to close bucket %q, file %q: %v\n", bucketName, fileName, err) 38 } 39 return true, nil 40 } 41 42 func (googleLock *GoogleStorageLock) Unlock(resource string) (bool, error) { 43 fileName := resource 44 45 existingLockTransactionId, err := googleLock.GetLock(resource) 46 if err != nil { 47 log.Printf("failed to get lock: %v\n", err) 48 } 49 if existingLockTransactionId == nil { 50 return false, nil 51 } 52 53 fileObject := googleLock.Bucket.Object(fileName) 54 err = fileObject.Delete(googleLock.Context) 55 if err != nil { 56 return false, fmt.Errorf("failed to delete lock file: %v\n", err) 57 } 58 59 return true, nil 60 } 61 62 func (googleLock *GoogleStorageLock) GetLock(resource string) (*int, error) { 63 fileName := resource 64 fileObject := googleLock.Bucket.Object(fileName) 65 fileAttrs, err := fileObject.Attrs(googleLock.Context) 66 if err != nil { 67 // TODO: not sure if it's the best way to handle it 68 if err.Error() == "storage: object doesn't exist" { 69 return nil, nil 70 } 71 return nil, err 72 } 73 fileMetadata := fileAttrs.Metadata 74 lockIdStr := fileMetadata["LockId"] 75 transactionId, err := strconv.Atoi(lockIdStr) 76 if err != nil { 77 log.Printf("failed to parse LockId in object's metadata: %v\n", err) 78 } 79 return &transactionId, nil 80 } 81 82 func GetGoogleStorageClient() (context.Context, *storage.Client) { 83 ctx := context.Background() 84 85 client, err := storage.NewClient(ctx) 86 if err != nil { 87 log.Fatalf("Failed to create Google Storage client: %v", err) 88 } 89 return ctx, client 90 }