2023-12-30 09:19:53 +01:00
|
|
|
package job
|
|
|
|
|
|
|
|
import (
|
2024-01-20 12:30:06 +01:00
|
|
|
"database/sql"
|
|
|
|
"errors"
|
2023-12-30 09:19:53 +01:00
|
|
|
"log/slog"
|
2024-01-20 12:30:06 +01:00
|
|
|
"time"
|
2023-12-30 09:19:53 +01:00
|
|
|
|
|
|
|
"ewintr.nl/emdb/client"
|
|
|
|
"ewintr.nl/emdb/cmd/api-service/moviestore"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Worker struct {
|
|
|
|
jq *JobQueue
|
|
|
|
movieRepo *moviestore.MovieRepository
|
|
|
|
reviewRepo *moviestore.ReviewRepository
|
|
|
|
imdb *client.IMDB
|
|
|
|
logger *slog.Logger
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewWorker(jq *JobQueue, movieRepo *moviestore.MovieRepository, reviewRepo *moviestore.ReviewRepository, imdb *client.IMDB, logger *slog.Logger) *Worker {
|
|
|
|
return &Worker{
|
|
|
|
jq: jq,
|
|
|
|
movieRepo: movieRepo,
|
|
|
|
reviewRepo: reviewRepo,
|
|
|
|
imdb: imdb,
|
|
|
|
logger: logger.With("service", "worker"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Worker) Run() {
|
2024-01-20 12:30:06 +01:00
|
|
|
logger := w.logger.With("method", "run")
|
|
|
|
logger.Info("starting worker")
|
|
|
|
for {
|
|
|
|
time.Sleep(interval)
|
2024-01-20 13:49:19 +01:00
|
|
|
j, err := w.jq.Next(moviestore.TypeSimple)
|
2024-01-20 12:30:06 +01:00
|
|
|
switch {
|
|
|
|
case errors.Is(err, sql.ErrNoRows):
|
|
|
|
logger.Info("no simple jobs found")
|
|
|
|
continue
|
|
|
|
case err != nil:
|
|
|
|
logger.Error("could not get next job", "error", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2024-01-20 13:24:42 +01:00
|
|
|
logger.Info("got a new job", "jobID", j.ID, "movieID", j.ActionID, "action", j.Action)
|
2023-12-30 09:19:53 +01:00
|
|
|
switch j.Action {
|
2024-01-20 13:49:19 +01:00
|
|
|
case moviestore.ActionRefreshIMDBReviews:
|
2024-01-20 13:24:42 +01:00
|
|
|
w.RefreshReviews(j.ID, j.ActionID)
|
2024-01-20 13:49:19 +01:00
|
|
|
case moviestore.ActionRefreshAllIMDBReviews:
|
2023-12-30 09:19:53 +01:00
|
|
|
w.RefreshAllReviews(j.ID)
|
2024-01-20 13:49:19 +01:00
|
|
|
case moviestore.ActionFindAllTitles:
|
2024-01-20 13:24:42 +01:00
|
|
|
w.FindAllTitles(j.ID)
|
2023-12-30 09:19:53 +01:00
|
|
|
default:
|
2024-01-20 12:30:06 +01:00
|
|
|
logger.Error("unknown job action", "action", j.Action)
|
2023-12-30 09:19:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *Worker) RefreshAllReviews(jobID int) {
|
|
|
|
logger := w.logger.With("method", "fetchReviews", "jobID", jobID)
|
|
|
|
|
|
|
|
movies, err := w.movieRepo.FindAll()
|
|
|
|
if err != nil {
|
|
|
|
logger.Error("could not get movies", "error", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, m := range movies {
|
2024-01-20 13:24:42 +01:00
|
|
|
time.Sleep(1 * time.Second)
|
2024-01-20 13:49:19 +01:00
|
|
|
if err := w.jq.Add(m.ID, moviestore.ActionRefreshIMDBReviews); err != nil {
|
2024-01-06 14:32:32 +01:00
|
|
|
logger.Error("could not add job", "error", err)
|
|
|
|
return
|
|
|
|
}
|
2023-12-30 09:19:53 +01:00
|
|
|
}
|
2024-01-18 07:47:36 +01:00
|
|
|
|
|
|
|
logger.Info("refresh all reviews", "count", len(movies))
|
|
|
|
w.jq.MarkDone(jobID)
|
2023-12-30 09:19:53 +01:00
|
|
|
}
|
|
|
|
|
2024-01-20 13:24:42 +01:00
|
|
|
func (w *Worker) FindAllTitles(jobID int) {
|
|
|
|
logger := w.logger.With("method", "findTitles", "jobID", jobID)
|
|
|
|
|
|
|
|
reviews, err := w.reviewRepo.FindAll()
|
|
|
|
if err != nil {
|
|
|
|
logger.Error("could not get reviews", "error", err)
|
|
|
|
w.jq.MarkFailed(jobID)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, r := range reviews {
|
|
|
|
time.Sleep(1 * time.Second)
|
2024-01-20 13:49:19 +01:00
|
|
|
if err := w.jq.Add(r.ID, moviestore.ActionFindTitles); err != nil {
|
2024-01-20 13:24:42 +01:00
|
|
|
logger.Error("could not add job", "error", err)
|
|
|
|
w.jq.MarkFailed(jobID)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.Info("find all titles", "count", len(reviews))
|
|
|
|
w.jq.MarkDone(jobID)
|
|
|
|
}
|
|
|
|
|
2023-12-30 09:19:53 +01:00
|
|
|
func (w *Worker) RefreshReviews(jobID int, movieID string) {
|
|
|
|
logger := w.logger.With("method", "fetchReviews", "jobID", jobID, "movieID", movieID)
|
|
|
|
|
|
|
|
m, err := w.movieRepo.FindOne(movieID)
|
|
|
|
if err != nil {
|
|
|
|
logger.Error("could not get movie", "error", err)
|
2024-01-20 13:24:42 +01:00
|
|
|
w.jq.MarkFailed(jobID)
|
2023-12-30 09:19:53 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := w.reviewRepo.DeleteByMovieID(m.ID); err != nil {
|
|
|
|
logger.Error("could not delete reviews", "error", err)
|
2024-01-20 13:24:42 +01:00
|
|
|
w.jq.MarkFailed(jobID)
|
2023-12-30 09:19:53 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-01-17 07:57:52 +01:00
|
|
|
reviews, err := w.imdb.GetReviews(m)
|
2023-12-30 09:19:53 +01:00
|
|
|
if err != nil {
|
|
|
|
logger.Error("could not get reviews", "error", err)
|
2024-01-20 13:24:42 +01:00
|
|
|
w.jq.MarkFailed(jobID)
|
2023-12-30 09:19:53 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-01-17 07:57:52 +01:00
|
|
|
for _, review := range reviews {
|
|
|
|
if err := w.reviewRepo.Store(review); err != nil {
|
2023-12-30 09:19:53 +01:00
|
|
|
logger.Error("could not store review", "error", err)
|
2024-01-20 13:24:42 +01:00
|
|
|
w.jq.MarkFailed(jobID)
|
2023-12-30 09:19:53 +01:00
|
|
|
return
|
|
|
|
}
|
2024-01-20 14:04:55 +01:00
|
|
|
if err := w.jq.Add(review.ID, moviestore.ActionFindTitles); err != nil {
|
|
|
|
logger.Error("could not add job", "error", err)
|
|
|
|
w.jq.MarkFailed(jobID)
|
|
|
|
return
|
|
|
|
}
|
2023-12-30 09:19:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
logger.Info("refresh reviews", "count", len(reviews))
|
2024-01-18 07:47:36 +01:00
|
|
|
w.jq.MarkDone(jobID)
|
2023-12-30 09:19:53 +01:00
|
|
|
}
|