Skip to content

enhancement(connectors): add built-in HTTP retry with exponential backoff to AbstractConnector #8144

Closed

Description

@mrveiss

Problem

AbstractConnector has no retry mechanism in its base class. Each connector that makes HTTP requests (web crawler, Notion, audio, etc.) must implement its own retry logic or silently drop data on transient failures (429, 502, 503, 504). This leads to:

  • Inconsistent retry behavior across connectors
  • Silent data loss when a source returns a rate-limit or transient error
  • Connector authors having to reinvent backoff logic every time

Proposed Solution

Add fetch_with_retry() to AbstractConnector in knowledge/connectors/base.py:

async def fetch_with_retry(
    self,
    fetch_fn: Callable[[], Awaitable[T]],
    max_attempts: int = 5,
    backoff_base: float = 2.0,
    retryable_status: tuple[int, ...] = (429, 500, 502, 503, 504),
) -> T:
    ...

Subclasses override should_retry(exc) -> bool and backoff_time(attempt) -> float to customize. The default implementation handles network errors and standard HTTP transient status codes.

Also add two hook methods so individual connectors can opt out or customize:

def should_retry(self, exception: Exception) -> bool: ...
def backoff_time(self, attempt: int) -> float: ...

Files

  • autobot-backend/knowledge/connectors/base.py — add fetch_with_retry(), should_retry(), backoff_time()
  • autobot-backend/knowledge/connectors/web_crawler.py — migrate existing retry to base class call
  • autobot-backend/knowledge/connectors/models.py — add retry_attempts to SyncResult.errors entries for observability

Acceptance Criteria

  • AbstractConnector exposes fetch_with_retry() with configurable max attempts and base delay
  • Default behavior: exponential backoff on 429/5xx, up to 5 attempts
  • should_retry() and backoff_time() are overridable hooks
  • web_crawler.py migrated to use base class retry
  • Unit tests cover: success on first try, success after retry, exhausted retries, non-retryable errors

Activity

  1. github-actions commented on May 22, 2026

    @github-actions
    Contributor

    PR #8277 (merged to Dev_new_gui) references this issue with a close keyword.

    feat(connectors): HTTP retry, typed auth, mid-sync checkpoint (#8144, #8145, #8146)

    If this issue is fully resolved, close it manually. If work remains, no action is needed.

  2. mrveiss commented on May 22, 2026

    @mrveiss
    OwnerAuthor

    Implemented and merged via PR #8277 into Dev_new_gui. Closing.

  3. mrveiss commented on May 22, 2026

    @mrveiss
    OwnerAuthor

    ✅ Closed — implementation merged to Dev_new_gui

    Commit: be3c276 feat(connectors): HTTP retry, typed auth, mid-sync checkpoint (#8144, #8145, #8146)

    Acceptance Criteria Met:

    • ✅ AbstractConnector.fetch_with_retry() added — exponential backoff, configurable max_attempts/backoff_base/retryable_status
    • ✅ should_retry() and backoff_time() are overridable hooks on the base class
    • ✅ RetryableError exception class defined for connectors to signal transient failures
    • ✅ WebCrawlerConnector migrated: test_connection(), fetch_content(), _fetch_page_with_html() all use fetch_with_retry
    • ✅ connector_resilience_test.py covers success-first-try, success-after-retry, exhausted-retries, non-retryable-propagates

    Discovery follow-up (filed, not blocking closure):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions