{"action":"created","issue":{"url":"https://api.github.com/repos/awslabs/aws-serverless-express/issues/103","repository_url":"https://api.github.com/repos/awslabs/aws-serverless-express","labels_url":"https://api.github.com/repos/awslabs/aws-serverless-express/issues/103/labels{/name}","comments_url":"https://api.github.com/repos/awslabs/aws-serverless-express/issues/103/comments","events_url":"https://api.github.com/repos/awslabs/aws-serverless-express/issues/103/events","html_url":"https://github.com/awslabs/aws-serverless-express/pull/103","id":263743096,"number":103,"title":"close server after context succeed","user":{"login":"jeremygiberson","id":487411,"avatar_url":"https://avatars2.githubusercontent.com/u/487411?v=4","gravatar_id":"","url":"https://api.github.com/users/jeremygiberson","html_url":"https://github.com/jeremygiberson","followers_url":"https://api.github.com/users/jeremygiberson/followers","following_url":"https://api.github.com/users/jeremygiberson/following{/other_user}","gists_url":"https://api.github.com/users/jeremygiberson/gists{/gist_id}","starred_url":"https://api.github.com/users/jeremygiberson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jeremygiberson/subscriptions","organizations_url":"https://api.github.com/users/jeremygiberson/orgs","repos_url":"https://api.github.com/users/jeremygiberson/repos","events_url":"https://api.github.com/users/jeremygiberson/events{/privacy}","received_events_url":"https://api.github.com/users/jeremygiberson/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2017-10-08T19:04:46Z","updated_at":"2017-10-12T17:33:44Z","closed_at":"2017-10-12T17:33:44Z","author_association":"NONE","pull_request":{"url":"https://api.github.com/repos/awslabs/aws-serverless-express/pulls/103","html_url":"https://github.com/awslabs/aws-serverless-express/pull/103","diff_url":"https://github.com/awslabs/aws-serverless-express/pull/103.diff","patch_url":"https://github.com/awslabs/aws-serverless-express/pull/103.patch"},"body":"This PR is in response to https://github.com/awslabs/aws-serverless-express/issues/91 an issue that our organization experiences as well. \r\n\r\nIn our case, we are using serverless framework with the \"serverless-offline\" plugin that spins up the service in our local environment and serves multiple requests. I think the expectation in lambda is a single request being serviced per process but in some local dev configurations a single process might be servicing multiple requests. For example we do local dredd API testing which starts serverless offline and calls all of our REST endpoints before shutting down serverless. \r\n\r\nTo recreate the issue:\r\n  * install serverless\r\n  * create serverless hello world template\r\n  * install serverless-offline plugin\r\n  * install expressjs\r\n  * install aws-serverless-express\r\n\r\nServerless config \r\n```yaml\r\nservice: serverless-hello-world\r\n\r\n# The `provider` block defines where your service will be deployed\r\nprovider:\r\n  name: aws\r\n  runtime: nodejs6.10\r\n\r\nplugins:\r\n  - serverless-offline\r\n\r\n# The `functions` block defines what code to deploy\r\nfunctions:\r\n  helloWorld:\r\n    handler: handler.helloWorld\r\n    # The `events` block defines how to trigger the handler.helloWorld code\r\n    events:\r\n      - http:\r\n          path: hello-world\r\n          method: get\r\n          cors: true\r\n```\r\n\r\nServerless handler\r\n```js\r\n'use strict';\r\n\r\nconst express = require('express');\r\nconst app = express();\r\n\r\napp.get('/hello-world', function (req, res) {\r\n  res.send('Hello World!')\r\n});\r\n\r\n\r\nconst awsServerlessExpress = require('aws-serverless-express');\r\n\r\nconst server = awsServerlessExpress.createServer(app);\r\n\r\nexports.helloWorld = (event, context, callback) => awsServerlessExpress.proxy(server, event, context);\r\n```\r\n\r\nTest your service locally:\r\n```\r\n$ sls offline start\r\nServerless: Starting Offline: dev/us-east-1.\r\n\r\nServerless: Routes for helloWorld:\r\nServerless: GET /hello-world\r\n\r\nServerless: Offline listening on http://localhost:3000\r\n```\r\n\r\nHit your endpoint multiple times:\r\n```\r\ncurl -v http://localhost:3000/hello-world\r\ncurl -v http://localhost:3000/hello-world\r\ncurl -v http://localhost:3000/hello-world\r\n```\r\n\r\nObserve warnings:\r\n```\r\nServerless: GET /hello-world (λ: helloWorld)\r\nServerless: The first request might take a few extra seconds\r\nServerless: [200] {\"statusCode\":200,\"body\":\"Hello World!\",\"headers\":{\"x-powered-by\":\"Express\",\"content-type\":\"text/html; charset=utf-8\",\"content-length\":\"12\",\"etag\":\"W/\\\"c-Lve95gjOVATpfV8EL5X4nxwjKHE\\\"\",\"date\":\"Sun, 08 Oct 2017 19:00:36 GMT\",\"connection\":\"close\"},\"isBase64Encoded\":false}\r\n\r\nServerless: GET /hello-world (λ: helloWorld)\r\nWARNING: Attempting to listen on socket /tmp/server0.sock, but it is already in use. This is likely as a result of a previous invocation error or timeout. Check the logs for the invocation(s) immediately prior to this for root cause, and consider increasing the timeout and/or cpu/memory allocation if this is purely as a result of a timeout. aws-serverless-express will restart the Node.js server listening on a new port and continue with this request.\r\nServerless: [200] {\"statusCode\":200,\"body\":\"Hello World!\",\"headers\":{\"x-powered-by\":\"Express\",\"content-type\":\"text/html; charset=utf-8\",\"content-length\":\"12\",\"etag\":\"W/\\\"c-Lve95gjOVATpfV8EL5X4nxwjKHE\\\"\",\"date\":\"Sun, 08 Oct 2017 19:00:37 GMT\",\"connection\":\"close\"},\"isBase64Encoded\":false}\r\n\r\nServerless: GET /hello-world (λ: helloWorld)\r\nWARNING: Attempting to listen on socket /tmp/server0.sock, but it is already in use. This is likely as a result of a previous invocation error or timeout. Check the logs for the invocation(s) immediately prior to this for root cause, and consider increasing the timeout and/or cpu/memory allocation if this is purely as a result of a timeout. aws-serverless-express will restart the Node.js server listening on a new port and continue with this request.\r\nWARNING: Attempting to listen on socket /tmp/server1.sock, but it is already in use. This is likely as a result of a previous invocation error or timeout. Check the logs for the invocation(s) immediately prior to this for root cause, and consider increasing the timeout and/or cpu/memory allocation if this is purely as a result of a timeout. aws-serverless-express will restart the Node.js server listening on a new port and continue with this request.\r\nServerless: [200] {\"statusCode\":200,\"body\":\"Hello World!\",\"headers\":{\"x-powered-by\":\"Express\",\"content-type\":\"text/html; charset=utf-8\",\"content-length\":\"12\",\"etag\":\"W/\\\"c-Lve95gjOVATpfV8EL5X4nxwjKHE\\\"\",\"date\":\"Sun, 08 Oct 2017 19:00:38 GMT\",\"connection\":\"close\"},\"isBase64Encoded\":false}\r\n```\r\n\r\n\r\n\r\nWith the change the PR applies, we simply call close on server after `context.succeed` is called.\r\n\r\nRe-run local test and hit the endpoint multiple times and observe the warning is no longer present.\r\n```\r\nServerless: GET /hello-world (λ: helloWorld)\r\nServerless: The first request might take a few extra seconds\r\nServerless: [200] {\"statusCode\":200,\"body\":\"Hello World!\",\"headers\":{\"x-powered-by\":\"Express\",\"content-type\":\"text/html; charset=utf-8\",\"content-length\":\"12\",\"etag\":\"W/\\\"c-Lve95gjOVATpfV8EL5X4nxwjKHE\\\"\",\"date\":\"Sun, 08 Oct 2017 19:03:02 GMT\",\"connection\":\"close\"},\"isBase64Encoded\":false}\r\n\r\nServerless: GET /hello-world (λ: helloWorld)\r\nServerless: [200] {\"statusCode\":200,\"body\":\"Hello World!\",\"headers\":{\"x-powered-by\":\"Express\",\"content-type\":\"text/html; charset=utf-8\",\"content-length\":\"12\",\"etag\":\"W/\\\"c-Lve95gjOVATpfV8EL5X4nxwjKHE\\\"\",\"date\":\"Sun, 08 Oct 2017 19:03:02 GMT\",\"connection\":\"close\"},\"isBase64Encoded\":false}\r\n\r\nServerless: GET /hello-world (λ: helloWorld)\r\nServerless: [200] {\"statusCode\":200,\"body\":\"Hello World!\",\"headers\":{\"x-powered-by\":\"Express\",\"content-type\":\"text/html; charset=utf-8\",\"content-length\":\"12\",\"etag\":\"W/\\\"c-Lve95gjOVATpfV8EL5X4nxwjKHE\\\"\",\"date\":\"Sun, 08 Oct 2017 19:03:03 GMT\",\"connection\":\"close\"},\"isBase64Encoded\":false}\r\n\r\nServerless: GET /hello-world (λ: helloWorld)\r\nServerless: [200] {\"statusCode\":200,\"body\":\"Hello World!\",\"headers\":{\"x-powered-by\":\"Express\",\"content-type\":\"text/html; charset=utf-8\",\"content-length\":\"12\",\"etag\":\"W/\\\"c-Lve95gjOVATpfV8EL5X4nxwjKHE\\\"\",\"date\":\"Sun, 08 Oct 2017 19:03:03 GMT\",\"connection\":\"close\"},\"isBase64Encoded\":false}\r\n```\r\n"},"comment":{"url":"https://api.github.com/repos/awslabs/aws-serverless-express/issues/comments/336210248","html_url":"https://github.com/awslabs/aws-serverless-express/pull/103#issuecomment-336210248","issue_url":"https://api.github.com/repos/awslabs/aws-serverless-express/issues/103","id":336210248,"user":{"login":"jeremygiberson","id":487411,"avatar_url":"https://avatars2.githubusercontent.com/u/487411?v=4","gravatar_id":"","url":"https://api.github.com/users/jeremygiberson","html_url":"https://github.com/jeremygiberson","followers_url":"https://api.github.com/users/jeremygiberson/followers","following_url":"https://api.github.com/users/jeremygiberson/following{/other_user}","gists_url":"https://api.github.com/users/jeremygiberson/gists{/gist_id}","starred_url":"https://api.github.com/users/jeremygiberson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jeremygiberson/subscriptions","organizations_url":"https://api.github.com/users/jeremygiberson/orgs","repos_url":"https://api.github.com/users/jeremygiberson/repos","events_url":"https://api.github.com/users/jeremygiberson/events{/privacy}","received_events_url":"https://api.github.com/users/jeremygiberson/received_events","type":"User","site_admin":false},"created_at":"2017-10-12T17:33:44Z","updated_at":"2017-10-12T17:33:44Z","author_association":"NONE","body":"I have to withdraw this solution. While it works great in the serverless offline environment it fails in AWS lambda. I think I was under a misconception of how AWS lambda works. Looks like a lambda function service serves more than a single request. "}}
{"actor":{"display_login":"jeremygiberson"}}