func (l *BlockingLimiter) tryAcquire(ctx context.Context) (core.Listener, bool) {
	for {
		l.c.L.Lock()
		deadline, deadlineSet := ctx.Deadline()
		if deadlineSet && time.Now().UTC().After(deadline) {
			l.logger.Debugf("deadline passed ctx=%v", time.Now().UTC().After(deadline), ctx)
			l.c.L.Unlock()
			return nil, false
		}
		listener, ok := l.delegate.Acquire(ctx)
		if ok && listener != nil {
			l.logger.Debugf("delegate returned a listener ctx=%v", ctx)
			l.c.L.Unlock()
			return listener, true
		}
		timeout := l.timeout  
		if deadlineSet {
			timeout := deadline.Sub(time.Now().UTC())
			if timeout <= 0 {
				l.logger.Debugf("deadline passed ctx=%v", ctx)
				return nil, false
			}
		}
		l.c.L.Unlock()
		timeoutWaiter := newTimeoutWaiter(l.c, timeout)
		timeoutWaiter.start()
		l.logger.Debugf("Blocking waiting for release or timeout ctx=%v", ctx)
		<-timeoutWaiter.wait()
		l.logger.Debugf("blocking released, trying again to acquire ctx=%v", ctx)
	}
}
tryAcquire will block when attempting to acquire a token
package limiter
import (
	"context"
	"fmt"
	"sync"
	"time"
	"github.com/platinummonkey/go-concurrency-limits/core"
	"github.com/platinummonkey/go-concurrency-limits/limit"
)
const longBlockingTimeout = time.Hour * 24 * 30 * 12 * 100  
type timeoutWaiter struct {
	timeoutSig chan struct{}
	closerSig  chan struct{}
	c          *sync.Cond
	once       sync.Once
	timeout    time.Duration
}
func newTimeoutWaiter(c *sync.Cond, timeout time.Duration) *timeoutWaiter {
	return &timeoutWaiter{
		timeoutSig: make(chan struct{}),
		closerSig:  make(chan struct{}),
		c:          c,
		timeout:    timeout,
	}
}
func (w *timeoutWaiter) start() {
	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
		wg.Done()
		w.run()
	}()
	go func() {
		wg.Done()
		w.c.L.Lock()
		w.c.Wait()
		w.c.L.Unlock()
		w.unblock()
	}()
	wg.Wait()
}
func (w *timeoutWaiter) run() {
	if w.timeout > 0 {
		select {
		case <-w.closerSig:
			close(w.timeoutSig)
			return
		case <-time.After(w.timeout):
			close(w.timeoutSig)
			return
		}
	}
	select {
	case <-w.closerSig:
		close(w.timeoutSig)
		return
	}
}
func (w *timeoutWaiter) unblock() {
	w.once.Do(func() {
		close(w.closerSig)
	})
}
func (w *timeoutWaiter) wait() <-chan struct{} {
	return w.timeoutSig
}
type BlockingLimiter struct {
	logger   limit.Logger
	delegate core.Limiter
	c        *sync.Cond
	timeout  time.Duration
}
func NewBlockingLimiter(
	delegate core.Limiter,
	timeout time.Duration,
	logger limit.Logger,
) *BlockingLimiter {
	mu := sync.Mutex{}
	if timeout <= 0 {
		timeout = longBlockingTimeout
	}
	if logger == nil {
		logger = limit.NoopLimitLogger{}
	}
	return &BlockingLimiter{
		logger:   logger,
		delegate: delegate,
		c:        sync.NewCond(&mu),
		timeout:  timeout,
	}
}