move job queue
This commit is contained in:
parent
4d207eed8b
commit
72e91d27ed
323
client/emdb.go
323
client/emdb.go
|
@ -1,323 +0,0 @@
|
||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"code.ewintr.nl/emdb/cmd/api-service/moviestore"
|
|
||||||
)
|
|
||||||
|
|
||||||
type EMDB struct {
|
|
||||||
baseURL string
|
|
||||||
apiKey string
|
|
||||||
c *http.Client
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewEMDB(baseURL string, apiKey string) *EMDB {
|
|
||||||
return &EMDB{
|
|
||||||
baseURL: baseURL,
|
|
||||||
apiKey: apiKey,
|
|
||||||
c: &http.Client{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *EMDB) GetMovies() ([]moviestore.Movie, error) {
|
|
||||||
url := fmt.Sprintf("%s/movie", e.baseURL)
|
|
||||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req.Header.Add("Authorization", e.apiKey)
|
|
||||||
|
|
||||||
resp, err := e.c.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
var movies []moviestore.Movie
|
|
||||||
if err := json.Unmarshal(body, &movies); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return movies, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *EMDB) GetMovie(id string) (moviestore.Movie, error) {
|
|
||||||
url := fmt.Sprintf("%s/movie/%s", e.baseURL, id)
|
|
||||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return moviestore.Movie{}, err
|
|
||||||
}
|
|
||||||
req.Header.Add("Authorization", e.apiKey)
|
|
||||||
|
|
||||||
resp, err := e.c.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return moviestore.Movie{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return moviestore.Movie{}, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
var movie moviestore.Movie
|
|
||||||
if err := json.Unmarshal(body, &movie); err != nil {
|
|
||||||
return moviestore.Movie{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return movie, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *EMDB) CreateMovie(m moviestore.Movie) (moviestore.Movie, error) {
|
|
||||||
body, err := json.Marshal(m)
|
|
||||||
if err != nil {
|
|
||||||
return moviestore.Movie{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
url := fmt.Sprintf("%s/movie", e.baseURL)
|
|
||||||
req, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(body))
|
|
||||||
if err != nil {
|
|
||||||
return moviestore.Movie{}, err
|
|
||||||
}
|
|
||||||
req.Header.Add("Authorization", e.apiKey)
|
|
||||||
|
|
||||||
resp, err := e.c.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return moviestore.Movie{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return moviestore.Movie{}, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
newBody, err := io.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return moviestore.Movie{}, err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
var newMovie moviestore.Movie
|
|
||||||
if err := json.Unmarshal(newBody, &newMovie); err != nil {
|
|
||||||
return moviestore.Movie{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return newMovie, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *EMDB) UpdateMovie(m moviestore.Movie) (moviestore.Movie, error) {
|
|
||||||
body, err := json.Marshal(m)
|
|
||||||
if err != nil {
|
|
||||||
return moviestore.Movie{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
url := fmt.Sprintf("%s/movie/%s", e.baseURL, m.ID)
|
|
||||||
req, err := http.NewRequest(http.MethodPut, url, bytes.NewReader(body))
|
|
||||||
if err != nil {
|
|
||||||
return moviestore.Movie{}, err
|
|
||||||
}
|
|
||||||
req.Header.Add("Authorization", e.apiKey)
|
|
||||||
|
|
||||||
resp, err := e.c.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return moviestore.Movie{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return moviestore.Movie{}, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
newBody, err := io.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return moviestore.Movie{}, err
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
var newMovie moviestore.Movie
|
|
||||||
if err := json.Unmarshal(newBody, &newMovie); err != nil {
|
|
||||||
return moviestore.Movie{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return newMovie, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *EMDB) GetReviews(movieID string) ([]moviestore.Review, error) {
|
|
||||||
url := fmt.Sprintf("%s/movie/%s/review", e.baseURL, movieID)
|
|
||||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req.Header.Add("Authorization", e.apiKey)
|
|
||||||
|
|
||||||
resp, err := e.c.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
var reviews []moviestore.Review
|
|
||||||
if err := json.Unmarshal(body, &reviews); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return reviews, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *EMDB) GetReview(id string) (moviestore.Review, error) {
|
|
||||||
url := fmt.Sprintf("%s/review/%s", e.baseURL, id)
|
|
||||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return moviestore.Review{}, err
|
|
||||||
}
|
|
||||||
req.Header.Add("Authorization", e.apiKey)
|
|
||||||
|
|
||||||
resp, err := e.c.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return moviestore.Review{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return moviestore.Review{}, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
var review moviestore.Review
|
|
||||||
if err := json.Unmarshal(body, &review); err != nil {
|
|
||||||
return moviestore.Review{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return review, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *EMDB) GetNextUnratedReview() (moviestore.Review, error) {
|
|
||||||
url := fmt.Sprintf("%s/review/unrated/next", e.baseURL)
|
|
||||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return moviestore.Review{}, err
|
|
||||||
}
|
|
||||||
req.Header.Add("Authorization", e.apiKey)
|
|
||||||
|
|
||||||
resp, err := e.c.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return moviestore.Review{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return moviestore.Review{}, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
var review moviestore.Review
|
|
||||||
if err := json.Unmarshal(body, &review); err != nil {
|
|
||||||
return moviestore.Review{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return review, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *EMDB) UpdateReview(review moviestore.Review) error {
|
|
||||||
body, err := json.Marshal(review)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
url := fmt.Sprintf("%s/review/%s", e.baseURL, review.ID)
|
|
||||||
req, err := http.NewRequest(http.MethodPut, url, bytes.NewReader(body))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
req.Header.Add("Authorization", e.apiKey)
|
|
||||||
|
|
||||||
resp, err := e.c.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
|
|
||||||
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *EMDB) CreateJob(movieID, action string) error {
|
|
||||||
j := struct {
|
|
||||||
MovieID string
|
|
||||||
Action string
|
|
||||||
}{
|
|
||||||
MovieID: movieID,
|
|
||||||
Action: action,
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := json.Marshal(j)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
url := fmt.Sprintf("%s/job", e.baseURL)
|
|
||||||
req, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(body))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
req.Header.Add("Authorization", e.apiKey)
|
|
||||||
|
|
||||||
resp, err := e.c.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
|
|
||||||
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *EMDB) GetNextAIJob() (moviestore.Job, error) {
|
|
||||||
url := fmt.Sprintf("%s/job/next-ai", e.baseURL)
|
|
||||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return moviestore.Job{}, err
|
|
||||||
}
|
|
||||||
req.Header.Add("Authorization", e.apiKey)
|
|
||||||
|
|
||||||
resp, err := e.c.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return moviestore.Job{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return moviestore.Job{}, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := io.ReadAll(resp.Body)
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
var j moviestore.Job
|
|
||||||
if err := json.Unmarshal(body, &j); err != nil {
|
|
||||||
return moviestore.Job{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return j, nil
|
|
||||||
}
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"code.ewintr.nl/emdb/cmd/api-service/moviestore"
|
|
||||||
"code.ewintr.nl/emdb/job"
|
"code.ewintr.nl/emdb/job"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -47,7 +46,7 @@ func (jobAPI *JobAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
func (jobAPI *JobAPI) Add(w http.ResponseWriter, r *http.Request) {
|
func (jobAPI *JobAPI) Add(w http.ResponseWriter, r *http.Request) {
|
||||||
logger := jobAPI.logger.With("method", "add")
|
logger := jobAPI.logger.With("method", "add")
|
||||||
|
|
||||||
var j moviestore.Job
|
var j job.Job
|
||||||
if err := json.NewDecoder(r.Body).Decode(&j); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&j); err != nil {
|
||||||
Error(w, http.StatusBadRequest, "could not decode job", err, logger)
|
Error(w, http.StatusBadRequest, "could not decode job", err, logger)
|
||||||
return
|
return
|
||||||
|
@ -82,7 +81,7 @@ func (jobAPI *JobAPI) List(w http.ResponseWriter, r *http.Request) {
|
||||||
func (jobAPI *JobAPI) NextAI(w http.ResponseWriter, r *http.Request) {
|
func (jobAPI *JobAPI) NextAI(w http.ResponseWriter, r *http.Request) {
|
||||||
logger := jobAPI.logger.With("method", "nextai")
|
logger := jobAPI.logger.With("method", "nextai")
|
||||||
|
|
||||||
j, err := jobAPI.jq.Next(moviestore.TypeAI)
|
j, err := jobAPI.jq.Next(job.TypeAI)
|
||||||
switch {
|
switch {
|
||||||
case errors.Is(err, sql.ErrNoRows):
|
case errors.Is(err, sql.ErrNoRows):
|
||||||
logger.Info("no ai jobs found")
|
logger.Info("no ai jobs found")
|
|
@ -26,7 +26,6 @@ func NewMovieAPI(apis APIIndex, repo *moviestore.MovieRepository, jq *job.JobQue
|
||||||
return &MovieAPI{
|
return &MovieAPI{
|
||||||
apis: apis,
|
apis: apis,
|
||||||
repo: repo,
|
repo: repo,
|
||||||
jq: jq,
|
|
||||||
logger: logger.With("api", "movie"),
|
logger: logger.With("api", "movie"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
package moviestore
|
|
||||||
|
|
||||||
import (
|
|
||||||
"slices"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type JobStatus string
|
|
||||||
type JobType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
interval = 20 * time.Second
|
|
||||||
|
|
||||||
TypeSimple JobType = "simple"
|
|
||||||
TypeAI JobType = "ai"
|
|
||||||
|
|
||||||
ActionRefreshIMDBReviews = "refresh-imdb-reviews"
|
|
||||||
ActionRefreshAllIMDBReviews = "refresh-all-imdb-reviews"
|
|
||||||
ActionFindTitles = "find-titles"
|
|
||||||
ActionFindAllTitles = "find-all-titles"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
SimpleActions = []string{
|
|
||||||
ActionRefreshIMDBReviews,
|
|
||||||
ActionRefreshAllIMDBReviews, // just creates a job for each movie
|
|
||||||
ActionFindAllTitles, // just creates a job for each review
|
|
||||||
}
|
|
||||||
AIActions = []string{
|
|
||||||
ActionFindTitles,
|
|
||||||
}
|
|
||||||
|
|
||||||
ValidActions = append(SimpleActions, AIActions...)
|
|
||||||
)
|
|
||||||
|
|
||||||
type Job struct {
|
|
||||||
ID int
|
|
||||||
ActionID string
|
|
||||||
Action string
|
|
||||||
Status JobStatus
|
|
||||||
Created time.Time
|
|
||||||
Updated time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func Valid(action string) bool {
|
|
||||||
if slices.Contains(ValidActions, action) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
46
job/job.go
46
job/job.go
|
@ -1,7 +1,51 @@
|
||||||
package job
|
package job
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"slices"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type JobStatus string
|
||||||
|
type JobType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
interval = 20 * time.Second
|
interval = 20 * time.Second
|
||||||
|
|
||||||
|
TypeSimple JobType = "simple"
|
||||||
|
TypeAI JobType = "ai"
|
||||||
|
|
||||||
|
ActionRefreshIMDBReviews = "refresh-imdb-reviews"
|
||||||
|
ActionRefreshAllIMDBReviews = "refresh-all-imdb-reviews"
|
||||||
|
ActionFindTitles = "find-titles"
|
||||||
|
ActionFindAllTitles = "find-all-titles"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
SimpleActions = []string{
|
||||||
|
ActionRefreshIMDBReviews,
|
||||||
|
ActionRefreshAllIMDBReviews, // just creates a job for each movie
|
||||||
|
ActionFindAllTitles, // just creates a job for each review
|
||||||
|
}
|
||||||
|
AIActions = []string{
|
||||||
|
ActionFindTitles,
|
||||||
|
}
|
||||||
|
|
||||||
|
ValidActions = append(SimpleActions, AIActions...)
|
||||||
|
)
|
||||||
|
|
||||||
|
type Job struct {
|
||||||
|
ID int
|
||||||
|
ActionID string
|
||||||
|
Action string
|
||||||
|
Status JobStatus
|
||||||
|
Created time.Time
|
||||||
|
Updated time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func Valid(action string) bool {
|
||||||
|
if slices.Contains(ValidActions, action) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
23
job/queue.go
23
job/queue.go
|
@ -8,7 +8,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.ewintr.nl/emdb/cmd/api-service/moviestore"
|
|
||||||
"code.ewintr.nl/emdb/storage"
|
"code.ewintr.nl/emdb/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -47,7 +46,7 @@ WHERE status = 'doing'
|
||||||
}
|
}
|
||||||
|
|
||||||
func (jq *JobQueue) Add(movieID, action string) error {
|
func (jq *JobQueue) Add(movieID, action string) error {
|
||||||
if !moviestore.Valid(action) {
|
if !Valid(action) {
|
||||||
return errors.New("invalid action")
|
return errors.New("invalid action")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,12 +57,12 @@ VALUES ($1, $2, 'todo');`, movieID, action)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (jq *JobQueue) Next(t moviestore.JobType) (moviestore.Job, error) {
|
func (jq *JobQueue) Next(t JobType) (Job, error) {
|
||||||
logger := jq.logger.With("method", "next")
|
logger := jq.logger.With("method", "next")
|
||||||
|
|
||||||
actions := moviestore.SimpleActions
|
actions := SimpleActions
|
||||||
if t == moviestore.TypeAI {
|
if t == TypeAI {
|
||||||
actions = moviestore.AIActions
|
actions = AIActions
|
||||||
}
|
}
|
||||||
actionsStr := fmt.Sprintf("('%s')", strings.Join(actions, "', '"))
|
actionsStr := fmt.Sprintf("('%s')", strings.Join(actions, "', '"))
|
||||||
query := fmt.Sprintf(`
|
query := fmt.Sprintf(`
|
||||||
|
@ -74,13 +73,13 @@ WHERE status='todo'
|
||||||
ORDER BY id ASC
|
ORDER BY id ASC
|
||||||
LIMIT 1;`, actionsStr)
|
LIMIT 1;`, actionsStr)
|
||||||
row := jq.db.QueryRow(query)
|
row := jq.db.QueryRow(query)
|
||||||
var job moviestore.Job
|
var job Job
|
||||||
err := row.Scan(&job.ID, &job.ActionID, &job.Action)
|
err := row.Scan(&job.ID, &job.ActionID, &job.Action)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(err, sql.ErrNoRows) {
|
if !errors.Is(err, sql.ErrNoRows) {
|
||||||
logger.Error("could not fetch next job", "error", err)
|
logger.Error("could not fetch next job", "error", err)
|
||||||
}
|
}
|
||||||
return moviestore.Job{}, err
|
return Job{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("found a job", "id", job.ID)
|
logger.Info("found a job", "id", job.ID)
|
||||||
|
@ -89,7 +88,7 @@ UPDATE job_queue
|
||||||
SET status='doing'
|
SET status='doing'
|
||||||
WHERE id=$1;`, job.ID); err != nil {
|
WHERE id=$1;`, job.ID); err != nil {
|
||||||
logger.Error("could not set job to doing", "error")
|
logger.Error("could not set job to doing", "error")
|
||||||
return moviestore.Job{}, err
|
return Job{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return job, nil
|
return job, nil
|
||||||
|
@ -116,7 +115,7 @@ WHERE id=$1;`, id); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (jq *JobQueue) List() ([]moviestore.Job, error) {
|
func (jq *JobQueue) List() ([]Job, error) {
|
||||||
rows, err := jq.db.Query(`
|
rows, err := jq.db.Query(`
|
||||||
SELECT id, action_id, action, status, created_at, updated_at
|
SELECT id, action_id, action, status, created_at, updated_at
|
||||||
FROM job_queue
|
FROM job_queue
|
||||||
|
@ -126,9 +125,9 @@ ORDER BY id DESC;`)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
var jobs []moviestore.Job
|
var jobs []Job
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var j moviestore.Job
|
var j Job
|
||||||
if err := rows.Scan(&j.ID, &j.ActionID, &j.Action, &j.Status, &j.Created, &j.Updated); err != nil {
|
if err := rows.Scan(&j.ID, &j.ActionID, &j.Action, &j.Status, &j.Created, &j.Updated); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ func (w *Worker) Run() {
|
||||||
logger.Info("starting worker")
|
logger.Info("starting worker")
|
||||||
for {
|
for {
|
||||||
time.Sleep(interval)
|
time.Sleep(interval)
|
||||||
j, err := w.jq.Next(moviestore.TypeSimple)
|
j, err := w.jq.Next(TypeSimple)
|
||||||
switch {
|
switch {
|
||||||
case errors.Is(err, sql.ErrNoRows):
|
case errors.Is(err, sql.ErrNoRows):
|
||||||
logger.Info("no simple jobs found")
|
logger.Info("no simple jobs found")
|
||||||
|
@ -45,11 +45,11 @@ func (w *Worker) Run() {
|
||||||
|
|
||||||
logger.Info("got a new job", "jobID", j.ID, "movieID", j.ActionID, "action", j.Action)
|
logger.Info("got a new job", "jobID", j.ID, "movieID", j.ActionID, "action", j.Action)
|
||||||
switch j.Action {
|
switch j.Action {
|
||||||
case moviestore.ActionRefreshIMDBReviews:
|
case ActionRefreshIMDBReviews:
|
||||||
w.RefreshReviews(j.ID, j.ActionID)
|
w.RefreshReviews(j.ID, j.ActionID)
|
||||||
case moviestore.ActionRefreshAllIMDBReviews:
|
case ActionRefreshAllIMDBReviews:
|
||||||
w.RefreshAllReviews(j.ID)
|
w.RefreshAllReviews(j.ID)
|
||||||
case moviestore.ActionFindAllTitles:
|
case ActionFindAllTitles:
|
||||||
w.FindAllTitles(j.ID)
|
w.FindAllTitles(j.ID)
|
||||||
default:
|
default:
|
||||||
logger.Error("unknown job action", "action", j.Action)
|
logger.Error("unknown job action", "action", j.Action)
|
||||||
|
@ -68,7 +68,7 @@ func (w *Worker) RefreshAllReviews(jobID int) {
|
||||||
|
|
||||||
for _, m := range movies {
|
for _, m := range movies {
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
if err := w.jq.Add(m.ID, moviestore.ActionRefreshIMDBReviews); err != nil {
|
if err := w.jq.Add(m.ID, ActionRefreshIMDBReviews); err != nil {
|
||||||
logger.Error("could not add job", "error", err)
|
logger.Error("could not add job", "error", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ func (w *Worker) FindAllTitles(jobID int) {
|
||||||
|
|
||||||
for _, r := range reviews {
|
for _, r := range reviews {
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
if err := w.jq.Add(r.ID, moviestore.ActionFindTitles); err != nil {
|
if err := w.jq.Add(r.ID, ActionFindTitles); err != nil {
|
||||||
logger.Error("could not add job", "error", err)
|
logger.Error("could not add job", "error", err)
|
||||||
w.jq.MarkFailed(jobID)
|
w.jq.MarkFailed(jobID)
|
||||||
return
|
return
|
||||||
|
@ -130,7 +130,7 @@ func (w *Worker) RefreshReviews(jobID int, movieID string) {
|
||||||
w.jq.MarkFailed(jobID)
|
w.jq.MarkFailed(jobID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := w.jq.Add(review.ID, moviestore.ActionFindTitles); err != nil {
|
if err := w.jq.Add(review.ID, ActionFindTitles); err != nil {
|
||||||
logger.Error("could not add job", "error", err)
|
logger.Error("could not add job", "error", err)
|
||||||
w.jq.MarkFailed(jobID)
|
w.jq.MarkFailed(jobID)
|
||||||
return
|
return
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"code.ewintr.nl/emdb/client"
|
"code.ewintr.nl/emdb/client"
|
||||||
"code.ewintr.nl/emdb/cmd/api-service/moviestore"
|
|
||||||
"code.ewintr.nl/emdb/job"
|
"code.ewintr.nl/emdb/job"
|
||||||
"code.ewintr.nl/emdb/storage"
|
"code.ewintr.nl/emdb/storage"
|
||||||
"github.com/charmbracelet/bubbles/list"
|
"github.com/charmbracelet/bubbles/list"
|
||||||
|
@ -134,7 +133,7 @@ func (m *tabTMDB) ImportMovieCmd(movie Movie) tea.Cmd {
|
||||||
if err := m.movieRepo.Store(movie.m); err != nil {
|
if err := m.movieRepo.Store(movie.m); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := m.jobQueue.Add(movie.m.ID, string(moviestore.ActionRefreshIMDBReviews)); err != nil {
|
if err := m.jobQueue.Add(movie.m.ID, string(job.ActionRefreshIMDBReviews)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue