1
Fork 0
photoview/api/scanner/queue.go

126 lines
2.3 KiB
Go
Raw Normal View History

package scanner
import (
"database/sql"
"errors"
"sync"
"github.com/viktorstrate/photoview/api/graphql/models"
)
type ScannerJobScope int
const (
JOB_SCAN_USER ScannerJobScope = iota
JOB_SCAN_ALBUM
)
type ScannerJob struct {
scope ScannerJobScope
// Either models.User, models.Album or nil depending on the value of scope
model interface{}
}
func (job *ScannerJob) modelAsUser() (*models.User, error) {
user, ok := job.model.(models.User)
if !ok {
return nil, errors.New("scanner job not of type User")
}
return &user, nil
}
func (job *ScannerJob) modelAsAlbum() (*models.Album, error) {
album, ok := job.model.(models.Album)
if !ok {
return nil, errors.New("scanner job not of type Album")
}
return &album, nil
}
func (job *ScannerJob) Run() {
// TODO: Not implemented
}
type ScannerQueue struct {
mutex sync.Mutex
idle_chan chan bool
in_progress []ScannerJob
up_next []ScannerJob
db *sql.DB
}
var global_scanner_queue ScannerQueue
func InitializeScannerQueue(db *sql.DB) {
global_scanner_queue = ScannerQueue{
idle_chan: make(chan bool, 1),
in_progress: make([]ScannerJob, 0),
up_next: make([]ScannerJob, 0),
db: db,
}
}
func (queue *ScannerQueue) startBackgroundWorker() {
for {
<-queue.idle_chan
queue.mutex.Lock()
defer queue.mutex.Unlock()
}
}
func (queue *ScannerQueue) AddJob(job *ScannerJob) error {
queue.mutex.Lock()
defer queue.mutex.Unlock()
if exists, err := queue.jobOnQueue(job); exists || err != nil {
return err
}
queue.up_next = append(queue.up_next, *job)
queue.Notify()
return nil
}
func (queue *ScannerQueue) Notify() bool {
select {
case queue.idle_chan <- true:
return true
default:
return false
}
}
func (queue *ScannerQueue) jobOnQueue(job *ScannerJob) (bool, error) {
scannerJobs := append(queue.in_progress, queue.up_next...)
for _, scannerJob := range scannerJobs {
if scannerJob == *job {
return true, nil
}
if scannerJob.scope == JOB_SCAN_USER {
user, err := scannerJob.modelAsUser()
if err != nil {
return true, err
}
if job.scope == JOB_SCAN_ALBUM {
album, err := job.modelAsAlbum()
if err != nil {
return true, err
}
if album.OwnerID == user.UserID {
return true, nil
}
}
}
}
return false, nil
}