SLS webpack invoke (v2) + SLS invoke local (V3) don't terminate once the response has been sent
See original GitHub issueThis is a Bug Report
Description
I’m trying to run sls webpack invoke -f some_function
inside a docker container, but the command hangs and I have to stop the machine in another terminal window. Hitting Ctrl+C/D doesn’t work. I’m getting Docker to do it as it’s part of a Jenkins pipeline, and that’s how other devs are doing this in my company.
I expect sls webpack invoke -f some_function
to terminate once the callback has been executed. I’m not running it with the --watch
flag.
I’ve tried upgrading to 2.2.2, but I get the same issue (still using sls webpack invoke -f some_function
even though the docs say it’s been disabled). I cannot run sls invoke local
as I get SyntaxError: Unexpected token import
as webpack hasn’t actually done anything
My serverless.yml has the following plugins
plugins:
- serverless-webpack
- serverless-offline (Even with this turned off, it makes no difference)
- serverless-jest-plugin (Even with this turned off, it makes no difference)
That is the exact order, and I’ve seen mention of webpack needing to be first, and it already is
Additional Data
Serverless-Webpack 2.2.0 (And 2.2.2) Webpack 3.5.4 Serverless-Offline 3.15.3 Serverless 1.20.2 OS: OS X (local) / Ubuntu (docker)
Stack Trace
(function (exports, require, module, __filename, __dirname) { import { successResponse } from '../helpers'
^^^^^^
SyntaxError: Unexpected token import
at createScript (vm.js:56:10)
at Object.runInThisContext (vm.js:97:10)
at Module._compile (module.js:542:28)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.require (module.js:497:17)
at require (internal/module.js:20:19)
at AwsInvokeLocal.invokeLocalNodeJs (/usr/local/lib/node_modules/serverless/lib/plugins/aws/invokeLocal/index.js:156:33)
at AwsInvokeLocal.invokeLocal (/usr/local/lib/node_modules/serverless/lib/plugins/aws/invokeLocal/index.js:114:19)
at AwsInvokeLocal.tryCatcher (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/promise.js:693:18)
at Async._drainQueue (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues (/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:672:20)
at tryOnImmediate (timers.js:645:5)
at processImmediate [as _immediateCallback] (timers.js:617:5)
webpack.config.js
const path = require('path')
const slsw = require('serverless-webpack')
require('source-map-support').install()
module.exports = {
entry: slsw.lib.entries,
devtool: 'source-map',
target: 'node',
externals: [
/aws-sdk/ // Available on AWS Lambda
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
},
output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, '.webpack'),
filename: '[name].js'
}
}
babelrc
{
"presets" : [
[
"env",
{
"presets": [
"stage-3"
],
"targets": {
"node": "6.10"
},
"useBuiltIns": true,
"modules": false,
"loose": true
}
]
],
"plugins":[
[
"transform-async-to-module-method",
{
"module": "bluebird",
"method": "coroutine"
}
]
]
}
Issue Analytics
- State:
- Created 6 years ago
- Reactions:2
- Comments:12 (8 by maintainers)
Thanks for the quick response! I posted this before I left work, so I’ll have a look at this in the morning.
The lingering objects might actually be a big clue. I’m not closing my db connection because I’ve been running into bugs if I do close the connection. I’m new to Promises and async/await. I’m not closing my database connection because there are queries that are somehow firing after the db gets closed. Serverless offline holds my hand there (somehow), but maybe that’s all I need to fix 😃
I’ll update you tomorrow
I tested it with two different projects of ours (with 3.0.0-rc.2). One project terminates correctly after showing the lambda results, one project does not. It looks for me now that the node main loop waits for an empty state and thus does not end the node process correctly. The tests were done in a bash shell, so the problem is independent from Docker.
I used
serverless invoke local --function=<function> --path=<test event json>
(the same should happen with v2 andwebpack invoke
)The project that terminates correctly does not use any global lingering objects, the other one that does not terminate, uses a global REDIS connection that still executes at the end. In AWS Lambda the behavior is that we configure the lambda to exit as soon as the final callback is called and not wait for the event loop to be empty. I’m pretty sure that that’s the core of the problem - the plugin must exit as soon as the terminating lambda callback has been called and the handler exits.