Runs the whole flow once, as if an event arrived for an inactive guild: guild activation (premium tier + scripts from the db, fresh vm requested), event dispatch and waiting for the ack.
(&mut self)
| 160 | /// guild activation (premium tier + scripts from the db, fresh vm |
| 161 | /// requested), event dispatch and waiting for the ack. |
| 162 | pub async fn run_iteration(&mut self) -> anyhow::Result<FullFlowTimings> { |
| 163 | let started = Instant::now(); |
| 164 | |
| 165 | // mirrors GuildHandler::setup for a guild going active |
| 166 | let tier = self.fetch_premium_tier().await; |
| 167 | self.handler.set_premium_tier(PremiumTierState::Fetched(tier)); |
| 168 | self.handler.reload_guild_scripts().await; |
| 169 | |
| 170 | let vm_requested = started.elapsed(); |
| 171 | |
| 172 | let Some(mut ack_rx) = self |
| 173 | .handler |
| 174 | .send_discord_guild_event_tracked(message_create_event(self.guild_id)) |
| 175 | .await |
| 176 | else { |
| 177 | anyhow::bail!("the benchmark event was not dispatched"); |
| 178 | }; |
| 179 | |
| 180 | let event_acked = loop { |
| 181 | tokio::select! { |
| 182 | biased; |
| 183 | _ = &mut ack_rx => break started.elapsed(), |
| 184 | action = self.handler.next_event() => { |
| 185 | let Some(action) = action else { |
| 186 | anyhow::bail!("guild handler command channel closed during the bench"); |
| 187 | }; |
| 188 | if !self.handler.handle_next_action(action).await { |
| 189 | anyhow::bail!("vm session shut down before the event was acked"); |
| 190 | } |
| 191 | } |
| 192 | } |
| 193 | }; |
| 194 | |
| 195 | // tear the vm down between iterations so the next one starts cold |
| 196 | self.handler.shutdown().await; |
| 197 | |
| 198 | Ok(FullFlowTimings { |
| 199 | vm_requested, |
| 200 | event_acked, |
| 201 | }) |
| 202 | } |
| 203 | |
| 204 | async fn fetch_premium_tier(&self) -> Option<PremiumSlotTier> { |
| 205 | let Ok(slots) = self.db.get_guild_premium_slots(self.guild_id).await else { |
no test coverage detected