diff options
author | Tom Smeding <tom@tomsmeding.com> | 2024-07-10 10:42:53 +0200 |
---|---|---|
committer | Tom Smeding <tom@tomsmeding.com> | 2024-07-10 10:42:53 +0200 |
commit | cd036edbac56cee8b367a3b2fbbfbbb18c3d3fde (patch) | |
tree | e154671057a8fd0db7b57bf6d74a2b22912e921d /modules/statusbot | |
parent | bf4d2336f3083f22609dc28dfbc30bb21bed93e9 (diff) |
statusbot: .well-known retry mechanism
Diffstat (limited to 'modules/statusbot')
-rw-r--r-- | modules/statusbot/statusbot.js | 65 |
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() { |