From 6c93dd77cab32903d8228d69cc615ed7eca46e56 Mon Sep 17 00:00:00 2001 From: Urban Hafner Date: Fri, 27 Dec 2024 16:43:48 +0100 Subject: [PATCH] Add retries for JavaScript requests JavaScript requests are now retries up to three times if they are GET requests. This should help with the timeouts we are seeing sometimes (esp. when a new machine is being provisioned). --- app/javascript/src/admin/graphs/BotSignUps.jsx | 3 ++- app/javascript/src/admin/graphs/CollectedInks.jsx | 3 ++- app/javascript/src/admin/graphs/CollectedPens.jsx | 3 ++- app/javascript/src/admin/graphs/CurrentlyInked.jsx | 3 ++- app/javascript/src/admin/graphs/SignUps.jsx | 3 ++- app/javascript/src/admin/graphs/Spam.jsx | 3 ++- app/javascript/src/admin/graphs/UsageRecords.jsx | 3 ++- app/javascript/src/admin/stats.jsx | 5 +++-- app/javascript/src/fetch.js | 12 +++++++++++- config/initializers/sentry.rb | 6 ++++++ fly.toml | 6 +++--- 11 files changed, 37 insertions(+), 13 deletions(-) diff --git a/app/javascript/src/admin/graphs/BotSignUps.jsx b/app/javascript/src/admin/graphs/BotSignUps.jsx index 135c73635..5a20c747f 100644 --- a/app/javascript/src/admin/graphs/BotSignUps.jsx +++ b/app/javascript/src/admin/graphs/BotSignUps.jsx @@ -3,11 +3,12 @@ import Highcharts from "highcharts"; import HighchartsReact from "highcharts-react-official"; import { Spinner } from "../components/Spinner"; +import { getRequest } from "../../fetch"; export const BotSignUps = () => { const [data, setData] = useState(null); useEffect(() => { - fetch("/admins/graphs/bot-signups.json") + getRequest("/admins/graphs/bot-signups.json") .then((res) => res.json()) .then((json) => setData(json)); }, []); diff --git a/app/javascript/src/admin/graphs/CollectedInks.jsx b/app/javascript/src/admin/graphs/CollectedInks.jsx index e1dd87e8f..a30045ae9 100644 --- a/app/javascript/src/admin/graphs/CollectedInks.jsx +++ b/app/javascript/src/admin/graphs/CollectedInks.jsx @@ -3,11 +3,12 @@ import Highcharts from "highcharts"; import HighchartsReact from "highcharts-react-official"; import { Spinner } from "../components/Spinner"; +import { getRequest } from "../../fetch"; export const CollectedInks = () => { const [data, setData] = useState(null); useEffect(() => { - fetch("/admins/graphs/collected-inks.json") + getRequest("/admins/graphs/collected-inks.json") .then((res) => res.json()) .then((json) => setData(json)); }, []); diff --git a/app/javascript/src/admin/graphs/CollectedPens.jsx b/app/javascript/src/admin/graphs/CollectedPens.jsx index 12167b483..908c20941 100644 --- a/app/javascript/src/admin/graphs/CollectedPens.jsx +++ b/app/javascript/src/admin/graphs/CollectedPens.jsx @@ -3,11 +3,12 @@ import Highcharts from "highcharts"; import HighchartsReact from "highcharts-react-official"; import { Spinner } from "../components/Spinner"; +import { getRequest } from "../../fetch"; export const CollectedPens = () => { const [data, setData] = useState(null); useEffect(() => { - fetch("/admins/graphs/collected-pens.json") + getRequest("/admins/graphs/collected-pens.json") .then((res) => res.json()) .then((json) => setData(json)); }, []); diff --git a/app/javascript/src/admin/graphs/CurrentlyInked.jsx b/app/javascript/src/admin/graphs/CurrentlyInked.jsx index 2ef57abd6..76a9af10f 100644 --- a/app/javascript/src/admin/graphs/CurrentlyInked.jsx +++ b/app/javascript/src/admin/graphs/CurrentlyInked.jsx @@ -3,11 +3,12 @@ import Highcharts from "highcharts"; import HighchartsReact from "highcharts-react-official"; import { Spinner } from "../components/Spinner"; +import { getRequest } from "../../fetch"; export const CurrentlyInked = () => { const [data, setData] = useState(null); useEffect(() => { - fetch("/admins/graphs/currently-inked.json") + getRequest("/admins/graphs/currently-inked.json") .then((res) => res.json()) .then((json) => setData(json)); }, []); diff --git a/app/javascript/src/admin/graphs/SignUps.jsx b/app/javascript/src/admin/graphs/SignUps.jsx index d3b3a9fc0..e88f6844d 100644 --- a/app/javascript/src/admin/graphs/SignUps.jsx +++ b/app/javascript/src/admin/graphs/SignUps.jsx @@ -3,11 +3,12 @@ import Highcharts from "highcharts"; import HighchartsReact from "highcharts-react-official"; import { Spinner } from "../components/Spinner"; +import { getRequest } from "../../fetch"; export const SignUps = () => { const [data, setData] = useState(null); useEffect(() => { - fetch("/admins/graphs/signups.json") + getRequest("/admins/graphs/signups.json") .then((res) => res.json()) .then((json) => setData(json)); }, []); diff --git a/app/javascript/src/admin/graphs/Spam.jsx b/app/javascript/src/admin/graphs/Spam.jsx index 6b19c2d6c..62dd85523 100644 --- a/app/javascript/src/admin/graphs/Spam.jsx +++ b/app/javascript/src/admin/graphs/Spam.jsx @@ -3,11 +3,12 @@ import Highcharts from "highcharts"; import HighchartsReact from "highcharts-react-official"; import { Spinner } from "../components/Spinner"; +import { getRequest } from "../../fetch"; export const Spam = () => { const [data, setData] = useState(null); useEffect(() => { - fetch("/admins/graphs/spam.json") + getRequest("/admins/graphs/spam.json") .then((res) => res.json()) .then((json) => setData(json)); }, []); diff --git a/app/javascript/src/admin/graphs/UsageRecords.jsx b/app/javascript/src/admin/graphs/UsageRecords.jsx index 79749767b..9733e9c24 100644 --- a/app/javascript/src/admin/graphs/UsageRecords.jsx +++ b/app/javascript/src/admin/graphs/UsageRecords.jsx @@ -3,11 +3,12 @@ import Highcharts from "highcharts"; import HighchartsReact from "highcharts-react-official"; import { Spinner } from "../components/Spinner"; +import { getRequest } from "../../fetch"; export const UsageRecords = () => { const [data, setData] = useState(null); useEffect(() => { - fetch("/admins/graphs/usage-records.json") + getRequest("/admins/graphs/usage-records.json") .then((res) => res.json()) .then((json) => setData(json)); }, []); diff --git a/app/javascript/src/admin/stats.jsx b/app/javascript/src/admin/stats.jsx index 3d20e10fe..887766410 100644 --- a/app/javascript/src/admin/stats.jsx +++ b/app/javascript/src/admin/stats.jsx @@ -1,5 +1,6 @@ import React, { useEffect, useState } from "react"; import { createRoot } from "react-dom/client"; +import { getRequest } from "../fetch"; document.addEventListener("DOMContentLoaded", () => { const elements = document.querySelectorAll(".stats"); @@ -31,7 +32,7 @@ const Stat = ({ id, arg }) => { async function load() { let url = `/admins/stats/${id}`; if (arg) url += `?arg=${arg}`; - const response = await fetch(url); + const response = await getRequest(url); const json = await response.json(); setData(json); setLoading(false); @@ -57,7 +58,7 @@ const ConditionalStat = ({ id, arg, href, template }) => { async function load() { let url = `/admins/stats/${id}`; if (arg) url += `?arg=${arg}`; - const response = await fetch(url); + const response = await getRequest(url); const json = await response.json(); setData(json); setLoading(false); diff --git a/app/javascript/src/fetch.js b/app/javascript/src/fetch.js index f5c848216..8f18d6e14 100644 --- a/app/javascript/src/fetch.js +++ b/app/javascript/src/fetch.js @@ -17,7 +17,11 @@ export function putRequest(path, body) { } function request(path, method, body) { - return fetch(path, { + return req(path, method, body); +} + +async function req(path, method, body, retries = 3) { + const response = await fetch(path, { credentials: "same-origin", method: method, body: JSON.stringify(body), @@ -27,6 +31,12 @@ function request(path, method, body) { "X-CSRF-Token": csrfToken() } }); + if (method === "GET" && response.status >= 500 && retries > 0) { + console.log("Retrying", path, method, body, retries); + return req(path, method, body, retries - 1); + } else { + return response; + } } const csrfToken = () => { diff --git a/config/initializers/sentry.rb b/config/initializers/sentry.rb index ff4dd3c18..f7e1ac05e 100644 --- a/config/initializers/sentry.rb +++ b/config/initializers/sentry.rb @@ -5,4 +5,10 @@ config.dsn = ENV["SENTRY_DSN"] config.enable_tracing = true config.enabled_patches << :faraday + + config.excluded_exceptions += + YAML.load_file(Rails.root.join("config", "honeybadger.yml")).dig( + "exceptions", + "ignore" + ) end diff --git a/fly.toml b/fly.toml index f8b3c38bf..24c66bde8 100644 --- a/fly.toml +++ b/fly.toml @@ -19,8 +19,8 @@ NEW_RELIC_APPLICATION_LOGGING_ENABLED = "false" NEW_RELIC_BROWSER_MONITORING_AUTO_INSTRUMENT = "false" NEW_RELIC_LOG = "stdout" RACK_ENV = "production" -RACK_TIMEOUT_SERVICE_TIMEOUT = "60" -RACK_TIMEOUT_WAIT_TIMEOUT = "0" # Disable the wait timeout +RACK_TIMEOUT_SERVICE_TIMEOUT = "25" +RACK_TIMEOUT_WAIT_TIMEOUT = "30" RAILS_ENV = "production" RAILS_LOG_TO_STDOUT = "enabled" RAILS_MAX_THREADS = "5" @@ -40,7 +40,7 @@ processes = ["web"] force_https = true auto_stop_machines = "suspend" auto_start_machines = true -min_machines_running = 3 +min_machines_running = 2 [http_service.concurrency] type = "requests" soft_limit = 4