mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-11-28 11:40:11 +03:00
api: exponential backoff when resubscribing
Use the new `lib/retry` to attempt to reconnect when clogged. If unsucessful after 5 attempts, stop retrying and log an error.
This commit is contained in:
parent
200b504c4e
commit
bf0f4e97c9
@ -14,6 +14,7 @@ import { Box, Col } from '@tlon/indigo-react';
|
||||
import { makeTheme } from './lib/theme';
|
||||
import { showBlit, csi } from './lib/blit';
|
||||
import { DEFAULT_SESSION } from './constants';
|
||||
import { retry } from './lib/retry';
|
||||
|
||||
const termConfig: ITerminalOptions = {
|
||||
logLevel: 'warn',
|
||||
@ -191,10 +192,16 @@ export default function Buffer({ name, selected, dark }: BufferProps) {
|
||||
},
|
||||
quit: async () => { // quit
|
||||
console.error('oops quit, reconnecting...');
|
||||
const newSubscriptionId = await initSubscription();
|
||||
useTermState.getState().set((state) => {
|
||||
state.sessions[name].subscriptionId = newSubscriptionId;
|
||||
});
|
||||
try {
|
||||
const newSubscriptionId = await retry(initSubscription, () => {
|
||||
console.log('attempting to reconnect ...');
|
||||
}, 5);
|
||||
useTermState.getState().set((state) => {
|
||||
state.sessions[name].subscriptionId = newSubscriptionId;
|
||||
});
|
||||
} catch (error) {
|
||||
console.log('unable to reconnect', error);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -11,7 +11,7 @@ export const DEFAULT_SESSION = '';
|
||||
export const SESSION_ID_REGEX = /(^[a-z]{1}[a-z\d-]*[a-z\d]{1}$)|(^[a-z]{1}$)/;
|
||||
|
||||
/**
|
||||
* Open a session with a given agent using `[agent]![session_name]
|
||||
* Open a session with a given agent using `[agent]![session_name]`
|
||||
*
|
||||
* For example:
|
||||
* ```
|
||||
|
39
pkg/interface/webterm/lib/retry.ts
Normal file
39
pkg/interface/webterm/lib/retry.ts
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Wait for the given milliseconds
|
||||
* @param {number} milliseconds The given time to wait
|
||||
* @returns {Promise} A fulfiled promise after the given time has passed
|
||||
*/
|
||||
function waitFor(milliseconds) {
|
||||
return new Promise(resolve => setTimeout(resolve, milliseconds));
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a promise and retry with exponential backoff
|
||||
* based on the maximum retry attempts it can perform
|
||||
* @param {Promise} promise promise to be executed
|
||||
* @param {function} onRetry callback executed on every retry
|
||||
* @param {number} maxRetries The maximum number of retries to be attempted
|
||||
* @returns {Promise} The result of the given promise passed in
|
||||
*/
|
||||
export function retry(promise, onRetry, maxRetries) {
|
||||
async function retryWithBackoff(retries) {
|
||||
try {
|
||||
if (retries > 0) {
|
||||
const timeToWait = 2 ** retries * 100;
|
||||
console.log(`waiting for ${timeToWait}ms...`);
|
||||
await waitFor(timeToWait);
|
||||
}
|
||||
return await promise();
|
||||
} catch (e) {
|
||||
if (retries < maxRetries) {
|
||||
onRetry();
|
||||
return retryWithBackoff(retries + 1);
|
||||
} else {
|
||||
console.warn('Max retries reached. Bubbling the error up');
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retryWithBackoff(0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user