How Read Frog’s Background Service Worker Manages Translation Queues and Asynchronous Tasks

Read Frog’s background service worker employs a dual-queue system—combining a rate-limited RequestQueue with a throughput-optimized BatchQueue—to process translation signals asynchronously, while leveraging IndexedDB caching to eliminate redundant API calls and respect provider rate limits.

The Read Frog browser extension (mengxi-ream/read-frog) centralizes its AI translation workloads within a dedicated background service worker located at src/entrypoints/background/translation-queues.ts. This architectural choice isolates heavy computational work from the UI thread, enabling the extension to handle high-volume translation requests, batch them for efficiency, and manage dynamic configuration changes without service interruption.

Dual Queue Architecture for Rate Control and Batching

The background service worker instantiates two complementary queue abstractions built atop the generic utilities in src/utils/request/. These queues cooperate to balance provider rate limits with throughput optimization.

RequestQueue: Individual Request Throttling

The RequestQueue manages rate-limited, retry-aware execution of individual translation thunks. Instantiated with configurable rate (requests per second), capacity (burst allowance), timeout, and retry settings, this queue prevents overwhelming AI providers like OpenAI or Anthropic. When the system determines a job cannot be batched, it creates a single-text thunk and enqueues it through this rate-limited pipeline, ensuring respectful API usage even under heavy load.

BatchQueue: Intelligent Job Grouping

The BatchQueue receives TranslateBatchData objects containing text, language configuration, provider details, scheduling timestamps, and content hashes. For batch-eligible jobs, it constructs a combined prompt by joining texts with \n\n + BATCH_SEPARATOR + \n\n, then enqueues the resulting thunk on the underlying RequestQueue. The batching logic respects maxCharactersPerBatch and maxItemsPerBatch limits; if thresholds are exceeded or batching fails, the system automatically falls back to individual RequestQueue submissions.

Signal Processing via Chrome Extension Messaging

The worker registers listeners using the thin onMessage wrapper around Chrome extension messaging (defined in src/utils/message.ts). These handlers translate UI signals into queued asynchronous tasks, enabling real-time communication between content scripts and the background worker.

enqueueTranslateRequest: Page-Level Translation Pipeline

When the content script emits an enqueueTranslateRequest signal, the worker first queries db.translationCache.get(hash) to check for cached results. For LLM providers, it optionally generates article summaries via getOrGenerateSummary, which itself uses the RequestQueue for caching and throttling to avoid redundant summary generation. Finally, the worker enqueues the validated request on the BatchQueue (or fallback RequestQueue) and persists the successful result back to IndexedDB.

enqueueSubtitlesTranslateRequest: Video Content Handling

The enqueueSubtitlesTranslateRequest handler mirrors the page-level flow for video subtitle translation, utilizing identical queue machinery and cache logic defined in src/entrypoints/background/translation-queues.ts. This ensures consistent rate limiting and batching behavior across different content types while maintaining separate data pipelines for web text versus timed subtitle data.

Dynamic Configuration Updates

The worker exposes runtime configuration endpoints that adjust behavior without requiring a service restart. The setTranslateRequestQueueConfig and setSubtitlesRequestQueueConfig handlers dynamically update RequestQueue parameters including rate and capacity, while setTranslateBatchQueueConfig and setSubtitlesBatchQueueConfig modify batch size limits and processing delays in real time.

Asynchronous Coordination and Caching Strategy

The background service worker achieves robust asynchronous coordination through three core mechanisms that ensure reliable task execution.

Thunk-Based Scheduling with Promise Resolution

Both RequestQueue.enqueue and BatchQueue.enqueue return Promises that resolve with translation results or batch result arrays. The queues manage scheduleAt timestamps to delay execution until specified times, while comprehensive error handling captures execution context—including batch keys and retry counts—for debugging and telemetry.

IndexedDB Caching Layer

Before initiating any network calls to executeTranslate (located in src/utils/host/translate/execute-translate.ts), the worker performs hash-based lookups in db.translationCache and db.articleSummaryCache (defined in src/utils/db/dexie/db.ts). Cache hits return immediately, bypassing the queue entirely and eliminating redundant async work. This pre-queue cache check occurs in the message handlers before any thunk creation.

Practical Implementation Examples

Enqueue a page-level translation from a content script:

chrome.runtime.sendMessage({
  type: "enqueueTranslateRequest",
  data: {
    text: "Hello world",
    langConfig: { sourceCode: "en", targetCode: "es" },
    providerConfig: { id: "openai", model: "gpt-4o" },
    scheduleAt: Date.now(),
    hash: "a1b2c3d4",
    articleTitle: "Greeting",
    articleTextContent: "Full article body …",
  },
});

Dynamically change the request-queue rate limit after user settings update:

chrome.runtime.sendMessage({
  type: "setTranslateRequestQueueConfig",
  data: { rate: 5, capacity: 20 },
});

Adjust batch size for subtitles processing without restarting the worker:

chrome.runtime.sendMessage({
  type: "setSubtitlesBatchQueueConfig",
  data: { maxCharactersPerBatch: 2000, maxItemsPerBatch: 10 },
});

Summary

  • The background service worker in src/entrypoints/background/translation-queues.ts orchestrates all translation work using cooperating RequestQueue and BatchQueue instances.
  • Rate limiting and retry logic are enforced at the individual request level, while batching reduces API call volume by grouping compatible jobs with a BATCH_SEPARATOR delimiter.
  • Signal processing occurs through Chrome extension messaging handlers that check IndexedDB caches before queuing new work, preventing unnecessary API calls.
  • Dynamic configuration allows runtime adjustment of queue parameters—including maxCharactersPerBatch and request rates—without service interruption.
  • The architecture supports both web page content and video subtitles through unified queue machinery while maintaining separate message handlers for each content type.

Frequently Asked Questions

How does the background service worker prevent duplicate translation API calls?

The worker checks db.translationCache.get(hash) immediately upon receiving an enqueueTranslateRequest signal. If a cached result exists for the content hash, the Promise resolves with the stored translation without entering the RequestQueue or BatchQueue, eliminating redundant network requests to the translation provider.

What happens when a translation job fails or exceeds rate limits?

The RequestQueue implements configurable retry logic with exponential backoff. Failed thunks are automatically re-enqueued up to the configured retry limit, with detailed error context (batch key, retry count) captured for debugging. If batch processing fails, the BatchQueue falls back to individual request queuing to maximize delivery success.

Can batch processing settings be adjusted without restarting the extension?

Yes. The worker listens for setTranslateBatchQueueConfig and setSubtitlesBatchQueueConfig messages, allowing dynamic updates to maxCharactersPerBatch, maxItemsPerBatch, and processing delays at runtime. Similarly, setTranslateRequestQueueConfig instantly updates rate limits and burst capacity without requiring a service worker restart.

How does Read Frog handle different content types like web pages versus video subtitles?

While both use the same underlying queue infrastructure in translation-queues.ts, the worker distinguishes content via separate message types: enqueueTranslateRequest for web content and enqueueSubtitlesTranslateRequest for video subtitles. Each handler applies appropriate preprocessing—including optional AI summary generation for articles—but funnels jobs through identical caching and queuing logic to ensure consistent performance.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →