upda/server/service_lock_mem.go
Varakh 1fc3818d3c
All checks were successful
/ build (push) Successful in 5m3s
feature(api,release): prepare for next major release and switch to requiring content-type set to JSON for all incoming requests and expose more CORS environment variables
- Switched to enforce JSON as Content-Type for all incoming requests
- Switched to properly respond with JSON on page not found or method not allowed
- Renamed CORS_ALLOW_ORIGIN to CORS_ALLOW_ORIGINS
- Added CORS_ALLOW_CREDENTIALS which defaults to true
- Added CORS_EXPOSE_HEADERS which defaults to *
- Overhauled package visibility for server module
2024-06-10 20:03:25 +02:00

75 lines
1.7 KiB
Go

package server
import (
"context"
"errors"
"git.myservermanager.com/varakh/upda/util"
"go.uber.org/zap"
"time"
)
type lockMemService struct {
registry *util.InMemoryLockRegistry
}
var (
errLockMemNotReleased = newServiceError(conflict, errors.New("lock service: could not release lock"))
)
func newLockMemService() lockService {
zap.L().Info("Initializing in-memory locking service")
return &lockMemService{registry: util.NewInMemoryLockRegistry()}
}
// lock locks a given resource without any options (default expiration)
func (s *lockMemService) lock(ctx context.Context, resource string) (appLock, error) {
return s.lockWithOptions(ctx, resource, withAppLockOptionExpiry(0))
}
// lockWithOptions locks a given resource, only TTL as option is supported
func (s *lockMemService) lockWithOptions(ctx context.Context, resource string, options ...appLockOption) (appLock, error) {
if resource == "" {
return nil, errorValidationNotBlank
}
var expiration time.Duration = 0
if options != nil {
lockOptions := &appLockOptions{}
for _, o := range options {
o.apply(lockOptions)
}
if lockOptions.expiry != nil {
expiration = *lockOptions.expiry
}
}
zap.L().Sugar().Debugf("Trying to lock '%s'", resource)
s.registry.LockWithTTL(resource, expiration)
zap.L().Sugar().Debugf("Locked '%s'", resource)
l := &inMemoryLock{
registry: s.registry,
resource: resource,
}
return l, nil
}
var _ appLock = (*inMemoryLock)(nil)
type inMemoryLock struct {
registry *util.InMemoryLockRegistry
resource string
}
func (r inMemoryLock) unlock(ctx context.Context) error {
zap.L().Sugar().Debugf("Unlocking '%s'", r.resource)
if err := r.registry.Unlock(r.resource); err != nil {
return errLockMemNotReleased
}
return nil
}