Skip to content

Phase 2: DocumentStore Scheduling Support #86

Description

@tinkermonkey

Extend DocumentStore.register_source() to accept scheduling parameters and add a get_sources_due_for_poll() query method needed by the Poller scheduler.

Requirements

  • Add poll_strategy: PollStrategy = PollStrategy.PULL and poll_interval_sec: int | None = None parameters to DocumentStore.register_source()
  • The INSERT statement in register_source() must pass these values into the sources table columns poll_strategy and poll_interval_sec
  • The existing INSERT OR IGNORE idempotency behavior must be preserved
  • Add get_sources_due_for_poll() -> list[dict] method that queries sources where: poll_strategy = 'pull' AND (last_fetched_at IS NULL OR datetime(last_fetched_at, '+' || poll_interval_sec || ' seconds') < datetime('now'))
  • Returned dicts must include at minimum: source_id, adapter_id, poll_interval_sec, last_fetched_at

Design Guidance

File to modify: src/context_library/storage/document_store.py

Current register_source signature (from codebase exploration):

def register_source(self, source_id: str, adapter_id: str, domain: Domain, origin_ref: str) -> None

New signature:

def register_source(
    self,
    source_id: str,
    adapter_id: str,
    domain: Domain,
    origin_ref: str,
    poll_strategy: PollStrategy = PollStrategy.PULL,
    poll_interval_sec: int | None = None,
) -> None

The SQLite sources table already has these columns (from the existing schema):

  • poll_strategy TEXT NOT NULL CHECK (poll_strategy IN ('push', 'pull', 'webhook'))
  • poll_interval_sec INTEGER
  • last_fetched_at DATETIME

No schema migration is required — the columns already exist.

get_sources_due_for_poll SQL pattern:

SELECT source_id, adapter_id, poll_interval_sec, last_fetched_at
FROM sources
WHERE poll_strategy = 'pull'
  AND poll_interval_sec IS NOT NULL
  AND (
    last_fetched_at IS NULL
    OR datetime(last_fetched_at, '+' || poll_interval_sec || ' seconds') < datetime('now')
  )

Import: Add from context_library.storage.models import PollStrategy (already imports Domain).

Existing update_last_fetched_at method is already implemented and used by the pipeline — the Poller will call this after each successful fetch.

Acceptance Criteria

  • register_source(..., poll_strategy=PollStrategy.PUSH) correctly persists 'push' in the sources.poll_strategy column
  • register_source(..., poll_interval_sec=3600) correctly persists 3600 in sources.poll_interval_sec
  • Calling register_source() twice with the same source_id does not raise an error (idempotency preserved)
  • get_sources_due_for_poll() returns a source with last_fetched_at IS NULL and poll_strategy='pull'
  • get_sources_due_for_poll() returns a source whose last_fetched_at + poll_interval_sec < now
  • get_sources_due_for_poll() does NOT return a source whose last_fetched_at + poll_interval_sec >= now
  • get_sources_due_for_poll() does NOT return sources with poll_strategy='push'
  • get_sources_due_for_poll() does NOT return sources with poll_interval_sec IS NULL
  • All existing DocumentStore tests continue to pass

Dependencies

Phase 1: Model Additions (PollStrategy + MessageMetadata)

Parent Issue

Part of #83

Discussion

This work is detailed in discussion 84

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions