title: Asynchronous invoke triggering aws lambda twice
body: <p>I have a chat application that when I click a button after typing in a message, the message gets posted to my DynamoDB table. The application is suppose to post the message once, but somehow is posting it twice.</p>
  
  <p>The pipeline is as follows:</p>
  
  <p>Client clicks <code>send</code> button --> hits my Google Cloud Endpoint API --> triggers my Google Cloud function --> invokes my AWS lambda function --> <code>POSTS</code> message DynamoDB.</p>
  
  <p>With the help of SO, I've isolated the problem to my Google Cloud function invoking Lambda asynchronously which is queuing the Lambda twice.</p>
  
  <blockquote>
    <p>With async, requests are queued before actually executing. So, if you call it once, AWS will check if there's one executing already, if not, it will add another one.</p>
  </blockquote>
  
  <p><a href="https://i.stack.imgur.com/VALS7.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/VALS7.png" alt="enter image description here"></a> (<a href="https://aws.amazon.com/blogs/architecture/understanding-the-different-ways-to-invoke-lambda-functions/" rel="nofollow noreferrer">AWS blog</a>)</p>
  
  <p>Ideally I'd like to invoke my Lambda synchronously but according to this Github <a href="https://github.com/boto/boto3/issues/885#issuecomment-260080124" rel="nofollow noreferrer">post</a>, I'd get billed twice (?). He mentions increasing the timeout of my function, but it's already set at 60 seconds - plenty of time for my lambda to send a response back. Is there some other mechanism that's queuing my lambda twice?</p>
  
  <p>For your reference my Google cloud function is as follows:</p>
  
  <pre><code>let AWS = require('aws-sdk');
  
  AWS.config.update({
    accessKeyId: ''
    secretAccessKey: ''
    region: ''
  })
  
  let lambda = new AWS.Lambda();
  
  exports.helloWorld = async (req,res) =&gt;{
    let payload = {
      pathParameters: req.query.p,
      httpMethod: req.method,
      body: req.method == "POST" ? req.body.message || req.body.user : null,
      cognitoUsername: req.query.u
    }
  
    let params = {
      FunctionName: '',
      InvocationType: 'RequestResponse',
      Payload: JSON.stringify(payload)
    }
  
    res.status(200).send( await lambda.invoke(params, function(err,data){
      if (err){throw err}
      else {return data.Payload}
    }).promise())
  }
  </code></pre>
  
  <p><strong>Solution</strong>:</p>
  
  <p>Based on @jarmod's solution, my Cloud function is shown below. The relevant part is at the end.</p>
  
  <pre><code>let AWS = require('aws-sdk');
  
  AWS.config.update({
    accessKeyId: ''
    secretAccessKey: ''
    region: ''
  })
  
  let lambda = new AWS.Lambda();
  
  exports.helloWorld = async (req,res) =&gt;{
    let payload = {
      pathParameters: req.query.p,
      httpMethod: req.method,
      body: req.method == "POST" ? req.body.message || req.body.user : null,
      cognitoUsername: req.query.u
    }
  
    let params = {
      FunctionName: '',
      InvocationType: 'RequestResponse',
      Payload: JSON.stringify(payload)
    }
  
    // code changed only here
    res.status(200).send( await lambda.invoke(params).promise())
  }
  </code></pre>
  
  <p><strong>Edit</strong>:</p>
  
  <p>@Ngenator brought to my attention that my Google Cloud function may be getting triggered twice. For reference, this is my API yaml configuration:</p>
  
  <pre><code>swagger: '2.0'
  info:
    title: Cloud Endpoints + GCF
    version: 1.0.0
  host: service.run.app
  x-google-endpoints:
    - name: "service.run.app"
      allowCors: "true"
  schemes:
    - https
  produces:
    - application/json
  paths:
    /function-2:
      get:
        operationId: get 
        parameters:
          - name: p
            in: query
            required: true
            type: string
          - name: u
            in: query
            required: false
            type: string
        x-google-backend:
          address: https://to.my/function-2
        responses:
          '200':
            description: A successful response
            schema:
              type: string
      post:
        operationId: post 
        consumes:
          - application/json
        parameters:
          - name: p
            in: query
            required: true
            type: string
          - name: u
            in: query
            required: false
            type: string
          - in: body
            name: body
            schema:
              type: object
              properties:
                message:
                  type: string
                user:
                  type: array
                  items:
                    type: string
        x-google-backend:
          address: https://to.my/function-2
        responses:
          '200':
            description: A successful response
            schema:
              type: string
  </code></pre>