batch_image_queue.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package service
  2. import (
  3. "context"
  4. "net/http"
  5. "strings"
  6. "time"
  7. infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors"
  8. )
  9. var (
  10. ErrBatchImageQueueEmpty = infraerrors.New(http.StatusNotFound, "BATCH_IMAGE_QUEUE_EMPTY", "batch image queue is empty")
  11. ErrBatchImageAlreadyQueued = infraerrors.New(http.StatusConflict, "BATCH_IMAGE_ALREADY_QUEUED", "batch image job is already queued")
  12. ErrBatchImageLockNotAcquired = infraerrors.New(http.StatusConflict, "BATCH_IMAGE_LOCK_NOT_ACQUIRED", "batch image job lock was not acquired")
  13. ErrInvalidBatchImageQueuePayload = infraerrors.New(http.StatusBadRequest, "BATCH_IMAGE_QUEUE_INVALID_PAYLOAD", "invalid batch image queue payload")
  14. )
  15. type ReservedBatchImageJob struct {
  16. BatchID string
  17. }
  18. type BatchImageJobLock interface {
  19. Release(ctx context.Context) error
  20. }
  21. type BatchImageQueue interface {
  22. Enqueue(ctx context.Context, batchID string) error
  23. Reserve(ctx context.Context, blockTimeout time.Duration) (ReservedBatchImageJob, error)
  24. RequeueAfter(ctx context.Context, batchID string, delay time.Duration) error
  25. Ack(ctx context.Context, batchID string) error
  26. Heartbeat(ctx context.Context, batchID string) error
  27. MoveDueDelayedToReady(ctx context.Context, limit int) (int, error)
  28. RecoverStaleActive(ctx context.Context, staleAfter time.Duration, limit int) (int, error)
  29. TryAcquireJobLock(ctx context.Context, batchID string, ttl time.Duration) (BatchImageJobLock, bool, error)
  30. }
  31. type BatchImageService struct {
  32. repo BatchImageRepository
  33. queue BatchImageQueue
  34. }
  35. func NewBatchImageService(repo BatchImageRepository, queue BatchImageQueue) *BatchImageService {
  36. return &BatchImageService{repo: repo, queue: queue}
  37. }
  38. func (s *BatchImageService) EnqueueBatchImageJob(ctx context.Context, batchID string) error {
  39. if !IsValidBatchImageID(batchID) {
  40. return ErrInvalidBatchImageQueuePayload
  41. }
  42. if s == nil || s.queue == nil {
  43. return infraerrors.New(http.StatusInternalServerError, "BATCH_IMAGE_QUEUE_NOT_CONFIGURED", "batch image queue is not configured")
  44. }
  45. if s.repo != nil {
  46. if _, err := s.repo.GetBatchImageJobByBatchID(ctx, batchID); err != nil {
  47. return err
  48. }
  49. }
  50. return s.queue.Enqueue(ctx, batchID)
  51. }
  52. func IsValidBatchImageID(batchID string) bool {
  53. return strings.HasPrefix(batchID, "imgbatch_") && len(batchID) > len("imgbatch_")
  54. }