mirror of
https://github.com/offen/docker-volume-backup.git
synced 2024-09-19 21:20:28 +02:00
279844ccfb
* Added abstract helper interface and implemented it for all storage backends * Moved storage client initializations also to helper classes * Fixed ssh init issue * Moved script parameter to helper struct to simplify script init. * Created sub modules. Enhanced abstract implementation. * Fixed config issue * Fixed declaration issues. Added config to interface. * Added StorageProviders to unify all backends. * Cleanup, optimizations, comments. * Applied discussed changes. See description. Moved modules to internal packages. Replaced StoragePool with slice. Moved conditional for init of storage backends back to script. * Fix docker build issue * Fixed accidentally removed local copy condition. * Delete .gitignore * Renaming/changes according to review Renamed Init functions and interface. Replaced config object with specific config values. Init func returns interface instead of struct. Removed custom import names where possible. * Fixed auto-complete error. * Combined copy instructions into one layer. * Added logging func for storages. * Introduced logging func for errors too. * Missed an error message * Moved config back to main. Optimized prune stats handling. * Move stats back to main package * Code doc stuff * Apply changes from #136 * Replace name field with function. * Changed receiver names from stg to b. * Renamed LogFuncDef to Log * Removed redundant package name. * Renamed storagePool to storages. * Simplified creation of new storage backend. * Added initialization for storage stats map. * Invert .dockerignore patterns. * Fix package typo
60 lines
1.5 KiB
Go
60 lines
1.5 KiB
Go
// Copyright 2022 - Offen Authors <hioffen@posteo.de>
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/gofrs/flock"
|
|
"github.com/offen/docker-volume-backup/internal/utilities"
|
|
)
|
|
|
|
// lock opens a lockfile at the given location, keeping it locked until the
|
|
// caller invokes the returned release func. In case the lock is currently blocked
|
|
// by another execution, it will repeatedly retry until the lock is available
|
|
// or the given timeout is exceeded.
|
|
func (s *script) lock(lockfile string) (func() error, error) {
|
|
start := time.Now()
|
|
defer func() {
|
|
s.stats.LockedTime = time.Now().Sub(start)
|
|
}()
|
|
|
|
retry := time.NewTicker(5 * time.Second)
|
|
defer retry.Stop()
|
|
deadline := time.NewTimer(s.c.LockTimeout)
|
|
defer deadline.Stop()
|
|
|
|
fileLock := flock.New(lockfile)
|
|
|
|
for {
|
|
acquired, err := fileLock.TryLock()
|
|
if err != nil {
|
|
return utilities.Noop, fmt.Errorf("lock: error trying lock: %w", err)
|
|
}
|
|
if acquired {
|
|
if s.encounteredLock {
|
|
s.logger.Info("Acquired exclusive lock on subsequent attempt, ready to continue.")
|
|
}
|
|
return fileLock.Unlock, nil
|
|
}
|
|
|
|
if !s.encounteredLock {
|
|
s.logger.Infof(
|
|
"Exclusive lock was not available on first attempt. Will retry until it becomes available or the timeout of %s is exceeded.",
|
|
s.c.LockTimeout,
|
|
)
|
|
s.encounteredLock = true
|
|
}
|
|
|
|
select {
|
|
case <-retry.C:
|
|
continue
|
|
case <-deadline.C:
|
|
return utilities.Noop, errors.New("lock: timed out waiting for lockfile to become available")
|
|
}
|
|
}
|
|
}
|