Ctrl K
ComunidadGuías…

specs/004-feed-queue/tasks.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Feed Queue System - Tasks

## Phase 1: Data Model

- [ ] Add `FetchStatus` enum (IDLE, QUEUED, FETCHING)
- [ ] Add fields to Source entity:
  - `fetchStatus` (FetchStatus, default IDLE)
  - `refreshIntervalMinutes` (Integer, default 15)
  - `queuedAt` (LocalDateTime)
  - `fetchStartedAt` (LocalDateTime)
- [ ] Create Flyway migration V5__Feed_queue_support.sql
- [ ] Add index for scheduler query
- [ ] Update SourceDTO with new fields
- [ ] Update SourceCreateRequest/SourceUpdateRequest with `refreshIntervalMinutes`

## Phase 2: Queue Infrastructure

- [ ] Create `FetchQueue` interface
  - `enqueue(Long sourceId)`
  - `canAccept()`
  - `size()`
- [ ] Implement `InMemoryFetchQueue`
  - `BlockingQueue<Long>` with configurable capacity
  - Worker thread pool with configurable size
  - Graceful shutdown on application stop
- [ ] Add configuration properties:
  - `application.jobs.feed-ingestion.queue-capacity`
  - `application.jobs.feed-ingestion.worker-count`

## Phase 3: Worker Implementation

- [ ] Create `FetchWorker` component
  - Extract fetch logic from existing `FeedIngestionJob.processSource()`
  - Handle FETCHING status transitions
  - Handle success/error outcomes
  - Reset to IDLE after completion
- [ ] Add proper logging with source_id context
- [ ] Add metrics for fetch duration and success rate

## Phase 4: Scheduler Implementation

- [ ] Create `FeedSchedulerJob` (replaces scheduling logic in `FeedIngestionJob`)
  - Run every 1 minute
  - Query for sources due for refresh
  - Mark as QUEUED and enqueue
- [ ] Add repository method `findSourcesDueForRefresh()`
  - Native query with interval arithmetic
  - Order by lastFetchedAt NULLS FIRST
  - Limit to prevent queue overflow
- [ ] Add backpressure handling (skip cycle if queue full)

## Phase 5: Recovery & Reliability

- [ ] Create `StuckSourceRecoveryJob`
  - Run every 5 minutes
  - Reset QUEUED sources stuck > 10 minutes
  - Reset FETCHING sources stuck > 10 minutes
  - Log warnings for recovered sources
- [ ] Add repository methods:
  - `resetStuckQueuedSources(threshold)`
  - `resetStuckFetchingSources(threshold)`
  - `countStuckSources()`

## Phase 6: Observability

- [ ] Add `FetchQueueMetrics`
  - Gauge: queue size
  - Counter: enqueue operations
  - Counter: processed (success/failure)
  - Timer: processing duration
- [ ] Add `FetchQueueHealthIndicator`
  - DOWN if queue > 90% capacity
  - DOWN if > 10 stuck sources
- [ ] Update logging with structured fields

## Phase 7: Cleanup & Migration

- [ ] Remove old `FeedIngestionJob` (or rename to `FeedSchedulerJob`)
- [ ] Update configuration:
  - Change interval property names
  - Add new properties for queue/workers
- [ ] Update local development config
- [ ] Update existing tests

## Phase 8: Testing

- [ ] Unit tests:
  - `FetchWorkerTest` - status transitions, error handling
  - `InMemoryFetchQueueTest` - capacity, threading
  - `FeedSchedulerJobTest` - query logic, enqueue calls
  - `StuckSourceRecoveryJobTest` - recovery logic
- [ ] Integration tests:
  - `NewSourcePickupIT` - verify < 2 min pickup
  - `RefreshIntervalIT` - verify per-source intervals
  - `StuckRecoveryIT` - verify automatic recovery

## Phase 9: Documentation

- [ ] Update API documentation (Swagger annotations)
- [ ] Update CLAUDE.md if needed
- [ ] Add runbook for monitoring queue health