From 5ea82ec48e3218a4ad2bfeed8424a0fd41a14b62 Mon Sep 17 00:00:00 2001 From: akash1810 Date: Tue, 5 Nov 2024 05:53:42 +0000 Subject: [PATCH 1/2] fix: Handle 429 responses from Google Chat API The Google Chat API has a rate limit of 60 requests per minute. Sleep for 1.5 seconds after a 429 response. See https://developers.google.com/workspace/chat/limits. --- src/google.rs | 36 ++++++++++++++++++++++++++++-------- src/main.rs | 4 ++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/google.rs b/src/google.rs index c69b640..839938f 100644 --- a/src/google.rs +++ b/src/google.rs @@ -1,5 +1,7 @@ use anyhow::{Context, Result}; +use log::info; use serde::{Deserialize, Serialize}; +use std::time; use url::Url; #[derive(Serialize, Deserialize, Debug)] @@ -40,15 +42,33 @@ impl GoogleChatMessage { .body(serde_json::to_string(&self)?) .header("User-Agent", "GU-PR-Bot") .send() - .await? - .text() - .await - .context(format!("Failed to get response from: {}", &webhook_url))?; + .await?; - serde_json::from_str(&response).context(format!( - "Failed to parse JSON when querying {}: {}", - &webhook_url, response - )) + if response + .status() + .eq(&reqwest::StatusCode::TOO_MANY_REQUESTS) + { + /* + Sleep for 1.5 seconds to avoid rate limiting, at 60 requests per minute. + See https://developers.google.com/workspace/chat/limits + */ + info!( + "Received {} response. Sleeping for 1.5 seconds before retrying", + response.status() + ); + tokio::time::sleep(time::Duration::from_millis(1500)).await; + Box::pin(self.send(webhook_url, thread_key)).await + } else { + let response_text = response + .text() + .await + .context(format!("Failed to get response from: {}", &webhook_url))?; + + serde_json::from_str(&response_text).context(format!( + "Failed to parse JSON when querying {}: {}", + &webhook_url, response_text + )) + } } } diff --git a/src/main.rs b/src/main.rs index e136030..f00804f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -193,6 +193,10 @@ async fn main() -> Result<(), Error> { .await?; for pull_request in pull_requests_to_review { + info!( + "Sending message for PR {} #{}", + pull_request.head.repo.name, pull_request.number + ); GoogleChatMessage::from(make_message(pull_request, show_pr_age)) .send(&webhook_url, &thread_key) .await?; From 1b3c1e3bc5a6a10d3978996200d68e4b3c3c9772 Mon Sep 17 00:00:00 2001 From: akash1810 Date: Tue, 5 Nov 2024 08:42:09 +0000 Subject: [PATCH 2/2] fix: Attempt Chat API request max 3 times --- src/google.rs | 24 ++++++++++++++++-------- src/main.rs | 4 ++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/google.rs b/src/google.rs index 839938f..3943b0f 100644 --- a/src/google.rs +++ b/src/google.rs @@ -34,7 +34,13 @@ impl GoogleChatMessage { Ok(updated_url.as_str().to_string()) } - pub async fn send(self, webhook_url: &str, thread_key: &str) -> Result { + pub async fn send( + self, + webhook_url: &str, + thread_key: &str, + attempt: i32, + ) -> Result { + let max_attempts = 3; let url = GoogleChatMessage::build_webhook_url(webhook_url, thread_key)?; let response = reqwest::Client::new() @@ -47,22 +53,24 @@ impl GoogleChatMessage { if response .status() .eq(&reqwest::StatusCode::TOO_MANY_REQUESTS) + && attempt < max_attempts { /* Sleep for 1.5 seconds to avoid rate limiting, at 60 requests per minute. See https://developers.google.com/workspace/chat/limits */ info!( - "Received {} response. Sleeping for 1.5 seconds before retrying", - response.status() + "Received {} response. Sleeping for 1.5 seconds before retrying (attempt {})", + response.status(), + attempt ); tokio::time::sleep(time::Duration::from_millis(1500)).await; - Box::pin(self.send(webhook_url, thread_key)).await + Box::pin(self.send(webhook_url, thread_key, attempt + 1)).await } else { - let response_text = response - .text() - .await - .context(format!("Failed to get response from: {}", &webhook_url))?; + let response_text = response.text().await.context(format!( + "Failed to get response from: {} after {} attempts", + &webhook_url, attempt + ))?; serde_json::from_str(&response_text).context(format!( "Failed to parse JSON when querying {}: {}", diff --git a/src/main.rs b/src/main.rs index f00804f..a4e7262 100644 --- a/src/main.rs +++ b/src/main.rs @@ -189,7 +189,7 @@ async fn main() -> Result<(), Error> { info!("Using thread key {}", thread_key); GoogleChatMessage::from(message) - .send(&webhook_url, &thread_key) + .send(&webhook_url, &thread_key, 0) .await?; for pull_request in pull_requests_to_review { @@ -198,7 +198,7 @@ async fn main() -> Result<(), Error> { pull_request.head.repo.name, pull_request.number ); GoogleChatMessage::from(make_message(pull_request, show_pr_age)) - .send(&webhook_url, &thread_key) + .send(&webhook_url, &thread_key, 0) .await?; } } else {