Skip to content

Commit

Permalink
first iteration of lockmanager with tests
Browse files Browse the repository at this point in the history
  • Loading branch information
OliverLok committed Jan 2, 2024
1 parent 4d20a14 commit ad938f5
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 0 deletions.
56 changes: 56 additions & 0 deletions util/lockmanager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package util

import (
"fmt"
"log"
"sync"
"time"
)

type Lock struct {
key string;
timestamp time.Time;
}

type LockManager struct {
locks map[string]*Lock;
mutex sync.Mutex;
staleDuration time.Duration;
}

func NewLockManager(staleDuration time.Duration) *LockManager {
lm := &LockManager{
locks: make(map[string]*Lock),
staleDuration: staleDuration,
}
go lm.removeStaleLocks();
return lm;
}

func (lm *LockManager) Lock(key string) {
lm.mutex.Lock();
lm.locks[key] = &Lock{key: key, timestamp: time.Now()};
}

func (lm *LockManager) Unlock(key string) error {
// Check if key exists in the lock map
_, ok := lm.locks[key];
if ok {
defer lm.mutex.Unlock();
delete(lm.locks, key);
return nil;
} else {
log.Fatal("Key not found.")
return fmt.Errorf("Error. Key not found.");
}
}

func (lm *LockManager) removeStaleLocks() {
time.Sleep(lm.staleDuration);
for key, lock := range lm.locks {
if time.Since(lock.timestamp) > lm.staleDuration {
delete(lm.locks, key);
lm.mutex.Unlock();
}
}
}
51 changes: 51 additions & 0 deletions util/lockmanager_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package util

import (
"fmt"
"testing"
"time"
)


func TestLockAcquisition(t *testing.T) {
lm := NewLockManager(3 * time.Second);
key := "testkey"
fmt.Println("Main Thread!")
lm.Lock(key)
lm.Lock(key)

fmt.Println("Got past the first lock from removeStaleLocks go routine")

go func() {
fmt.Println("1st Go Routine Started")

startTime := time.Now();
lm.Lock(key)
lockWaitDuration := time.Since(startTime);
fmt.Printf("Waited %v long to aquire the lock in the 1st go routine\n", lockWaitDuration);

go func() {
fmt.Println("2nd Go Routine Started")
startTime := time.Now();
lm.Lock(key);
lockWaitDuration := time.Since(startTime);
fmt.Printf("Waited %v long to aquire the lock in the 2nd go routine\n", lockWaitDuration);
defer lm.Unlock(key);
fmt.Println("2nd Go Routine Done")
}()


defer lm.Unlock(key)
fmt.Println("1st Go Routine Done")
time.Sleep(3 * time.Second)
}()

fmt.Println("Main Thread Almost Done")
time.Sleep(1 * time.Second)
lm.Unlock(key)

time.Sleep(4 * time.Second)

fmt.Println("Main Thread Done!")

}

0 comments on commit ad938f5

Please sign in to comment.