Files
herolib/lib/dav/webdav/locker.v

116 lines
2.8 KiB
V

module webdav
import time
import rand
struct Locker {
mut:
locks map[string]Lock
}
// LockResult represents the result of a lock operation
pub struct LockResult {
pub:
token string // The lock token
is_new_lock bool // Whether this is a new lock or an existing one
}
// lock attempts to lock a resource for a specific owner
// Returns a LockResult with the lock token and whether it's a new lock
// Returns an error if the resource is already locked by a different owner
pub fn (mut lm Locker) lock(l Lock) !Lock {
if l.resource in lm.locks {
// Check if the lock is still valid
existing_lock := lm.locks[l.resource]
if time.now().unix() - existing_lock.created_at.unix() < existing_lock.timeout {
// Resource is already locked
if existing_lock.owner == l.owner {
// Same owner, refresh the lock
refreshed_lock := Lock {...existing_lock,
resource: l.resource
owner: l.owner
depth: l.depth
timeout: l.timeout
created_at: time.now()
}
lm.locks[l.resource] = refreshed_lock
return refreshed_lock
} else {
// Different owner, return an error
return error('Resource is already locked by a different owner')
}
}
// Expired lock, remove it
lm.unlock(l.resource)
}
// Generate a new lock token
new_lock := Lock{
...l,
token: rand.uuid_v4()
created_at: time.now()
}
lm.locks[l.resource] = new_lock
return new_lock
}
pub fn (mut lm Locker) unlock(resource string) bool {
if resource in lm.locks {
lm.locks.delete(resource)
return true
}
return false
}
// is_locked checks if a resource is currently locked
pub fn (lm Locker) is_locked(resource string) bool {
if resource in lm.locks {
lock_ := lm.locks[resource]
// Check if lock is expired
if time.now().unix() - lock_.created_at.unix() >= lock_.timeout {
return false
}
return true
}
return false
}
// get_lock returns the Lock object for a resource if it exists and is valid
pub fn (lm Locker) get_lock(resource string) ?Lock {
if resource in lm.locks {
lock_ := lm.locks[resource]
// Check if lock is expired
if time.now().unix() - lock_.created_at.unix() >= lock_.timeout {
return none
}
return lock_
}
return none
}
pub fn (mut lm Locker) unlock_with_token(resource string, token string) bool {
if resource in lm.locks {
lock_ := lm.locks[resource]
if lock_.token == token {
lm.locks.delete(resource)
return true
}
}
return false
}
fn (mut lm Locker) lock_recursive(l Lock) !Lock {
if l.depth == 0 {
return lm.lock(l)
}
// Implement logic to lock child resources if depth == 1
// For now, just lock the parent resource
return lm.lock(l)
}
pub fn (mut lm Locker) cleanup_expired_locks() {
// now := time.now().unix()
// lm.locks
// lm.locks = lm.locks.filter(it.value.created_at.unix() + it.value.timeout > now)
}