Increase fallback Retry-After
time to 1 minute
This commit is contained in:
parent
b6287f4839
commit
05e5786883
4 changed files with 25 additions and 20 deletions
|
@ -1,19 +1,20 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
|
import { MINUTE } from '../../util/durations';
|
||||||
|
|
||||||
import { parseRetryAfter } from '../../util/parseRetryAfter';
|
import { parseRetryAfter } from '../../util/parseRetryAfter';
|
||||||
|
|
||||||
describe('parseRetryAfter', () => {
|
describe('parseRetryAfter', () => {
|
||||||
it('should return 1 second when passed non-strings', () => {
|
it('should return 1 minute when passed non-strings', () => {
|
||||||
assert.equal(parseRetryAfter(undefined), 1000);
|
assert.equal(parseRetryAfter(undefined), MINUTE);
|
||||||
assert.equal(parseRetryAfter(1234), 1000);
|
assert.equal(parseRetryAfter(1234), MINUTE);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 1 second with invalid strings', () => {
|
it('should return 1 minute with invalid strings', () => {
|
||||||
assert.equal(parseRetryAfter('nope'), 1000);
|
assert.equal(parseRetryAfter('nope'), MINUTE);
|
||||||
assert.equal(parseRetryAfter('1ff'), 1000);
|
assert.equal(parseRetryAfter('1ff'), MINUTE);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return milliseconds on valid input', () => {
|
it('should return milliseconds on valid input', () => {
|
||||||
|
|
|
@ -5,15 +5,18 @@ import { assert } from 'chai';
|
||||||
|
|
||||||
import { findRetryAfterTimeFromError } from '../../../jobs/helpers/findRetryAfterTimeFromError';
|
import { findRetryAfterTimeFromError } from '../../../jobs/helpers/findRetryAfterTimeFromError';
|
||||||
import { HTTPError } from '../../../textsecure/Errors';
|
import { HTTPError } from '../../../textsecure/Errors';
|
||||||
|
import { MINUTE } from '../../../util/durations';
|
||||||
|
|
||||||
describe('findRetryAfterTimeFromError', () => {
|
describe('findRetryAfterTimeFromError', () => {
|
||||||
it('returns 1 second if no Retry-After time is found', () => {
|
it('returns 1 minute if no Retry-After time is found', () => {
|
||||||
[
|
[
|
||||||
undefined,
|
undefined,
|
||||||
null,
|
null,
|
||||||
{},
|
{},
|
||||||
{ responseHeaders: {} },
|
{ responseHeaders: {} },
|
||||||
{ responseHeaders: { 'retry-after': 'garbage' } },
|
{ responseHeaders: { 'retry-after': 'garbage' } },
|
||||||
|
{ responseHeaders: { 'retry-after': '0.5' } },
|
||||||
|
{ responseHeaders: { 'retry-after': '12.34' } },
|
||||||
{
|
{
|
||||||
httpError: new HTTPError('Slow down', {
|
httpError: new HTTPError('Slow down', {
|
||||||
code: 413,
|
code: 413,
|
||||||
|
@ -29,20 +32,20 @@ describe('findRetryAfterTimeFromError', () => {
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
].forEach(input => {
|
].forEach(input => {
|
||||||
assert.strictEqual(findRetryAfterTimeFromError(input), 1000);
|
assert.strictEqual(findRetryAfterTimeFromError(input), MINUTE);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns 1 second if a Retry-After time is found, but it's less than 1 second", () => {
|
it("returns 1 second if a Retry-After time is found, but it's less than 1 second", () => {
|
||||||
['0', '-99', '0.5'].forEach(headerValue => {
|
['0', '-99'].forEach(headerValue => {
|
||||||
const input = { responseHeaders: { 'retry-after': headerValue } };
|
const input = { responseHeaders: { 'retry-after': headerValue } };
|
||||||
assert.strictEqual(findRetryAfterTimeFromError(input), 1000);
|
assert.strictEqual(findRetryAfterTimeFromError(input), 1000);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns 1 second for extremely large numbers', () => {
|
it('returns 1 minute for extremely large numbers', () => {
|
||||||
const input = { responseHeaders: { 'retry-after': '999999999999999999' } };
|
const input = { responseHeaders: { 'retry-after': '999999999999999999' } };
|
||||||
assert.strictEqual(findRetryAfterTimeFromError(input), 1000);
|
assert.strictEqual(findRetryAfterTimeFromError(input), MINUTE);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('finds the retry-after time on top-level response headers', () => {
|
it('finds the retry-after time on top-level response headers', () => {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2021 Signal Messenger, LLC
|
// Copyright 2021-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { assert } from 'chai';
|
import { assert } from 'chai';
|
||||||
|
@ -39,19 +39,19 @@ describe('sleepFor413RetryAfterTimeIfApplicable', () => {
|
||||||
sinon.assert.notCalled(log.info);
|
sinon.assert.notCalled(log.info);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('waits for 1 second if the error lacks Retry-After info', async () => {
|
it('waits for 1 minute if the error lacks Retry-After info', async () => {
|
||||||
let done = false;
|
let done = false;
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
await sleepFor413RetryAfterTime({
|
await sleepFor413RetryAfterTime({
|
||||||
err: {},
|
err: {},
|
||||||
log: createLogger(),
|
log: createLogger(),
|
||||||
timeRemaining: 1234,
|
timeRemaining: 12345678,
|
||||||
});
|
});
|
||||||
done = true;
|
done = true;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
await clock.tickAsync(999);
|
await clock.tickAsync(durations.MINUTE - 1);
|
||||||
assert.isFalse(done);
|
assert.isFalse(done);
|
||||||
|
|
||||||
await clock.tickAsync(2);
|
await clock.tickAsync(2);
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
// Copyright 2021-2022 Signal Messenger, LLC
|
// Copyright 2021-2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import { SECOND } from './durations';
|
import { SECOND, MINUTE } from './durations';
|
||||||
import { isNormalNumber } from './isNormalNumber';
|
import { isNormalNumber } from './isNormalNumber';
|
||||||
|
|
||||||
|
const DEFAULT_RETRY_AFTER = MINUTE;
|
||||||
const MINIMAL_RETRY_AFTER = SECOND;
|
const MINIMAL_RETRY_AFTER = SECOND;
|
||||||
|
|
||||||
export function parseRetryAfter(value: unknown): number {
|
export function parseRetryAfter(value: unknown): number {
|
||||||
if (typeof value !== 'string') {
|
if (typeof value !== 'string') {
|
||||||
return MINIMAL_RETRY_AFTER;
|
return DEFAULT_RETRY_AFTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
let retryAfter = parseInt(value, 10);
|
const retryAfter = parseInt(value, 10);
|
||||||
if (!isNormalNumber(retryAfter) || retryAfter.toString() !== value) {
|
if (!isNormalNumber(retryAfter) || retryAfter.toString() !== value) {
|
||||||
retryAfter = 0;
|
return DEFAULT_RETRY_AFTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Math.max(retryAfter * SECOND, MINIMAL_RETRY_AFTER);
|
return Math.max(retryAfter * SECOND, MINIMAL_RETRY_AFTER);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue