func (self *MaxJobsSemaphore) Acquire(metadata *Metadata) bool {
	if metadata == nil {
		return false
	}
	if st, ok := metadata.getState(); ok && st != Queued && st != Waiting {
		return false
	}
	defer self.cond.Signal()
	self.lock.Lock()
	defer self.lock.Unlock()
	for len(self.running) >= self.Limit {
		if st, ok := metadata.getState(); ok && st != Queued && st != Waiting {
			return false
		}
		if _, ok := self.running[metadata]; ok {
			return true
		}
		self.cond.Wait()
	}
	if st, ok := metadata.getState(); ok && st != Queued && st != Waiting {
		return false
	}
	self.running[metadata] = struct{}{}
	return true
}
Wait for this semaphore to have capacity to run this metadata
object.

If the object is not in the queued or waiting states, it was canceled
between when the job was enqueued and now.

If the object was already in the semaphore, as may be the case in the
event of automatic restart if the failure was missed for whatever reason,
then we only treat the metadata object as having one job running ever.
package core
import (
	"sync"
)
type MaxJobsSemaphore struct {
	running map[*Metadata]struct{}
	cond    *sync.Cond
	lock    sync.Mutex
	Limit   int
}
func NewMaxJobsSemaphore(limit int) *MaxJobsSemaphore {
	if limit < 1 {
		panic("Invalid max jobs limit")
	}
	self := &MaxJobsSemaphore{
		running: make(map[*Metadata]struct{}),
		Limit:   limit,
	}
	self.cond = sync.NewCond(&self.lock)
	return self
}