summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Smeding <tom@tomsmeding.com>2024-07-10 10:42:53 +0200
committerTom Smeding <tom@tomsmeding.com>2024-07-10 10:42:53 +0200
commitcd036edbac56cee8b367a3b2fbbfbbb18c3d3fde (patch)
treee154671057a8fd0db7b57bf6d74a2b22912e921d
parentbf4d2336f3083f22609dc28dfbc30bb21bed93e9 (diff)
statusbot: .well-known retry mechanism
-rw-r--r--modules/statusbot/statusbot.js65
1 files changed, 51 insertions, 14 deletions
diff --git a/modules/statusbot/statusbot.js b/modules/statusbot/statusbot.js
index da81d82..1af5804 100644
--- a/modules/statusbot/statusbot.js
+++ b/modules/statusbot/statusbot.js
@@ -110,6 +110,36 @@ class PRatelimit {
}
}
+// f: ((true, ...Args) => () | (false) => ()) => ()
+// cb: (true, ...Args) => () | (false) => ()
+// The callback to f should be invoked with 'true' plus further arguments if it
+// succeeded, and 'false' if it did not.
+// Based on this info, if f failed, f is retried a few times. Once ntimes has
+// been exhausted or a call succeeds, cb is invoked with respectively either
+// (false) or (true, ...args).
+function pretry(interval, multiplier, ntimes, f, cb) {
+ let tm = interval;
+ let ncalled = 0;
+
+ function schedule() {
+ setTimeout(() => {
+ f((success, ...args) => {
+ if (success) {
+ cb(true, ...args);
+ return;
+ }
+
+ ncalled++;
+ tm *= multiplier;
+ if (ncalled >= ntimes) cb(false);
+ else schedule();
+ });
+ }, tm);
+ }
+
+ schedule();
+}
+
// cb: (state) => ()
function augmentConfig(config, cb) {
const m = config.user_id.match(/^@[^:]+:(.*)$/);
@@ -126,20 +156,27 @@ function augmentConfig(config, cb) {
}
// wait a bit with requesting this in case the homeserver in question is the same server as us
- setTimeout(() => {
- fetch("GET", {}, home_server, "/.well-known/matrix/server", "", (status, body) => {
- if (status != 200) {
- throw new Error(`statusbot: Failed getting https://${home_server}/.well-known/matrix/server`);
- }
- const mserver = JSON.parse(body)["m.server"];
- const m = mserver.match(/^([^:]*)(:443)?$/);
- if (!m) {
- throw new Error(`statusbot: Matrix server port not 443 (sorry): <${mserver}>`);
- }
- const matrix_server = m[1];
- cb({config, home_server, matrix_server, access_token, req_counter});
- });
- }, 100);
+ pretry(500, 1.2, 10,
+ cb => {
+ fetch("GET", {}, home_server, "/.well-known/matrix/server", "", (status, body) => {
+ if (status != 200) {
+ cb(false); // attempt failed (perhaps a later attempt will succeed)
+ }
+ const mserver = JSON.parse(body)["m.server"];
+ const m = mserver.match(/^([^:]*)(:443)?$/);
+ if (!m) {
+ throw new Error(`statusbot: Matrix server port not 443 (sorry): <${mserver}>`);
+ }
+ const matrix_server = m[1];
+ // attempt succeeded!
+ cb(true, {config, home_server, matrix_server, access_token, req_counter});
+ });
+ },
+ (success, state) => {
+ if (success) cb(state);
+ else throw new Error(`statusbot: Failed getting https://${home_server}/.well-known/matrix/server`);
+ }
+ );
}
function updatePersist() {