Skip to content

Commit 02f858a

Browse files
Hayim.Shaul@ibm.comadecaro
authored andcommitted
replace mutex with context aware semaphore
Signed-off-by: Hayim.Shaul@ibm.com <hayimsha@fhe3.haifa.ibm.com>
1 parent 9a0f07c commit 02f858a

1 file changed

Lines changed: 26 additions & 5 deletions

File tree

token/services/storage/auditdb/store.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
dbdriver "github.com/hyperledger-labs/fabric-token-sdk/token/services/storage/db/driver"
2424
"github.com/hyperledger-labs/fabric-token-sdk/token/services/storage/db/multiplexed"
2525
"github.com/hyperledger-labs/fabric-token-sdk/token/services/storage/ttxdb"
26+
"golang.org/x/sync/semaphore"
2627
)
2728

2829
var (
@@ -275,6 +276,9 @@ func (d *StoreService) GetTokenRequests(ctx context.Context, txIDs []string) (ma
275276

276277
// AcquireLocks acquires locks for the passed anchor and enrollment ids.
277278
// This can be used to prevent concurrent read/write access to the audit records of the passed enrollment ids.
279+
// The function respects context cancellation and deadlines, returning an error if the context is cancelled
280+
// or times out before all locks can be acquired. This prevents indefinite blocking and enables fast failure
281+
// in case of lock contention or deadlock scenarios.
278282
func (d *StoreService) AcquireLocks(ctx context.Context, anchor string, eIDs ...string) error {
279283
// This implementation allows concurrent calls to AcquireLocks such that if two
280284
// or more calls involve non-overlapping enrollment IDs, both calls will succeed.
@@ -286,12 +290,29 @@ func (d *StoreService) AcquireLocks(ctx context.Context, anchor string, eIDs ...
286290
// Without sorting, these two calls could deadlock. Sorting prevents this issue.
287291
dedup := deduplicateAndSort(eIDs)
288292
logger.DebugfContext(ctx, "Acquire locks for [%s:%v] enrollment ids", anchor, dedup)
289-
d.eIDsLocks.LoadOrStore(anchor, dedup)
293+
294+
acquired := []string{}
290295
for _, id := range dedup {
291-
lock, _ := d.eIDsLocks.LoadOrStore(id, &sync.RWMutex{})
292-
lock.(*sync.RWMutex).Lock()
296+
// Use semaphore with weight 1 to act as a mutex, but with context support
297+
sem, _ := d.eIDsLocks.LoadOrStore(id, semaphore.NewWeighted(1))
298+
299+
// Acquire respects context cancellation and deadlines without spawning goroutines
300+
if err := sem.(*semaphore.Weighted).Acquire(ctx, 1); err != nil {
301+
// Context cancelled or timed out - rollback already acquired locks
302+
logger.WarnfContext(ctx, "Failed to acquire lock for enrollment ID [%s] due to context cancellation, rolling back %d acquired locks", id, len(acquired))
303+
for _, acquiredID := range acquired {
304+
if s, ok := d.eIDsLocks.Load(acquiredID); ok {
305+
s.(*semaphore.Weighted).Release(1)
306+
}
307+
}
308+
return errors.Wrapf(err, "failed to acquire lock for enrollment ID [%s]", id)
309+
}
310+
acquired = append(acquired, id)
293311
logger.DebugfContext(ctx, "Acquire locks for [%s:%v] enrollment id done", anchor, id)
294312
}
313+
314+
// Store anchor mapping only after successfully acquiring all locks
315+
d.eIDsLocks.Store(anchor, dedup)
295316
logger.DebugfContext(ctx, "Acquire locks for [%s:%v] enrollment ids...done", anchor, dedup)
296317

297318
return nil
@@ -308,14 +329,14 @@ func (d *StoreService) ReleaseLocks(ctx context.Context, anchor string) {
308329
dedup := dedupBoxed.([]string)
309330
logger.DebugfContext(ctx, "Release locks for [%s:%v] enrollment ids", anchor, dedup)
310331
for _, id := range dedup {
311-
lock, ok := d.eIDsLocks.Load(id)
332+
sem, ok := d.eIDsLocks.Load(id)
312333
if !ok {
313334
logger.Warnf("unlock for enrollment id [%s:%s] not possible, lock never acquired", anchor, id)
314335

315336
continue
316337
}
317338
logger.DebugfContext(ctx, "unlock lock for [%s:%v] enrollment id done", anchor, id)
318-
lock.(*sync.RWMutex).Unlock()
339+
sem.(*semaphore.Weighted).Release(1)
319340
}
320341
logger.DebugfContext(ctx, "Release locks for [%s:%v] enrollment ids...done", anchor, dedup)
321342
}

0 commit comments

Comments
 (0)