Skip to content

Commit

Permalink
Fix lint (#8)
Browse files Browse the repository at this point in the history
* Fix lint errors
  • Loading branch information
FurmanovD committed Apr 2, 2023
1 parent 9aa7094 commit b5e447f
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 130 deletions.
15 changes: 15 additions & 0 deletions db/redislock/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package redislock

import (
"errors"
)

type Error error

var (
// these errors describes a result of a record lock
ErrAlreadyLocked = Error(errors.New("key is already locked"))
ErrUninitialized = Error(errors.New("locker or redis client is not initialized"))
ErrEmptyKey = Error(errors.New("key to lock is empty"))
ErrUnlockRequired = Error(errors.New("locker already locked another key"))
)
52 changes: 26 additions & 26 deletions db/redislock/redislock.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,27 @@ type lockInfo struct {
}

type redisLocker struct {
mutex sync.Mutex
redis *redis.Client
locked *lockInfo // saves all info to unlock. != nil means locked state
mutex sync.Mutex
rclient *redis.Client
locked *lockInfo // saves all info to unlock. != nil means locked state
//TODO(DF) possibly add a lock-count to allow the same locker lock the same key, e.g. to extend a lock TTL
}

func NewRedisLocker(c *redis.Client) RedisLock {
return &redisLocker{
redis: c,
rclient: c,
}
}

// Locks a redis record by creating a key with special name or returns an AlreadyLocked if such a key already exists
func (rl *redisLocker) Lock(ctx context.Context, key string, ttl time.Duration) RedisLockError {
// Locks a redis record by creating a key with special name or returns an ErrAlreadyLocked if such a key already exists
func (rl *redisLocker) Lock(ctx context.Context, key string, ttl time.Duration) Error {

if rl == nil || rl.redis == nil {
return Uninitialized
if rl == nil || rl.rclient == nil {
return ErrUninitialized
}

if key == "" {
return EmptyKey
return ErrEmptyKey
}

rl.mutex.Lock()
Expand All @@ -57,14 +57,14 @@ func (rl *redisLocker) ObtainLock(
ttl time.Duration,
timeout time.Duration,
retryPeriod time.Duration,
) RedisLockError {
) Error {

if rl == nil || rl.redis == nil {
return Uninitialized
if rl == nil || rl.rclient == nil {
return ErrUninitialized
}

if key == "" {
return EmptyKey
return ErrEmptyKey
}

rl.mutex.Lock()
Expand All @@ -77,53 +77,53 @@ func (rl *redisLocker) ObtainLock(
for ; !now.After(timeoutTime); now = time.Now() {
tryRes := rl.tryLock(ctx, key, ttl)
switch tryRes {
case AlreadyLocked:
case ErrAlreadyLocked:
time.Sleep(retryPeriod)
default:
return tryRes
}
}
// if we reached this point, it means timeout is reached and another lock still not released
return AlreadyLocked
return ErrAlreadyLocked
}

func (rl *redisLocker) Unlock() RedisLockError {
func (rl *redisLocker) Unlock() Error {

if rl == nil || rl.redis == nil {
return Uninitialized
if rl == nil || rl.rclient == nil {
return ErrUninitialized
}

rl.mutex.Lock()
defer rl.mutex.Unlock()

if rl.locked != nil && rl.locked.Key != "" {
rl.redis.Del(rl.locked.Ctx, rl.locked.Key)
rl.rclient.Del(rl.locked.Ctx, rl.locked.Key)
}
rl.locked = nil

return Ok
return nil
}

// tryLock actually locks the record.
// ! No sync.
// ! No parameters validation.
func (rl *redisLocker) tryLock(ctx context.Context, key string, ttl time.Duration) RedisLockError {
func (rl *redisLocker) tryLock(ctx context.Context, key string, ttl time.Duration) Error {

lockKey := lockKeyPrefix + key
if rl.locked != nil {
if rl.locked.Key != lockKey {
return UnlockRequired
return ErrUnlockRequired
}
return Ok
return nil
}

if setRes := rl.redis.SetNX(ctx, lockKey, lockValue, ttl); setRes.Val() {
if setRes := rl.rclient.SetNX(ctx, lockKey, lockValue, ttl); setRes.Val() {
rl.locked = &lockInfo{
Key: lockKey,
Ctx: ctx,
}
return Ok
return nil
}

return AlreadyLocked
return ErrAlreadyLocked
}
18 changes: 3 additions & 15 deletions db/redislock/redislock_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,20 @@ package redislock

import (
"context"
"errors"
"time"
)

type RedisLockError error

var (
// these errors describes a result of a record lock
Ok = RedisLockError(nil)
AlreadyLocked = RedisLockError(errors.New("a key is already locked"))
Uninitialized = RedisLockError(errors.New("locker or redis client is not initialized"))
EmptyKey = RedisLockError(errors.New("key to lock is empty"))
UnlockRequired = RedisLockError(errors.New("locker is already locked another key"))
)

// TODO(DF) Add later some "lockerID" parameter to unlock all records locked by the server if it crashed

// RedisLock describes a locker interface.
type RedisLock interface {
Lock(ctx context.Context, key string, ttl time.Duration) RedisLockError
Lock(ctx context.Context, key string, ttl time.Duration) Error
ObtainLock(
ctx context.Context,
key string,
ttl time.Duration,
timeout time.Duration,
loopPeriod time.Duration,
) RedisLockError
Unlock() RedisLockError
) Error
Unlock() Error
}
108 changes: 57 additions & 51 deletions filesys/fsops/fsops.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ func copyFileInt(src, dst string, deletesrc bool) error {
return err
}
}
// if err = os.Link(src, dst); err == nil {
// return err
// }

// TODO: in case "delete original" == true and src and dest are on the same volume - use os.Rename()

res := copyFileContents(src, dst)
if deletesrc {
os.Remove(src)
}

return res
}

Expand All @@ -62,6 +62,7 @@ func copyFileContents(src, dst string) error {
return err
}
defer in.Close()

out, err := os.Create(dst)
if err != nil {
return err
Expand All @@ -72,19 +73,21 @@ func copyFileContents(src, dst string) error {
err = cerr
}
}()

if _, err = io.Copy(out, in); err != nil {
return err
}
err = out.Sync()
err = out.Sync() // its required to be sure defer functions are called.

return err
}

// CopyFolder copies a folder's content to a (new one) another one
// CopyFolder copies a folder's content to a (new one) another one.
func CopyFolder(source string, dest string) error {
return copyFolderInt(source, dest, -1, false)
}

// CopyFolderLevels copies a folder's content to a (new one) another one
// CopyFolderLevels copies a folder's content to a (new one) another one.
func CopyFolderLevels(source string, dest string, levels int) error {
return copyFolderInt(source, dest, levels, false)
}
Expand All @@ -97,7 +100,7 @@ func copyFolderInt(source string, dest string, levels int, deletesource bool) er
}
srcName := srcstat.Name()

//build dest:
// build dest:
fullDest := filepath.Join(dest, srcName)
if _, err = os.Stat(fullDest); os.IsNotExist(err) {
err = os.MkdirAll(fullDest, os.ModeDir|os.ModePerm)
Expand All @@ -118,19 +121,19 @@ func copyFolderInt(source string, dest string, levels int, deletesource bool) er
return err
}

// CopyFolderContent copies a folder's content only
// CopyFolderContent copies a folder's content only.
func CopyFolderContent(source string, dest string) error {
return copyFolderContentInt(source, dest, -1, false)
}

// CopyFolderContentLevels copies a folder's content only
// CopyFolderContentLevels copies a folder's content only.
func CopyFolderContentLevels(source string, dest string, levelsDeeper int) error {
return copyFolderContentInt(source, dest, levelsDeeper, false)
}

func copyFolderContentInt(source string, dest string, levelsDeeper int, deletesource bool) error {

//check dirs:
// check dirs.
var err error
if _, err = os.Stat(source); os.IsNotExist(err) {
return err
Expand All @@ -146,9 +149,9 @@ func copyFolderContentInt(source string, dest string, levelsDeeper int, deleteso
sourcefilepointer := source + "/" + obj.Name()
destinationfilepointer := dest + "/" + obj.Name()
if obj.IsDir() {
if 0 > levelsDeeper { //recursively all
if 0 > levelsDeeper { // recursively all.
err = copyFolderInt(sourcefilepointer, destinationfilepointer, levelsDeeper, deletesource)
} else if 1 <= levelsDeeper { //some levels only - continue
} else if 1 <= levelsDeeper { // some levels only - continue.
err = copyFolderInt(sourcefilepointer, destinationfilepointer, levelsDeeper-1, deletesource)
} // else
// 0 == levelsDeeper - means "do not copy next levels"
Expand Down Expand Up @@ -197,71 +200,74 @@ func IsFile(path string) bool {
return !fi.IsDir()
}

// MoveFolder moves a folder's content only
// MoveFolder moves a folder's content only.
func MoveFolder(source string, dest string) error {
//Check is Dir:
// check is dir.
if !IsDir(source) {
return fmt.Errorf("%s source is not a directory or inaccessible", source)
}

if filepath.VolumeName(source) == filepath.VolumeName(dest) { //on the same disk
if strings.HasPrefix(dest, source) {
return fmt.Errorf("Directory %s cannot be moved to a nested directory %s", source, dest)
}
if filepath.VolumeName(source) != filepath.VolumeName(dest) {
// different disks.
return copyFolderInt(source, dest, -1, true)
}

if !IsDir(dest) {
errmake := os.MkdirAll(dest, os.ModeDir|os.ModePerm)
if errmake != nil {
return errmake
}
}
// on the same disk.
if strings.HasPrefix(dest, source) {
return fmt.Errorf("directory %s cannot be moved to a nested directory %s", source, dest)
}

srcstat, err := os.Stat(source)
if err != nil {
return err
if !IsDir(dest) {
errmake := os.MkdirAll(dest, os.ModeDir|os.ModePerm)
if errmake != nil {
return errmake
}
srcName := srcstat.Name()
//build dest:
fullDest := filepath.Join(dest, srcName)
return os.Rename(source, fullDest)
}

} else {
// Different disks:
return copyFolderInt(source, dest, -1, true)
srcstat, err := os.Stat(source)
if err != nil {
return err
}
srcName := srcstat.Name()
// build dest.
fullDest := filepath.Join(dest, srcName)

return os.Rename(source, fullDest)
}

// MoveFile moves a folder's content only
// MoveFile moves a folder's content only.
func MoveFile(source string, dest string) error {
//Check is File:
// check is file.
if !IsFile(source) {
return fmt.Errorf("%s source is not a file or inaccessible", source)
}

if filepath.VolumeName(source) == filepath.VolumeName(dest) { //on the same disk
if strings.HasPrefix(dest, source) {
return fmt.Errorf("File %s cannot be moved to directory %s - destination directory can not be created", source, dest)
}
return os.Rename(source, dest)
} else {
// Different disks:
if filepath.VolumeName(source) == filepath.VolumeName(dest) {
// different disks.
return copyFileInt(source, dest, true)
}

// on the same disk.
if strings.HasPrefix(dest, source) {
return fmt.Errorf("file %s cannot be moved to directory %s - destination directory can not be created", source, dest)
}

return os.Rename(source, dest)
}

// GetFilename returns a filename
func GetFilename(fullfilename string, withExt bool) string {
dir := filepath.Dir(fullfilename)
filename_wExt, err := stringtools.GetSubstring(fullfilename, dir, "")
filenameWithExt, err := stringtools.GetSubstring(fullfilename, dir, "")
if nil != err {
return ""
}
if withExt || !strings.Contains(filename_wExt, ".") {
return filename_wExt[1 : len(filename_wExt)-1]
if withExt || !strings.Contains(filenameWithExt, ".") {
return filenameWithExt[1 : len(filenameWithExt)-1]
}

filename_woExt := filename_wExt[1:strings.LastIndex(filename_wExt, ".")]
return filename_woExt
filenameWithoutExt := filenameWithExt[1:strings.LastIndex(filenameWithExt, ".")]
return filenameWithoutExt
}

func IsFileContains(fpath string, test []byte) bool {
Expand All @@ -271,7 +277,7 @@ func IsFileContains(fpath string, test []byte) bool {
}
in.Close()

if 0 == len(test) {
if len(test) == 0 {
return false
}

Expand All @@ -292,7 +298,7 @@ func IsFileContains(fpath string, test []byte) bool {
if testmatches {
return true
}
} // if first byte of test slice found
} // loop by whole file content
} // if first byte of test slice found.
} // loop by whole file content.
return false
}

0 comments on commit b5e447f

Please sign in to comment.