package buildqueue import ( "brunel/domain" "brunel/fastmap" "sync" "errors" ) var queue = fastmap.New[string, domain.BuildQueueItem]() var queueLock = sync.RWMutex{} func Add(buildItem domain.BuildQueueItem) error { queueLock.Lock() defer queueLock.Unlock() if _, ok := queue.Get(buildItem.Source.Name); ok { return errors.New("package already in queue") } queue.Set(buildItem.Source.Name, buildItem) return nil } func Get(name string) (domain.BuildQueueItem, bool) { queueLock.RLock() defer queueLock.RUnlock() item, ok := queue.Get(name) return item, ok } func Remove(name string) error { queueLock.Lock() defer queueLock.Unlock() _, ok := queue.Get(name) if !ok { return errors.New("package not in queue") } queue.Delete(name) return nil } func Update(buildItem domain.BuildQueueItem) error { queueLock.Lock() defer queueLock.Unlock() item, ok := queue.Get(buildItem.Source.Name) if !ok { return errors.New("package not in queue") } if item.Status == domain.Building { return errors.New("package is already building") } queue.Set(buildItem.Source.Name, buildItem) return nil } func GetQueueCopy() *fastmap.Fastmap[string, domain.BuildQueueItem] { queueLock.RLock() defer queueLock.RUnlock() returnQueue := fastmap.New[string, domain.BuildQueueItem]() queue.Iter(func(k string, v domain.BuildQueueItem) bool { returnQueue.Set(k, v) return true }) return returnQueue } func GetBuildingQueue() *fastmap.Fastmap[string, domain.BuildQueueItem] { queueLock.RLock() defer queueLock.RUnlock() returnQueue := fastmap.New[string, domain.BuildQueueItem]() queue.Iter(func(k string, v domain.BuildQueueItem) bool { if v.Status == domain.Building { returnQueue.Set(k, v) } return true }) return returnQueue } func GetCounts() domain.BuildQueueCount { queueLock.RLock() defer queueLock.RUnlock() count := domain.BuildQueueCount{ Queued: 0, Building: 0, } queue.Iter(func(k string, v domain.BuildQueueItem) bool { if v.Status == domain.Queued { count.Queued++ } else if v.Status == domain.Building { count.Building++ } return true }) return count } func ProcessNext() error { queueLock.RLock() var item *domain.BuildQueueItem queue.Iter(func(k string, v domain.BuildQueueItem) bool { if v.Status == domain.Queued { item = &v return false } return true }) if item == nil { return errors.New("no packages in queue") } queueLock.RUnlock() err := UpdateBuildFile(*item) if err != nil { return err } queueLock.Lock() defer queueLock.Unlock() item.Status = domain.Building err = Update(*item) return err }