3

Is there a way of overwriting retries for an individual call in AWS SDK for PHP?

The following code explains the question:

// Create client with a default of 2 retries
$sqsClient = new sqsClient('2012-11-05', ['retries' => 2]);

// This will retry twice to get the queue attributes (perfect)
try {
    $sqsClient->getQueueAttributes();
} catch(Exception $e) {
}

// I want the following to NEVER retry
try {
    $sqsClient->turnOffRetryLogic(???);
    $sqsClient->receiveMessages(['WaitTimeSeconds' => 5]);
} catch(Exception $e) {
}

// Now set the retries back to as before.

Retries are handled by Middleware - but as the Middleware class is marked "final" I need to pass in a "decider"? This means we need to hook into one of the handlers but none appear to be connected to retries.

Edit:

I have managed to prove the concept of a new "decider" by directly editing the AWS SDK as follows:

final class Middleware
{
    public static function retry(
        callable $decider = null,
        callable $delay = null,
        $stats = false
    ) {
    ....
    $decider = function() {
        echo 'retries cancelled';
        return false;
    };
    ....

So the question is how to do this without editing the SDK. Have tried various middleware hooks as follows, without success.

$decider = function() {
    echo 'No retries';
    return false;
};
$SqsClient->getHandlerList()->appendSign(\AWS\Middleware::retry($decider, null), 'retry');
$result = $SqsClient->receiveMessage($aParams);

(Code samples snipped to only show relevant parts)

Robbie
  • 17,605
  • 4
  • 35
  • 72

1 Answers1

2

Next code removes retry handler

$sqsClient->getHandlerList()->remove('retry');

Sqs client isn't going to retry after that. To restore default behavior you can attach default handler back

$decider = RetryMiddleware::createDefaultDecider(3);
$sqsClient->getHandlerList()->appendSign(
    Middleware::retry($decider, null, false),
    'retry'
);

Though, two separate clients with retries enabled and disabled sound more transparent for me.

vl.lapikov
  • 756
  • 7
  • 12
  • I currently have the "two clients" method in code and it works well - but I feel it's messy insofar that I get a message through the non-retry client and then (if the process fails) return it back to the queue using the retry client. And if the SDK is modified to keep track of messages... I'll give your method a try and report back. Thanks! – Robbie Jul 16 '18 at 11:50
  • Testing Update: Your solution is logical and doesn't break anything. Unfortunately I'm currently unable to replicate the set of instances necessary to to test correctly (cUrl timeout within the library class) so I've included the code in my classes in good faith - will feedback if it ever fails on me.Thanks for your help. – Robbie Jul 18 '18 at 01:47