mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-03-12 07:23:58 +00:00
Merge pull request #2405 from balena-os/fix-api-request-timeout
Decrease balenaCloud api request timeout from 15m to 59s
This commit is contained in:
commit
906ce6dc0d
@ -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