@@ -16,7 +16,9 @@ Three small additions to the data we already have:
1616pub struct WeatherSnapshot {
1717 pub temp_c : f32 ,
1818 pub condition : WeatherCondition ,
19- pub fetched_at : String ,
19+ /// Wall-clock time when the shell received the response. The shell
20+ /// stamps it; the core only compares it for the refresh throttle.
21+ pub fetched_at : std :: time :: SystemTime ,
2022}
2123
2224#[derive(Debug , Clone , Copy , PartialEq , Eq )]
@@ -78,10 +80,16 @@ done. Strongly typed end-to-end.
7880A small helper, used by both ` Increment ` and ` Decrement ` :
7981
8082``` rust
83+ const WEATHER_REFRESH_AFTER : Duration = Duration :: from_secs (10 );
84+
8185fn after_count_change (model : & mut Model ) -> Command <Effect , Event > {
8286 use crux_core :: render :: render;
8387 let render_cmd = render ();
84- if model . count % 10 == 0 && ! model . weather_in_flight {
88+ let should_fetch = model . count != 0
89+ && model . count % 10 == 0
90+ && ! model . weather_in_flight
91+ && weather_is_stale (model . last_weather. as_ref ());
92+ if should_fetch {
8593 model . weather_in_flight = true ;
8694 let fetch_cmd = Command :: request_from_shell (FetchMunichWeather )
8795 . then_send (Event :: WeatherLoaded );
@@ -90,14 +98,27 @@ fn after_count_change(model: &mut Model) -> Command<Effect, Event> {
9098 render_cmd
9199 }
92100}
101+
102+ fn weather_is_stale (last : Option <& WeatherSnapshot >) -> bool {
103+ match last {
104+ None => true ,
105+ Some (snap ) => SystemTime :: now ()
106+ . duration_since (snap . fetched_at)
107+ . map (| elapsed | elapsed >= WEATHER_REFRESH_AFTER )
108+ . unwrap_or (true ),
109+ }
110+ }
93111```
94112
95113- ` request_from_shell(...) ` — ask the shell to perform an effect.
96114- ` .then_send(Event::WeatherLoaded) ` — when the result comes back, wrap it
97115 in this event and feed it through ` update ` again.
98116- ` Command::all(...) ` — emit several commands at once.
99- - ` weather_in_flight ` is the guard that stops rapid clicks from firing
100- several requests concurrently.
117+ - ` weather_in_flight ` is the in-flight guard that stops rapid clicks from
118+ firing several requests concurrently.
119+ - ` weather_is_stale(...) ` is the time-based throttle. With both guards in
120+ place we never hammer the API: at most one request in flight, and never
121+ more than once every 10 seconds.
101122
102123## The new ` update `
103124
0 commit comments