mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-04-16 23:38:52 +00:00
Decrease balenaCloud api request timeout from 15m to 59s
This was mistakenly increased due to confusion between the timeout for requests to the supervisor's api vs the timeout for requests from the supervisor to the balenaCloud api. This separates the two configs and documents the difference between the timeouts whilst also decreasing the timeout for balenaCloud api requests to the correct/expected value Change-type: patch
This commit is contained in:
parent
f67e45f432
commit
49163e92a0
@ -101,11 +101,11 @@ export const update = async (
|
||||
): Promise<void> => {
|
||||
await config.initialized();
|
||||
return Bluebird.using(lockGetTarget(), async () => {
|
||||
const { uuid, apiEndpoint, apiTimeout, deviceApiKey } =
|
||||
const { uuid, apiEndpoint, apiRequestTimeout, deviceApiKey } =
|
||||
await config.getMany([
|
||||
'uuid',
|
||||
'apiEndpoint',
|
||||
'apiTimeout',
|
||||
'apiRequestTimeout',
|
||||
'deviceApiKey',
|
||||
]);
|
||||
|
||||
@ -126,12 +126,12 @@ export const update = async (
|
||||
timeout: {
|
||||
// TODO: We use the same default timeout for all of these in order to have a timeout generally
|
||||
// but it would probably make sense to tune them individually
|
||||
lookup: apiTimeout,
|
||||
connect: apiTimeout,
|
||||
secureConnect: apiTimeout,
|
||||
socket: apiTimeout,
|
||||
send: apiTimeout,
|
||||
response: apiTimeout,
|
||||
lookup: apiRequestTimeout,
|
||||
connect: apiRequestTimeout,
|
||||
secureConnect: apiRequestTimeout,
|
||||
socket: apiRequestTimeout,
|
||||
send: apiRequestTimeout,
|
||||
response: apiRequestTimeout,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -41,14 +41,17 @@ export let stateReportErrors = 0;
|
||||
type StateReportOpts = {
|
||||
[key in keyof Pick<
|
||||
config.ConfigMap<SchemaTypeKey>,
|
||||
'apiEndpoint' | 'apiTimeout' | 'deviceApiKey' | 'appUpdatePollInterval'
|
||||
| 'apiEndpoint'
|
||||
| 'apiRequestTimeout'
|
||||
| 'deviceApiKey'
|
||||
| 'appUpdatePollInterval'
|
||||
>]: SchemaReturn<key>;
|
||||
};
|
||||
|
||||
type StateReport = { body: Partial<DeviceState>; opts: StateReportOpts };
|
||||
|
||||
async function report({ body, opts }: StateReport) {
|
||||
const { apiEndpoint, apiTimeout, deviceApiKey } = opts;
|
||||
const { apiEndpoint, apiRequestTimeout, deviceApiKey } = opts;
|
||||
|
||||
if (!apiEndpoint) {
|
||||
throw new InternalInconsistencyError(
|
||||
@ -69,7 +72,7 @@ async function report({ body, opts }: StateReport) {
|
||||
|
||||
const [{ statusCode, body: statusMessage, headers }] = await request
|
||||
.patchAsync(endpoint, params)
|
||||
.timeout(apiTimeout);
|
||||
.timeout(apiRequestTimeout);
|
||||
|
||||
if (statusCode < 200 || statusCode >= 300) {
|
||||
throw new StatusError(
|
||||
@ -203,7 +206,7 @@ export async function startReporting() {
|
||||
// Get configs needed to make a report
|
||||
const reportConfigs = (await config.getMany([
|
||||
'apiEndpoint',
|
||||
'apiTimeout',
|
||||
'apiRequestTimeout',
|
||||
'deviceApiKey',
|
||||
'appUpdatePollInterval',
|
||||
])) as StateReportOpts;
|
||||
|
@ -90,7 +90,7 @@ export const fnSchema = {
|
||||
'deviceArch',
|
||||
'deviceType',
|
||||
'apiEndpoint',
|
||||
'apiTimeout',
|
||||
'apiRequestTimeout',
|
||||
'registered_at',
|
||||
'deviceId',
|
||||
'version',
|
||||
@ -107,7 +107,7 @@ export const fnSchema = {
|
||||
provisioningApiKey: conf.apiKey,
|
||||
deviceApiKey: conf.deviceApiKey,
|
||||
apiEndpoint: conf.apiEndpoint,
|
||||
apiTimeout: conf.apiTimeout,
|
||||
apiRequestTimeout: conf.apiRequestTimeout,
|
||||
registered_at: conf.registered_at,
|
||||
deviceId: conf.deviceId,
|
||||
supervisorVersion: conf.version,
|
||||
|
@ -12,6 +12,9 @@ export const schemaTypes = {
|
||||
type: t.string,
|
||||
default: '',
|
||||
},
|
||||
/**
|
||||
* The timeout for the supervisor's api
|
||||
*/
|
||||
apiTimeout: {
|
||||
type: PermissiveNumber,
|
||||
default: 15 * 60 * 1000,
|
||||
@ -118,6 +121,13 @@ export const schemaTypes = {
|
||||
type: PermissiveBoolean,
|
||||
default: false,
|
||||
},
|
||||
/**
|
||||
* The timeout for requests to the balenaCloud api
|
||||
*/
|
||||
apiRequestTimeout: {
|
||||
type: PermissiveNumber,
|
||||
default: 59000,
|
||||
},
|
||||
deltaRequestTimeout: {
|
||||
type: PermissiveNumber,
|
||||
default: 59000,
|
||||
@ -218,7 +228,7 @@ export const schemaTypes = {
|
||||
provisioningApiKey: t.union([t.string, NullOrUndefined]),
|
||||
deviceApiKey: t.string,
|
||||
apiEndpoint: t.string,
|
||||
apiTimeout: PermissiveNumber,
|
||||
apiRequestTimeout: PermissiveNumber,
|
||||
registered_at: t.union([PermissiveNumber, NullOrUndefined]),
|
||||
deviceId: t.union([PermissiveNumber, NullOrUndefined]),
|
||||
supervisorVersion: t.union([t.string, t.undefined]),
|
||||
|
@ -4,6 +4,9 @@ export const schema = {
|
||||
mutable: false,
|
||||
removeIfNull: false,
|
||||
},
|
||||
/**
|
||||
* The timeout for the supervisor's api
|
||||
*/
|
||||
apiTimeout: {
|
||||
source: 'config.json',
|
||||
mutable: false,
|
||||
@ -120,6 +123,11 @@ export const schema = {
|
||||
mutable: true,
|
||||
removeIfNull: false,
|
||||
},
|
||||
apiRequestTimeout: {
|
||||
source: 'db',
|
||||
mutable: true,
|
||||
removeIfNull: false,
|
||||
},
|
||||
delta: {
|
||||
source: 'db',
|
||||
mutable: true,
|
||||
|
@ -141,6 +141,11 @@ const configKeys: Dictionary<ConfigOption> = {
|
||||
varType: 'bool',
|
||||
defaultValue: 'true',
|
||||
},
|
||||
apiRequestTimeout: {
|
||||
envVarName: 'SUPERVISOR_API_REQUEST_TIMEOUT',
|
||||
varType: 'int',
|
||||
defaultValue: '59000',
|
||||
},
|
||||
delta: {
|
||||
envVarName: 'SUPERVISOR_DELTA',
|
||||
varType: 'bool',
|
||||
|
@ -111,10 +111,10 @@ export const exchangeKeyAndGetDevice = async (
|
||||
opts: Partial<KeyExchangeOpts>,
|
||||
): Promise<Device> => {
|
||||
const uuid = opts.uuid;
|
||||
const apiTimeout = opts.apiTimeout;
|
||||
if (!(uuid && apiTimeout)) {
|
||||
const apiRequestTimeout = opts.apiRequestTimeout;
|
||||
if (!(uuid && apiRequestTimeout)) {
|
||||
throw new InternalInconsistencyError(
|
||||
'UUID and apiTimeout should be defined in exchangeKeyAndGetDevice',
|
||||
'UUID and apiRequestTimeout should be defined in exchangeKeyAndGetDevice',
|
||||
);
|
||||
}
|
||||
|
||||
@ -122,7 +122,12 @@ export const exchangeKeyAndGetDevice = async (
|
||||
// valid, because if it is then we can just use that
|
||||
if (opts.deviceApiKey != null) {
|
||||
try {
|
||||
return await fetchDevice(balenaApi, uuid, opts.deviceApiKey, apiTimeout);
|
||||
return await fetchDevice(
|
||||
balenaApi,
|
||||
uuid,
|
||||
opts.deviceApiKey,
|
||||
apiRequestTimeout,
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof DeviceNotFoundError) {
|
||||
// do nothing...
|
||||
@ -146,7 +151,7 @@ export const exchangeKeyAndGetDevice = async (
|
||||
balenaApi,
|
||||
uuid,
|
||||
opts.provisioningApiKey,
|
||||
apiTimeout,
|
||||
apiRequestTimeout,
|
||||
);
|
||||
} catch {
|
||||
throw new ExchangeKeyError(`Couldn't fetch device with provisioning key`);
|
||||
@ -165,7 +170,7 @@ export const exchangeKeyAndGetDevice = async (
|
||||
Authorization: `Bearer ${opts.provisioningApiKey}`,
|
||||
},
|
||||
})
|
||||
.timeout(apiTimeout);
|
||||
.timeout(apiRequestTimeout);
|
||||
|
||||
if (res.statusCode !== 200) {
|
||||
throw new ExchangeKeyError(
|
||||
@ -220,7 +225,7 @@ export const provision = async (
|
||||
osVariant: opts.osVariant,
|
||||
macAddress: opts.macAddress,
|
||||
}),
|
||||
).timeout(opts.apiTimeout);
|
||||
).timeout(opts.apiRequestTimeout);
|
||||
} catch (err) {
|
||||
if (
|
||||
err instanceof deviceRegister.ApiError &&
|
||||
|
@ -84,6 +84,7 @@ describe('device-config', () => {
|
||||
SUPERVISOR_LOCAL_MODE: 'false',
|
||||
SUPERVISOR_CONNECTIVITY_CHECK: 'true',
|
||||
SUPERVISOR_LOG_CONTROL: 'true',
|
||||
SUPERVISOR_API_REQUEST_TIMEOUT: '59000',
|
||||
SUPERVISOR_DELTA: 'false',
|
||||
SUPERVISOR_DELTA_REQUEST_TIMEOUT: '59000',
|
||||
SUPERVISOR_DELTA_APPLY_TIMEOUT: '0',
|
||||
|
Loading…
x
Reference in New Issue
Block a user