shad-go/retryupdate/update.go

69 lines
1.3 KiB
Go
Raw Normal View History

2022-02-10 22:06:57 +00:00
//go:build !solution
2020-03-07 19:14:49 +00:00
package retryupdate
2024-06-07 01:08:48 +00:00
import (
"errors"
"fmt"
"github.com/gofrs/uuid"
"gitlab.com/slon/shad-go/retryupdate/kvapi"
)
var (
authError *kvapi.AuthError
conflictError *kvapi.ConflictError
)
2020-03-07 19:14:49 +00:00
func UpdateValue(c kvapi.Client, key string, updateFn func(oldValue *string) (newValue string, err error)) error {
2024-06-07 01:08:48 +00:00
newVersion := uuid.Must(uuid.NewV4())
get:
for {
old, err := c.Get(&kvapi.GetRequest{Key: key})
var value *string
oldUuid := uuid.Nil
if err != nil {
switch {
case errors.As(err, &authError):
return err
case !errors.Is(err, kvapi.ErrKeyNotFound):
continue
}
} else {
value = &old.Value
oldUuid = old.Version
}
for {
new, err := updateFn(value)
if err != nil {
return err
}
_, err = c.Set(&kvapi.SetRequest{
Key: key,
Value: new,
OldVersion: oldUuid,
NewVersion: newVersion,
})
if err != nil {
fmt.Println(err)
switch {
case errors.As(err, &conflictError):
if conflictError.ExpectedVersion == newVersion {
return nil
}
continue get
case errors.Is(err, kvapi.ErrKeyNotFound):
value = nil
oldUuid = uuid.Nil
continue
case errors.As(err, &authError):
return err
default:
continue
}
}
return nil
}
}
2020-03-07 19:14:49 +00:00
}