0
votes

I have an AWS Elastic Beanstalk Worker Environment setup using SQS. The SQS is posting to a URL, which is an endpoint to a codebase that uses Laravel. From this endpoint, it takes up the message and process the payload. Some of my processes are time-consuming and is taking more than 20 minutes to complete. I am sending back a success response from the endpoint, but as it takes a lot of time to complete the process, most of the time, the messages are going to the inflight mode in SQS. I am trying to make a deleteMessage() call using PHP SDK, but I need to pass ReceiptHandle for deleting a message. As per the documentation here, SQS is not posting ReceiptHandle to my application and so I can't make a delete call. The problem with messages in inFlight mode is that it will be called again in the next time the and so the process is duplicated.

How can I delete a message once the process is completed ?

My current code is as follows :

 $worker->process(
            $request->header('X-Aws-Sqsd-Queue'), $job, [
                'maxTries' => 0,
                'delay' => 0
            ]
        );
        return $this->response([
            'Processed ' . $job->getJobId()
        ]);

Where worker is an instance of

Illuminate\Queue\Worker;

and the response function is json encoding the data and respond with 200

1

1 Answers

0
votes

You must have ReceiptHandle to delete a message in queue. In core PHP below is the function to read and delete a message in queue.

function ReadMessages($client,$queueUrl){
    try {
        $result = $client->receiveMessage(array(
            'AttributeNames' => ['SentTimestamp'],
            'MaxNumberOfMessages' => 1,
            'MessageAttributeNames' => ['All'],
            'QueueUrl' => $queueUrl, // REQUIRED
            'WaitTimeSeconds' => 0,
        ));
        if (count($result->get('Messages')) > 0) {
            var_dump($result->get('Messages')[0]);

            //to delete a message pass the receipt Handle
            $result = $client->deleteMessage([
                'QueueUrl' => $queueUrl, // REQUIRED
                'ReceiptHandle' => $result->get('Messages')[0]['ReceiptHandle'] // REQUIRED
            ]);
            } else {
                echo "No messages in queue. \n";
            }
        }   
    catch (AwsException $e) {
        // output error message if fails
        return 'error';
        error_log($e->getMessage());
    }
}

Do some workaround so you get a ReceiptHandle to delete a message in queue.