116 lines
2.8 KiB
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)
|
|
}
|