У меня есть приложение чата, которое, когда я нажимаю кнопку после ввода сообщения, отправляется в мою таблицу DynamoDB. Предполагается, что приложение публикует сообщение один раз, но каким-то образом публикует его дважды.
Конвейер выглядит следующим образом:
Клиент нажимает кнопку send
-> попадает в мой API-интерфейс Google Cloud Endpoint -> запускает мою функцию Google Cloud -> вызывает мою AWS лямбда-функцию -> POSTS
сообщение DynamoDB.
С помощью SO я изолировал проблему с моей функцией Google Cloud вызывая Lambda асинхронно, который ставит Lambda в очередь дважды.
При использовании asyn c запросы ставятся в очередь перед фактическим выполнением. Поэтому, если вы позвоните один раз, AWS проверит, выполняется ли уже один, а если нет, добавит еще один.
( AWS blog )
В идеале я хотел бы вызывать мою Lambda синхронно, но в соответствии с этим постом Github мне выставили бы счет дважды (?). Он упоминает об увеличении времени ожидания моей функции, но оно уже установлено на 60 секунд - у моей лямбды достаточно времени, чтобы отправить ответ обратно. Есть ли какой-то другой механизм, который ставит мою лямбду в очередь дважды?
Для справки, моя облачная функция Google выглядит следующим образом:
let AWS = require('aws-sdk');
AWS.config.update({
accessKeyId: ''
secretAccessKey: ''
region: ''
})
let lambda = new AWS.Lambda();
exports.helloWorld = async (req,res) =>{
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())
}
Решение :
На основе решения @ jarmod моя функция Cloud показана ниже. Соответствующая часть находится в конце.
let AWS = require('aws-sdk');
AWS.config.update({
accessKeyId: ''
secretAccessKey: ''
region: ''
})
let lambda = new AWS.Lambda();
exports.helloWorld = async (req,res) =>{
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())
}
Редактировать :
@ Ngenator обратил мое внимание на то, что моя функция Google Cloud может запускаться дважды. Для справки, это моя конфигурация API yaml:
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