126 lines
2.3 KiB
Go
126 lines
2.3 KiB
Go
|
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
|
||
|
}
|