Guides

Polling

An interval on a query refetches it while it is observed. It runs from the end of the last fetch, pauses when the app is away and resumes when it returns.

An interval on a query#

Add interval to a query and the core refetches it while somebody is looking.

Show the code for Rust, Swift, Kotlin and TypeScript
rust
#[undra::query(key = "prices", interval = "30s")]
async fn prices(ctx: &Ctx) -> Result<Vec<Price>, ApiError> { .. }
swift
let prices = try PricesQueryHandle()          // fetches now, then 30 seconds after each fetch ends
// a screen that wants fresher data while it is visible:
.onAppear { prices.setPollInterval(.seconds(5)) }
.onDisappear { prices.setPollInterval(nil) }       // back to the query's own 30 seconds
kotlin
val prices = PricesQueryHandle.create()
DisposableEffect(Unit) { prices.setPollInterval(5.seconds); onDispose { prices.setPollInterval(null) } }
ts
const prices = await PricesQueryHandle.create();
useEffect(() => { void prices.setPollInterval(5000); return () => void prices.setPollInterval(null); }, []);

The shortest interval is one second; below that the compiler says to use a stream, which is the tool for real-time data (the opt-in ports have WebSocket and Server-Sent Events).

How it polls#

The next fetch is scheduled one interval after the end of the previous one, whether it succeeded or failed once its retries ran out. A fetch slower than the interval never overlaps the next, and a struggling server is asked less often rather than hammered.

SituationWhat happens
Nobody observes the entryno timer; the last observer going away cancels it
The app is in the background or inactivepaused, unless the query says poll_in_background
The device is offlinepaused
The app comes to the front, the network returnsthe usual triggers fire (a stale entry refetches, going online refetches everything observed) and polling continues from the end of that fetch
Several observersthe entry polls at the shortest interval any of them asked for, each new observer starting from the attribute's
A fetch failsretried with backoff as any query is, then the interval runs from the end; the error shows and the next success clears it

Time comes from the Clock and delays from the Timer port, so a test under undra::ports::fakes advances the clock and sees each poll, background pause included. The contract scenario S33 checks it on every platform with real timers.

Edit this page on GitHub