Streaming Http response from Lambda function with Amplify Gen2

0

I am building a simple Amplify App which use lambda function (written in typescript) as backend. I am doing different thing and returning the full reponse in on shot, everything work fine. But now I want to stream the response while generating it as it is a long time task. I cannot find anything about it in Amplify Gen2 documentation, nor any exemple covering this topic.

My technical base for my functions code is based on current documentation which means the main way to handle the function code is with an handler which directly the response content like this:

import type { Handler } from 'aws-lambda';

export const handler: Handler = async (event, context) => {
  // your function code goes here
  return 'Hello, World!';
};

I tried returning a "Response" object or a "Stream" but without success.

There are some discussions (see this one) about it in some place, but I can't find a real answer on how to do it (at least it should be feasible in pure lambda, but no clue on how to do it from Amplify and what is added in front of the lambda).

There is also this discussion about streaming from lambda using "lambda-stream" project but I could not get it to work, not sure if it is applicable to Amplify (and more specifically gen2)..

Thanks for your help !

2 Risposte
0

Hello,

Process in Chunks with Status Updates

  • Instead of streaming, you can process your long-running task in smaller chunks and return status updates as responses.

Steps:

1. Divide Task into Smaller Chunks

  • Break your long task into smaller, manageable steps.

2. Use a Simple Polling Mechanism on the Client-Side

  • The frontend can periodically check for updates from the backend.

Store Task Progress Temporarily in a Database

  • Use a simple DynamoDB table to store the progress of the task.

For the Example code to implement.

Lambda Function

import { Handler } from 'aws-lambda';
import AWS from 'aws-sdk';

const dynamoDb = new AWS.DynamoDB.DocumentClient();

export const handler: Handler = async (event) => {
  const taskId = event.taskId || 'default-task';

  // Simulate task processing (e.g., processing part of the task)
  const taskProgress = { status: 'In Progress', step: 1 }; // Simulate task step

  // Store task progress in DynamoDB
  await dynamoDb.put({
    TableName: 'TaskProgress',
    Item: {
      taskId: taskId,
      progress: taskProgress,
    },
  }).promise();

  return {
    statusCode: 200,
    body: JSON.stringify(taskProgress),
  };
};

Frontend React - Polling for Task Status

import React, { useState, useEffect } from 'react';
import Amplify, { API } from 'aws-amplify';

function PollingComponent({ taskId }) {
  const [taskStatus, setTaskStatus] = useState('Not Started');

  useEffect(() => {
    const interval = setInterval(async () => {
      try {
        const response = await API.get('YourApiName', `/task-status/${taskId}`);
        setTaskStatus(response.status);
      } catch (error) {
        console.error('Error fetching task status:', error);
      }
    }, 5000); // Poll every 5 seconds

    return () => clearInterval(interval);
  }, [taskId]);

  return (
    <div>
      <h3>Task Status: {taskStatus}</h3>
    </div>
  );
}

export default PollingComponent;

  • Processes the task in chunks and stores progress in DynamoDB.

  • Polls every few seconds to get the latest task status.

ESPERTO
con risposta 2 mesi fa
0

A little more context, my function use api (which are using streaming) for audio processing and llm, the whole thing can take something like 10s while the response could ideally start after just 1 or 2 seconds. So the reponse cannot be something else than streaming, I perfectly understand your solution but for my case it is not a good one. About the last part of my message about using lambda-stream, I tested the handler and I obtains the following message: { "data": { "myCustomFunction": null }, "errors": [ { "path": [ "myCustomFunction" ], "data": null, "errorType": "Lambda:IllegalArgument", "errorInfo": null, "locations": [ { "line": 2, "column": 3, "sourceName": null } ], "message": "Error while de-serializing lambda response payload. Got: Hello world from Lambda!" } ] }

meaning the stream processing part works (the text "Hello world from Lambda!" is sent in multiple parts) but is checked by some higher levels processing which make it fail, so it might be worth looking in this direction.

Any idea or tips is welcomed ! (higher level code running aws lambda cannot be found anywhere ? I am not afraid of a deep dive but cannot find anything right now).

Anyway thank for your response !

con risposta 2 mesi fa

Accesso non effettuato. Accedi per postare una risposta.

Una buona risposta soddisfa chiaramente la domanda, fornisce un feedback costruttivo e incoraggia la crescita professionale del richiedente.

Linee guida per rispondere alle domande