J'ai une fonction lambda qui effectue une série d'actions. J'ai une application de réaction qui déclenche la fonction lambda. Existe-t-il un moyen d'envoyer une réponse partielle de la fonction lambda une fois que chaque action est terminée.
const testFunction = (event, context, callback) => { let partialResponse1 = await action1(event); // send partial response to client let partialResponse2 = await action2(partialResponse1); // send partial response to client let partialResponse3 = await action3(partialResponse2); // send partial response to client let response = await action4(partialResponse3); // send final response }
Est-ce possible dans les fonctions lambda? Si oui, comment pouvons-nous faire cela. Tout document de référence ou exemple de code serait d'une grande aide. Merci.
Remarque: C'est un cas assez simple de montrer un chargeur avec% du côté client. Je ne veux pas trop compliquer les choses SQS ou les fonctions pas à pas.
Je cherche toujours une réponse à ce sujet.
4 Réponses :
Aman, Vous pouvez pousser les sorties partielles dans SQS et lire les messages SQS pour traiter ces messages. Il s'agit d'une architecture simple et évolutive. AWS fournit des SDK SQS dans différents langages, par exemple, JavaScript, Java, Python, etc.
La lecture et l'écriture dans SQS sont très faciles à l'aide du SDK et peuvent également être implémentées côté serveur ou dans votre couche d'interface utilisateur (avec un IAM approprié).
Merci pour l'info. J'examinerai ceci. Le SQS fournira-t-il le msg au client ou le client doit-il vérifier périodiquement le msg dans SQS?
Il existe 2 façons de mettre en œuvre cela. Soit vous pouvez utiliser le déclencheur SQS pour déclencher Lambda, donc chaque fois qu'un message est reçu dans la file d'attente, AWS lambda est déclenché. La deuxième option consiste à utiliser AWS lambda en tant qu'écouteur de file d'attente défini avec un planificateur (à partir du planificateur cloudwatch). Une fois le message traité, la file d'attente doit être purgée manuellement.
J'ai trouvé que la fonction d'étape AWS peut être ce dont vous avez besoin:
AWS Step Functions vous permet de coordonner plusieurs services AWS dans des flux de travail sans serveur afin que vous puissiez créer et mettre à jour rapidement des applications.
Consultez ce lien pour plus de détails:
Dans notre exemple, vous êtes un développeur à qui il a été demandé de créer une application sans serveur pour automatiser la gestion des tickets d'assistance dans un centre d'appels. Bien qu'une fonction Lambda puisse appeler l'autre, vous craignez que la gestion de toutes ces connexions ne devienne difficile à mesure que l'application du centre d'appels devient plus sophistiquée. De plus, tout changement dans le flux de l'application nécessitera des modifications à plusieurs endroits et vous pourriez finir par écrire le même code encore et encore.
Ce que vous recherchez, c'est que la réponse
soit exposée comme un flux où vous pouvez écrire dans le flux et le vider
Malheureusement, ce n'est pas là dans Node.js code >
Comment diffuser la réponse AWS Lambda dans le nœud ?
https: //docs.aws.amazon.com/lambda/latest/dg/programming-model.html
Mais vous pouvez toujours faire le streaming si vous utilisez Java
https : //docs.aws.amazon.com/lambda/latest/dg/java-handler-io-type-stream.html
package example; import java.io.InputStream; import java.io.OutputStream; import com.amazonaws.services.lambda.runtime.RequestStreamHandler; import com.amazonaws.services.lambda.runtime.Context; public class Hello implements RequestStreamHandler{ public void handler(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { int letter; while((letter = inputStream.read()) != -1) { outputStream.write(Character.toUpperCase(letter)); } } }
D'après ce que j'ai compris, vous utilisez API Gateway + Lambda et que vous cherchez à afficher la progression de Lambda via l'interface utilisateur.
Étant donné que chaque étape doit se terminer avant que la prochaine étape ne commence, je ne vois aucune raison de ne pas appeler le lambda 4 fois, ou divisez le lambda en 4 lambdas séparés.
Par exemple:
// Not real syntax Gateway-API --> lambda1 - startProcess(): returns ID { uuid = randomUUID(); write to dynamoDB { status: starting }. send sqs-message-to-start-process(data, uuid); return response { uuid: uuid }; } SQS --> lambda2 - execute(): returns void { try { let partialResponse1 = await action1(event); write to dynamoDB { status: action 1 complete }. // send partial response to client let partialResponse2 = await action2(partialResponse1); write to dynamoDB { status: action 2 complete }. // send partial response to client let partialResponse3 = await action3(partialResponse2); write to dynamoDB { status: action 3 complete }. // send partial response to client let response = await action4(partialResponse3); write to dynamoDB { status: action 4 complete, response: response }. } catch(err) { write to dynamoDB { status: failed, error: err }. } } Gateway-API --> lambda3 -> getStatus(uuid): returns status { return status from dynamoDB (uuid); } Your UI Code: res = ajax.get(/startProcess); uuid = res.uuid; in interval every X (e.g. 3) seconds: status = ajax.get(/getStatus?uuid=uuid); show(status); if (status.error) { handle(status.error) and break; } if (status.response) { handle(status.response) and break; } }
Si vous voulez toujours que les 4 appels soient exécutés pendant la même exécution lambda, vous pouvez faire ce qui suit (ceci est particulièrement vrai si le processus devrait être très long) (et parce que ce n'est généralement pas une bonne pratique de exécuter une transaction http "longue attente").
Vous pouvez l'implémenter en enregistrant la "progression" dans une base de données, et lorsque le processus est terminé, enregistrez également les résultats dans la base de données.
Tout ce que vous avez à faire est d'interroger l'état toutes les X secondes.
// Not real syntax! try { res1 = await ajax.post(/process, {stage: 1, data: ... }); out(stage 1 complete); res2 = await ajax.post(/process, {stage: 2, data: res1}); out(stage 2 complete); res3 = await ajax.post(/process, {stage: 3, data: res2}); out(stage 3 complete); res4 = await ajax.post(/process, {stage: 4, data: res3}); out(stage 4 complete); out(process finished); catch(err) { out(stage {$err.stage-number} failed to complete); }
N'oubliez pas que les lambda ne peuvent pas dépasser 15 minutes d'exécution. Par conséquent, vous devez être sûr à 100% que quoi que fasse le processus, il ne dépasse jamais cette limite stricte.
Merci de votre aide. Comme je le vois, il n'y a pas de moyen spécifique de renvoyer une réponse partielle à partir de la fonction lambda. écrire le statut dans la base de données et vérifier à intervalle fixe semble être le meilleur choix pour le moment.
J'ai confirmé la prime pour cela. :) Je n'accepte pas la réponse, de sorte qu'en cas de mise à jour d'AWS, quelqu'un puisse publier ou fournir des informations supplémentaires à ce sujet.
Je ne pense pas que cela soit possible à moins que vous n'utilisiez un middleware comme la file d'attente de messages. Mais la question est intéressante.
Votre approche peut être incorrecte. Qu'est-ce qui appelle le lambda? Est-ce une passerelle API?
Oui, c'est une passerelle API.