package semaphore

import (
	"github.com/pingcap/dbaas/billing2/utils/log"
	"github.com/pingcap/dbaas/billing2/utils/timeutils"
	"go.uber.org/zap"
)

type Semaphore struct {
	ch chan struct{}
}

func NewSemaphore(maxConcurrent int) *Semaphore {
	return &Semaphore{
		ch: make(chan struct{}, maxConcurrent),
	}
}

func (s *Semaphore) Acquire() {
	s.ch <- struct{}{}
}

func (s *Semaphore) Release() {
	<-s.ch
}

func ExecutionWithSemaphore(sem *Semaphore, f func()) {
	t1 := timeutils.GetNow()
	sem.Acquire()
	defer sem.Release()
	t2 := timeutils.GetNow()
	log.Info("try-lock cost", zap.Duration("cost", t2.Sub(t1)))
	f()
}
