-
Notifications
You must be signed in to change notification settings - Fork 647
Description
Describe the bug
This applies to every auto-generated client, but I will use client-sqs as an example.
This is related to: #2271, #2027, #2993
Note that in the above snippet, loadNodeConfig is called multiple times to get the defaults for the client configuration:
aws-sdk-js-v3/clients/client-sqs/src/runtimeConfig.ts
Lines 31 to 53 in bda3b40
| return { | |
| ...clientSharedValues, | |
| ...config, | |
| runtime: "node", | |
| base64Decoder: config?.base64Decoder ?? fromBase64, | |
| base64Encoder: config?.base64Encoder ?? toBase64, | |
| bodyLengthChecker: config?.bodyLengthChecker ?? calculateBodyLength, | |
| credentialDefaultProvider: | |
| config?.credentialDefaultProvider ?? decorateDefaultCredentialProvider(credentialDefaultProvider), | |
| defaultUserAgentProvider: | |
| config?.defaultUserAgentProvider ?? | |
| defaultUserAgent({ serviceId: clientSharedValues.serviceId, clientVersion: packageInfo.version }), | |
| maxAttempts: config?.maxAttempts ?? loadNodeConfig(NODE_MAX_ATTEMPT_CONFIG_OPTIONS), | |
| md5: config?.md5 ?? Hash.bind(null, "md5"), | |
| region: config?.region ?? loadNodeConfig(NODE_REGION_CONFIG_OPTIONS, NODE_REGION_CONFIG_FILE_OPTIONS), | |
| requestHandler: config?.requestHandler ?? new NodeHttpHandler(), | |
| retryMode: config?.retryMode ?? loadNodeConfig(NODE_RETRY_MODE_CONFIG_OPTIONS), | |
| sha256: config?.sha256 ?? Hash.bind(null, "sha256"), | |
| streamCollector: config?.streamCollector ?? streamCollector, | |
| useDualstackEndpoint: config?.useDualstackEndpoint ?? loadNodeConfig(NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS), | |
| useFipsEndpoint: config?.useFipsEndpoint ?? loadNodeConfig(NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS), | |
| utf8Decoder: config?.utf8Decoder ?? fromUtf8, | |
| utf8Encoder: config?.utf8Encoder ?? toUtf8, |
Which is the exported fn loadConfig from @aws-sdk/node-config-provider package:
aws-sdk-js-v3/packages/node-config-provider/src/configLoader.ts
Lines 27 to 37 in 7392341
| export const loadConfig = <T = string>( | |
| { environmentVariableSelector, configFileSelector, default: defaultValue }: LoadedConfigSelectors<T>, | |
| configuration: LocalConfigOptions = {} | |
| ): Provider<T> => | |
| memoize( | |
| chain( | |
| fromEnv(environmentVariableSelector), | |
| fromSharedConfigFiles(configFileSelector, configuration), | |
| fromStatic(defaultValue) | |
| ) | |
| ); |
Which then uses fromSharedConfigFiles to load config values from the disk.
This is a very undesirable "feature", especially in the serverless environments.
Because under heavy load this results in the following errors:
error: {
"type": "NodeError",
"message": "A system error occurred: uv_os_homedir returned EMFILE (too many open files)",
"stack":
SystemError [ERR_SYSTEM_ERROR]: A system error occurred: uv_os_homedir returned EMFILE (too many open files)
at Object.getHomeDir (/node_modules/@aws-sdk/shared-ini-file-loader/dist-cjs/index.js:82:17)
at Object.loadSharedConfigFiles (/node_modules/@aws-sdk/shared-ini-file-loader/dist-cjs/index.js:11:89)
at null.<anonymous> (/node_modules/@aws-sdk/node-config-provider/dist-cjs/fromSharedConfigFiles.js:9:53)
at null.<anonymous> (/node_modules/@aws-sdk/property-provider/dist-cjs/chain.js:11:28)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at null.coalesceProvider (/node_modules/@aws-sdk/property-provider/dist-cjs/memoize.js:13:24)
at Object.isConstant (/node_modules/@aws-sdk/property-provider/dist-cjs/memoize.js:24:28)
at Object.getEndpointFromRegion (/node_modules/@aws-sdk/config-resolver/dist-cjs/endpointsConfig/utils/getEndpointFromRegion.js:12:34)
at null.buildHttpRpcRequest (/node_modules/@aws-sdk/client-sqs/dist-cjs/protocols/Aws_query.js:2540:68)
"code": "ERR_SYSTEM_ERROR",
"info": {
"errno": -24,
"code": "EMFILE",
"message": "too many open files",
"syscall": "uv_os_homedir"
},
"errno": -24,
"syscall": "uv_os_homedir"
}
Yes the call is memoized, but if your Lambda is getting executed heavily, and installation happens within the handler, then this call happens multiple times.
Your environment
SDK version number
@aws-sdk/client-sqs@3.40.0
Is the issue in the browser/Node.js/ReactNative?
Node.js
Details of the browser/Node.js/ReactNative version
node -v v14.17.5
Steps to reproduce
import { SQS } from '@aws-sdk/client-sqs'
const sqs = new SQS({})Observed behavior
error: {
"type": "NodeError",
"message": "A system error occurred: uv_os_homedir returned EMFILE (too many open files)",
"stack":
SystemError [ERR_SYSTEM_ERROR]: A system error occurred: uv_os_homedir returned EMFILE (too many open files)
at Object.getHomeDir (/node_modules/@aws-sdk/shared-ini-file-loader/dist-cjs/index.js:82:17)
at Object.loadSharedConfigFiles (/node_modules/@aws-sdk/shared-ini-file-loader/dist-cjs/index.js:11:89)
at null.<anonymous> (/node_modules/@aws-sdk/node-config-provider/dist-cjs/fromSharedConfigFiles.js:9:53)
at null.<anonymous> (/node_modules/@aws-sdk/property-provider/dist-cjs/chain.js:11:28)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at null.coalesceProvider (/node_modules/@aws-sdk/property-provider/dist-cjs/memoize.js:13:24)
at Object.isConstant (/node_modules/@aws-sdk/property-provider/dist-cjs/memoize.js:24:28)
at Object.getEndpointFromRegion (/node_modules/@aws-sdk/config-resolver/dist-cjs/endpointsConfig/utils/getEndpointFromRegion.js:12:34)
at null.buildHttpRpcRequest (/node_modules/@aws-sdk/client-sqs/dist-cjs/protocols/Aws_query.js:2540:68)
"code": "ERR_SYSTEM_ERROR",
"info": {
"errno": -24,
"code": "EMFILE",
"message": "too many open files",
"syscall": "uv_os_homedir"
},
"errno": -24,
"syscall": "uv_os_homedir"
}
Expected behavior
- Do not error out
- Do not read config from disk by default, or allow overriding this behaviour.
Screenshots
N/A
Additional context
N/A