7
votes

Trying to run my serverless python lambda functions locally using:

serverless invoke local -f hello

The function runs, but it seems to take 2-5 seconds before the handler is called. This is a real issue for me as I'm hoping to use invoke to support local testing.

My handler is super simple:

def hello(event, context):
   print('start')
   body = {
      "message": "Go Serverless v1.0! Your function executed successfully!",
      "input": event
   }

   response = {
      "statusCode": 200,
     "body": json.dumps(body)
   }
   print('end')

   return response

Rough timings:

  • calling invoke to print(start): 2-5s
  • print(start) to print(end): <0.5s
  • print(end) to response returning to terminal: 1s

Since I cant find any other people with this issue, suggests its something to do with my local machine. No idea what it could be or even where to start fault finding.

Serverless: 1.32 (globally installed) Python: 3.6.5

1
You can try using pyflame to profile the execution of your command and see where it spends the most time. github.com/uber/pyflame - Kamil Niski

1 Answers

-1
votes

That's a problem with the serverless framework(AWS SAM framework too sadly), and not with your code. The Node.JS and Go local invokes suffer from the same issue unfortunately.

The problem stems from, not execution of the code, but the fact that on every invoke, the execution environment needs to be reconfigured, and the time needed for that depends on the machine.

One alternative to invoke is, as I did, write a API HTTP Server wrapper upon your lambda handlers. On the local environment, you can start the server using the wrapper and continue testing.

Edit:

This is basically what you need to do to create a wrapper:

  1. Spin up your HTTP Server from your wrapper.
  2. Create a function which converts your request on the server to Lambda requests, and one that converts the response returned from your lambda handler to your HTTP Server response.
  3. On your wrapper, create path endpoints corresponding to the paths mentioned in serverless.yml. Use the functions created in step 2 to forward the request to your handler.
  4. On recieving the returned result from your handler, map it to your HTTP server response and send it to the user as response.