package main

import "sync"

var (
	opMutexes = map[string]*sync.Mutex{}
	opsLock   sync.Mutex
)

func opMutex[T any](key string, op func() (T, error)) (T, error) {
	lock := func() *sync.Mutex {
		opsLock.Lock()
		defer opsLock.Unlock()

		lock, ok := opMutexes[key]
		if !ok {
			lock = new(sync.Mutex)
			opMutexes[key] = lock
		}

		return lock
	}()

	lock.Lock()
	defer lock.Unlock()

	return op()
}
