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
#[undra::query(key = "prices", interval = "30s")]
async fn prices(ctx: &Ctx) -> Result<Vec<Price>, ApiError> { .. }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 secondsval prices = PricesQueryHandle.create()
DisposableEffect(Unit) { prices.setPollInterval(5.seconds); onDispose { prices.setPollInterval(null) } }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.
| Situation | What happens |
|---|---|
| Nobody observes the entry | no timer; the last observer going away cancels it |
| The app is in the background or inactive | paused, unless the query says poll_in_background |
| The device is offline | paused |
| The app comes to the front, the network returns | the usual triggers fire (a stale entry refetches, going online refetches everything observed) and polling continues from the end of that fetch |
| Several observers | the entry polls at the shortest interval any of them asked for, each new observer starting from the attribute's |
| A fetch fails | retried 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.