Skip to content

Commit 88a385b

Browse files
adds transaction lock manager
1 parent 3a13307 commit 88a385b

File tree

3 files changed

+67
-5
lines changed

3 files changed

+67
-5
lines changed

‎appcontext/dependencies.go‎

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,37 @@ import (
66
local_repo "nipun.io/brew_machine/repository/local"
77
"nipun.io/brew_machine/service"
88
local_service "nipun.io/brew_machine/service/local"
9+
"sync"
910
)
1011

1112
type Instance struct {
12-
BeverageRepository repository.BeverageRepository
13-
IngredientRepository repository.IngredientRepository
14-
BeverageManager service.BeverageManager
15-
IngredientManager service.IngredientManager
16-
DispenserService service.DispenserService
13+
BeverageRepository repository.BeverageRepository
14+
IngredientRepository repository.IngredientRepository
15+
BeverageManager service.BeverageManager
16+
IngredientManager service.IngredientManager
17+
DispenserService service.DispenserService
18+
TransactionLockManager service.TransactionLockManager
1719
}
1820

1921
var AppDependencies *Instance
2022

2123
func LoadDependencies() {
2224
AppDependencies = &Instance{}
25+
AppDependencies.addTransactionLockManager()
2326
AppDependencies.addBeverageRepository()
2427
AppDependencies.addIngredientRepository()
2528
AppDependencies.addBeverageManager()
2629
AppDependencies.addIngredientManager()
2730
AppDependencies.addDispenserService()
2831
}
2932

33+
func (dependencies *Instance) addTransactionLockManager() {
34+
dependencies.TransactionLockManager = &local_service.TransactionLockManager{
35+
KeeperState: map[string]string{},
36+
Keeper: map[string]*sync.Mutex{},
37+
}
38+
}
39+
3040
func (dependencies *Instance) addBeverageRepository() {
3141
dependencies.BeverageRepository = local_repo.NewInMemoryBeverageRepository()
3242
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package service
2+
3+
import (
4+
"strings"
5+
"sync"
6+
7+
"nipun.io/brew_machine/logger"
8+
)
9+
10+
type TransactionLockManager struct {
11+
Keeper map[string]*sync.Mutex
12+
KeeperState map[string]string
13+
}
14+
15+
const (
16+
Locked = "LOCKED"
17+
)
18+
19+
var mutex sync.Mutex // Global Mutex, all operation of locking and un-locking happen in a serial manner using this.
20+
21+
func (tlm *TransactionLockManager) AcquireLock(entities []string) {
22+
logger.Logger.Debug().Msgf("Trying to acquire operation lock for %+v", entities)
23+
mutex.Lock()
24+
entitiesString := strings.Join(entities, "-")
25+
if tlm.Keeper[entitiesString] == nil {
26+
tlm.Keeper[entitiesString] = &sync.Mutex{}
27+
logger.Logger.Debug().Msgf("Created mutex for entity : %s", entitiesString)
28+
}
29+
logger.Logger.Debug().Msgf("Trying to acquire lock for %+v", entities)
30+
tlm.Keeper[entitiesString].Lock() // who ever want to acquire a lock on something already locked, will have to wait.
31+
logger.Logger.Debug().Msgf("Acquired lock on mutex for entity : %s", entitiesString)
32+
tlm.KeeperState[entitiesString] = Locked
33+
mutex.Unlock()
34+
}
35+
36+
func (tlm *TransactionLockManager) ReleaseLock(entities []string) {
37+
mutex.Lock() // to deal with classic deadlock scenario
38+
entitiesString := strings.Join(entities, "-")
39+
40+
if tlm.KeeperState[entitiesString] == Locked {
41+
logger.Logger.Debug().Msgf("released lock on mutex for entity : %s", entitiesString)
42+
tlm.Keeper[entitiesString].Unlock()
43+
tlm.KeeperState[entitiesString] = ""
44+
}
45+
mutex.Unlock()
46+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package service
2+
3+
type TransactionLockManager interface {
4+
AcquireLock([]string)
5+
ReleaseLock([]string)
6+
}

0 commit comments

Comments
 (0)